From 84b5c4d2d0774f800237634e5d0336f53c004fe3 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 4 Jan 2026 09:44:40 +0800 Subject: [PATCH 01/33] =?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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1cccac4b..79a19f10b 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ ### 重要信息 1. [`WxJava` 荣获 `GitCode` 2024年度十大开源社区奖项](https://mp.weixin.qq.com/s/wM_UlMsDm3IZ1CPPDvcvQw)。 2. 项目合作洽谈请联系微信`binary0000`(在微信里自行搜索并添加好友,请注明来意,如有关于SDK问题需讨论请参考下文入群讨论,不要加此微信)。 -3. **2024-12-30 发布 [【4.7.0正式版】](https://mp.weixin.qq.com/s/_7k-XLYBqeJJhvHWCsdT0A)**! +3. **2026-01-03 发布 [【4.8.0正式版】](https://mp.weixin.qq.com/s/mJoFtGc25pXCn3uZRh6Q-w)**! 5. 贡献源码可以参考视频:[【贡献源码全过程(上集)】](https://mp.weixin.qq.com/s/3xUZSATWwHR_gZZm207h7Q)、[【贡献源码全过程(下集)】](https://mp.weixin.qq.com/s/nyzJwVVoYSJ4hSbwyvTx9A) ,友情提供:[程序员小山与Bug](https://space.bilibili.com/473631007) 6. 新手重要提示:本项目仅是一个SDK开发工具包,未提供Web实现,建议使用 `maven` 或 `gradle` 引用本项目即可使用本SDK提供的各种功能,详情可参考 **[【Demo项目】](demo.md)** 或本项目中的部分单元测试代码; 7. 微信开发新手请务必阅读【开发文档】([Gitee Wiki](https://gitee.com/binary/weixin-java-tools/wikis/Home) 或者 [Github Wiki](https://github.com/binarywang/WxJava/wiki))的常见问题部分,可以少走很多弯路,节省不少时间。 @@ -95,7 +95,7 @@ com.github.binarywang (不同模块参考下文) - 4.7.0 + 4.8.0 ``` From 521d46d95706960cf5a73f40f472001489b52edc Mon Sep 17 00:00:00 2001 From: HeCG95 <52144646+HeCG95@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:33:02 +0800 Subject: [PATCH 02/33] =?UTF-8?q?:new:=20#3828=20=E3=80=90=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E3=80=91=E6=9B=B4=E6=96=B0=E5=95=86?= =?UTF-8?q?=E5=AE=B6=E8=BD=AC=E8=B4=A6=20API=20=E7=9A=84=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=92=8C=E5=93=8D=E5=BA=94=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E5=AE=98=E6=96=B9=E6=96=87=E6=A1=A3=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=B0=83=E6=95=B4=EF=BC=8C=E6=96=B0=E5=A2=9E=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E5=9C=BA=E6=99=AF=E6=8A=A5=E5=A4=87=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessOperationTransferRequest.java | 44 ++++++++++++++++--- .../BusinessOperationTransferResult.java | 28 ++++++++---- .../BusinessOperationTransferExample.java | 12 ++++- .../BusinessOperationTransferServiceTest.java | 19 ++++++-- 4 files changed, 84 insertions(+), 19 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java index 91d943883..60b8edaf4 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java @@ -6,8 +6,10 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.List; /** * 运营工具-商家转账请求参数 @@ -37,11 +39,11 @@ public class BusinessOperationTransferRequest implements Serializable { private String outBillNo; /** - * 运营工具转账场景ID - * 必须,用于标识运营工具转账的具体业务场景 + * 转账场景ID + * 必须,该笔转账使用的转账场景,可前往“商户平台-产品中心-商家转账”中申请。如:1000(现金营销),1006(企业报销)等 */ - @SerializedName("operation_scene_id") - private String operationSceneId; + @SerializedName("transfer_scene_id") + private String transferSceneId; /** * 用户在直连商户应用下的用户标示 @@ -86,4 +88,36 @@ public class BusinessOperationTransferRequest implements Serializable { */ @SerializedName("notify_url") private String notifyUrl; -} \ No newline at end of file + + /** + * 转账场景报备信息 + * 必须,需按转账场景准确填写报备信息,参考 转账场景报备信息字段说明 + */ + @SerializedName("transfer_scene_report_infos") + private List transferSceneReportInfos; + + /** + * 转账场景报备信息 + */ + @Data + @Accessors(chain = true) + public static class TransferSceneReportInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 信息类型 + * 必须,不能超过15个字符,商户所属转账场景下的信息类型,此字段内容为固定值,需严格按照 转账场景报备信息字段说明 传参。 + */ + @SerializedName("info_type") + private String infoType; + + /** + * 信息内容 + * 必须,不能超过32个字符,商户所属转账场景下的信息内容,商户可按实际业务场景自定义传参,需严格按照 转账场景报备信息字段说明 传参。 + */ + @SerializedName("info_content") + private String infoContent; + + } + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferResult.java index a380d6133..91771b43e 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferResult.java @@ -31,15 +31,27 @@ public class BusinessOperationTransferResult implements Serializable { private String transferBillNo; /** - * 转账状态 - * WAIT_PAY:等待确认 - * PROCESSING:转账中 - * SUCCESS:转账成功 - * FAIL:转账失败 - * REFUND:已退款 + * 单据状态 + * 商家转账订单状态 + * ACCEPTED:转账已受理,可原单重试(非终态)。 + * PROCESSING: 转账锁定资金中。如果一直停留在该状态,建议检查账户余额是否足够,如余额不足,可充值后再原单重试(非终态)。 + * WAIT_USER_CONFIRM: 待收款用户确认,当前转账单据资金已锁定,可拉起微信收款确认页面进行收款确认(非终态)。 + * TRANSFERING: 转账中,可拉起微信收款确认页面再次重试确认收款(非终态)。 + * SUCCESS: 转账成功,表示转账单据已成功(终态)。 + * FAIL: 转账失败,表示该笔转账单据已失败。若需重新向用户转账,请重新生成单据并再次发起(终态)。 + * CANCELING: 转账撤销中,商户撤销请求受理成功,该笔转账正在撤销中,需查单确认撤销的转账单据状态(非终态)。 + * CANCELLED: 转账撤销完成,代表转账单据已撤销成功(终态)。 */ - @SerializedName("transfer_state") - private String transferState; + @SerializedName("state") + private String state; + + /** + * 跳转领取页面的package信息 + * 跳转微信支付收款页的package信息, APP调起用户确认收款 或者 JSAPI调起用户确认收款 时需要使用的参数。仅当转账单据状态为WAIT_USER_CONFIRM时返回。
+ * 单据创建后,用户24小时内不领取将过期关闭,建议拉起用户确认收款页面前,先查单据状态:如单据状态为WAIT_USER_CONFIRM,可用之前的package信息拉起;单据到终态时需更换单号重新发起转账。 + */ + @SerializedName("package_info") + private String packageInfo; /** * 发起转账的时间 diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/example/BusinessOperationTransferExample.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/example/BusinessOperationTransferExample.java index d11738816..117395ba6 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/example/BusinessOperationTransferExample.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/example/BusinessOperationTransferExample.java @@ -8,6 +8,8 @@ import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import java.util.Arrays; + /** * 运营工具-商家转账API使用示例 * @@ -41,10 +43,15 @@ public void init() { public void createOperationTransferExample() { try { // 构建转账请求 + BusinessOperationTransferRequest.TransferSceneReportInfo reportInfo = new BusinessOperationTransferRequest.TransferSceneReportInfo(); + reportInfo.setInfoType("活动名称"); + reportInfo.setInfoContent("新会员有礼"); + BusinessOperationTransferRequest request = BusinessOperationTransferRequest.newBuilder() .appid("your_app_id") // 应用ID .outBillNo("OT" + System.currentTimeMillis()) // 商户转账单号 - .operationSceneId(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING) // 运营工具转账场景ID + .transferSceneId(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING) // 运营工具转账场景ID + .transferSceneReportInfos(Arrays.asList(reportInfo)) // 转账场景报备信息 .openid("user_openid") // 用户openid .userName("张三") // 用户姓名(可选) .transferAmount(100) // 转账金额,单位分 @@ -59,7 +66,8 @@ public void createOperationTransferExample() { System.out.println("转账成功!"); System.out.println("商户单号: " + result.getOutBillNo()); System.out.println("微信转账单号: " + result.getTransferBillNo()); - System.out.println("转账状态: " + result.getTransferState()); + System.out.println("单据状态: " + result.getState()); + System.out.println("跳转领取页面的package信息: " + result.getPackageInfo()); System.out.println("创建时间: " + result.getCreateTime()); } catch (WxPayException e) { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/BusinessOperationTransferServiceTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/BusinessOperationTransferServiceTest.java index 4107be434..672483f96 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/BusinessOperationTransferServiceTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/BusinessOperationTransferServiceTest.java @@ -7,6 +7,8 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import java.util.Arrays; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -36,10 +38,17 @@ public void testServiceInitialization() { @Test public void testRequestBuilder() { + + // 构建转账请求 + BusinessOperationTransferRequest.TransferSceneReportInfo reportInfo = new BusinessOperationTransferRequest.TransferSceneReportInfo(); + reportInfo.setInfoType("test_info_type"); + reportInfo.setInfoContent("test_info_content"); + BusinessOperationTransferRequest request = BusinessOperationTransferRequest.newBuilder() .appid("test_app_id") .outBillNo("OT" + System.currentTimeMillis()) - .operationSceneId(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING) + .transferSceneId(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING) + .transferSceneReportInfos(Arrays.asList(reportInfo)) .openid("test_openid") .transferAmount(100) .transferRemark("测试转账") @@ -47,7 +56,7 @@ public void testRequestBuilder() { .build(); assertThat(request.getAppid()).isEqualTo("test_app_id"); - assertThat(request.getOperationSceneId()).isEqualTo(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING); + assertThat(request.getTransferSceneId()).isEqualTo(WxPayConstants.OperationSceneId.OPERATION_CASH_MARKETING); assertThat(request.getTransferAmount()).isEqualTo(100); assertThat(request.getTransferRemark()).isEqualTo("测试转账"); } @@ -77,11 +86,13 @@ public void testResultClasses() { BusinessOperationTransferResult result = new BusinessOperationTransferResult(); result.setOutBillNo("test_out_bill_no"); result.setTransferBillNo("test_transfer_bill_no"); - result.setTransferState("SUCCESS"); + result.setState("SUCCESS"); + result.setPackageInfo("test_package_info"); assertThat(result.getOutBillNo()).isEqualTo("test_out_bill_no"); assertThat(result.getTransferBillNo()).isEqualTo("test_transfer_bill_no"); - assertThat(result.getTransferState()).isEqualTo("SUCCESS"); + assertThat(result.getState()).isEqualTo("SUCCESS"); + assertThat(result.getPackageInfo()).isEqualTo("test_package_info"); BusinessOperationTransferQueryResult queryResult = new BusinessOperationTransferQueryResult(); queryResult.setOperationSceneId("2001"); From 987001214ddf126d748853445d0b8859abd34258 Mon Sep 17 00:00:00 2001 From: buaazyl Date: Tue, 6 Jan 2026 11:19:28 +0800 Subject: [PATCH 03/33] =?UTF-8?q?:art:=20#3830=20=E3=80=90=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E9=97=AE=E9=A2=98=E3=80=91=E4=BF=AE=E5=A4=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8HttpComponents=E6=97=B6=E4=B8=8D=E9=85=8D=E7=BD=AEprox?= =?UTF-8?q?y=20password=E5=90=AF=E5=8A=A8=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/impl/WxChannelServiceHttpComponentsImpl.java | 3 +-- .../weixin/cp/api/impl/WxCpServiceHttpComponentsImpl.java | 3 ++- .../service/impl/WxCpCgServiceHttpComponentsImpl.java | 3 ++- .../tp/service/impl/WxCpTpServiceHttpComponentsImpl.java | 8 ++++---- .../weixin/mp/api/impl/WxMpServiceHttpComponentsImpl.java | 3 ++- .../api/impl/WxQidianServiceHttpComponentsImpl.java | 6 ++++-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpComponentsImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpComponentsImpl.java index 6cf2d3850..f4cbb0475 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpComponentsImpl.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpComponentsImpl.java @@ -5,7 +5,6 @@ import me.chanjar.weixin.channel.config.WxChannelConfig; import me.chanjar.weixin.channel.util.JsonUtils; import me.chanjar.weixin.common.util.http.HttpClientType; -import me.chanjar.weixin.common.util.http.apache.ApacheBasicResponseHandler; import me.chanjar.weixin.common.util.http.hc.BasicResponseHandler; import me.chanjar.weixin.common.util.http.hc.DefaultHttpComponentsClientBuilder; import me.chanjar.weixin.common.util.http.hc.HttpComponentsClientBuilder; @@ -41,7 +40,7 @@ public void initHttp() { apacheHttpClientBuilder.httpProxyHost(config.getHttpProxyHost()) .httpProxyPort(config.getHttpProxyPort()) .httpProxyUsername(config.getHttpProxyUsername()) - .httpProxyPassword(config.getHttpProxyPassword().toCharArray()); + .httpProxyPassword(config.getHttpProxyPassword() == null ? null : config.getHttpProxyPassword().toCharArray()); if (config.getHttpProxyHost() != null && config.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(config.getHttpProxyHost(), config.getHttpProxyPort()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceHttpComponentsImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceHttpComponentsImpl.java index 92fd2dbd9..4b6a1e36f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceHttpComponentsImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceHttpComponentsImpl.java @@ -82,7 +82,8 @@ public void initHttp() { apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) .httpProxyPort(this.configStorage.getHttpProxyPort()) .httpProxyUsername(this.configStorage.getHttpProxyUsername()) - .httpProxyPassword(this.configStorage.getHttpProxyPassword().toCharArray()); + .httpProxyPassword(this.configStorage.getHttpProxyPassword() == null ? null : + this.configStorage.getHttpProxyPassword().toCharArray()); if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/WxCpCgServiceHttpComponentsImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/WxCpCgServiceHttpComponentsImpl.java index d5c60ad03..4c8fa5d13 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/WxCpCgServiceHttpComponentsImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/WxCpCgServiceHttpComponentsImpl.java @@ -35,7 +35,8 @@ public void initHttp() { apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) .httpProxyPort(this.configStorage.getHttpProxyPort()) .httpProxyUsername(this.configStorage.getHttpProxyUsername()) - .httpProxyPassword(this.configStorage.getHttpProxyPassword().toCharArray()); + .httpProxyPassword(this.configStorage.getHttpProxyPassword() == null ? null : + this.configStorage.getHttpProxyPassword().toCharArray()); if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceHttpComponentsImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceHttpComponentsImpl.java index bba597a3e..44b5fd869 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceHttpComponentsImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceHttpComponentsImpl.java @@ -10,7 +10,6 @@ import me.chanjar.weixin.common.util.http.hc.DefaultHttpComponentsClientBuilder; import me.chanjar.weixin.common.util.http.hc.HttpComponentsClientBuilder; import me.chanjar.weixin.common.util.json.GsonParser; -import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.config.RequestConfig; @@ -87,9 +86,10 @@ public void initHttp() { HttpComponentsClientBuilder apacheHttpClientBuilder = DefaultHttpComponentsClientBuilder.get(); apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) - .httpProxyPort(this.configStorage.getHttpProxyPort()) - .httpProxyUsername(this.configStorage.getHttpProxyUsername()) - .httpProxyPassword(this.configStorage.getHttpProxyPassword().toCharArray()); + .httpProxyPort(this.configStorage.getHttpProxyPort()) + .httpProxyUsername(this.configStorage.getHttpProxyUsername()) + .httpProxyPassword(this.configStorage.getHttpProxyPassword() == null ? null : + this.configStorage.getHttpProxyPassword().toCharArray()); if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpComponentsImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpComponentsImpl.java index bbf065acf..c54202ad2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpComponentsImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpComponentsImpl.java @@ -51,7 +51,8 @@ public void initHttp() { apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) .httpProxyPort(configStorage.getHttpProxyPort()) .httpProxyUsername(configStorage.getHttpProxyUsername()) - .httpProxyPassword(configStorage.getHttpProxyPassword().toCharArray()); + .httpProxyPassword(configStorage.getHttpProxyPassword() == null ? null : + configStorage.getHttpProxyPassword().toCharArray()); if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); diff --git a/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceHttpComponentsImpl.java b/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceHttpComponentsImpl.java index a5cc23f0a..90486efc8 100644 --- a/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceHttpComponentsImpl.java +++ b/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceHttpComponentsImpl.java @@ -48,8 +48,10 @@ public void initHttp() { HttpComponentsClientBuilder apacheHttpClientBuilder = DefaultHttpComponentsClientBuilder.get(); apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) - .httpProxyPort(configStorage.getHttpProxyPort()).httpProxyUsername(configStorage.getHttpProxyUsername()) - .httpProxyPassword(configStorage.getHttpProxyPassword().toCharArray()); + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword() == null ? null : + configStorage.getHttpProxyPassword().toCharArray()); if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); From e46da01cc802d0d925a89db6427c415dd9347e56 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 11:20:58 +0800 Subject: [PATCH 04/33] =?UTF-8?q?:art:=20#3824=20=E3=80=90=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=9E=B6=E6=9E=84=E3=80=91=E5=8D=87=E7=BA=A7=E5=88=B0?= =?UTF-8?q?=20Apache=20HttpClient=205.x=20=E4=BD=9C=E4=B8=BA=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=20HTTP=20=E5=AE=A2=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 46 ++++ docs/HTTPCLIENT_UPGRADE_GUIDE.md | 203 ++++++++++++++++++ pom.xml | 6 +- .../wxjava/channel/enums/HttpClientType.java | 8 +- .../properties/WxChannelProperties.java | 2 +- .../wxjava/miniapp/enums/HttpClientType.java | 4 + .../solon/wxjava/mp/enums/HttpClientType.java | 4 + .../wxjava/mp/properties/WxMpProperties.java | 2 +- .../wxjava/qidian/enums/HttpClientType.java | 4 + .../qidian/properties/WxQidianProperties.java | 2 +- .../AbstractWxChannelConfiguration.java | 4 + .../wxjava/channel/enums/HttpClientType.java | 6 +- .../wxjava/channel/enums/HttpClientType.java | 8 +- .../properties/WxChannelProperties.java | 2 +- .../wxjava/miniapp/enums/HttpClientType.java | 6 +- .../wx-java-mp-spring-boot-starter/README.md | 2 +- .../wxjava/mp/properties/WxMpProperties.java | 2 +- .../wxjava/qidian/enums/HttpClientType.java | 4 + .../qidian/properties/WxQidianProperties.java | 2 +- weixin-java-common/pom.xml | 20 +- 20 files changed, 313 insertions(+), 24 deletions(-) create mode 100644 docs/HTTPCLIENT_UPGRADE_GUIDE.md diff --git a/README.md b/README.md index 79a19f10b..54af600be 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,52 @@ - **微信开放平台**(`weixin-java-open`)主要用于第三方平台,代公众号或小程序进行开发和管理 +--------------------------------- +### HTTP 客户端支持 + +本项目同时支持多种 HTTP 客户端实现,默认推荐使用 **Apache HttpClient 5.x**(最新稳定版本)。 + +#### 支持的 HTTP 客户端类型 + +| HTTP 客户端 | 说明 | 配置值 | 推荐程度 | +|------------|------|--------|---------| +| Apache HttpClient 5.x | Apache HttpComponents Client 5.x,最新版本 | `HttpComponents` | ⭐⭐⭐⭐⭐ 推荐 | +| Apache HttpClient 4.x | Apache HttpClient 4.x,向后兼容 | `HttpClient` | ⭐⭐⭐⭐ 兼容 | +| OkHttp | Square OkHttp 客户端 | `OkHttp` | ⭐⭐⭐ 可选 | +| Jodd-http | Jodd 轻量级 HTTP 客户端 | `JoddHttp` | ⭐⭐ 可选 | + +#### 配置方式 + +**Spring Boot 配置示例:** + +```properties +# 使用 HttpClient 5.x(推荐,MP/CP/Channel/QiDian 模块默认) +wx.mp.config-storage.http-client-type=HttpComponents + +# 使用 HttpClient 4.x(兼容模式,MiniApp 模块默认) +wx.mp.config-storage.http-client-type=HttpClient + +# 使用 OkHttp +wx.mp.config-storage.http-client-type=OkHttp + +# 使用 Jodd-http +wx.mp.config-storage.http-client-type=JoddHttp +``` + +**注意**:如果使用 Multi-Starter(如 `wx-java-mp-multi-spring-boot-starter`),枚举值需使用大写下划线格式: +```properties +# Multi-Starter 配置格式 +wx.mp.config-storage.http-client-type=HTTP_COMPONENTS # 注意使用大写下划线 +``` + +**注意事项:** +1. **MiniApp 模块**已提供 `HttpComponents`(HttpClient 5.x)类型的配置选项,但当前默认仍为 HttpClient 4.x;如需启用 HttpClient 5.x,请确保所使用的集成模块(如 `wx-java-miniapp-spring-boot-starter`、`wx-java-miniapp-solon-plugin`)版本已支持该选项 +2. **MP、Channel、QiDian 模块**已完整支持 HttpClient 5.x,默认推荐使用 +3. **CP 模块**的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档 +4. 如需使用 OkHttp 或 Jodd-http,需在项目中添加对应的依赖(scope为provided) +5. HttpClient 4.x 和 HttpClient 5.x 可以共存,按需配置即可 + + --------------------------------- ### 版本说明 diff --git a/docs/HTTPCLIENT_UPGRADE_GUIDE.md b/docs/HTTPCLIENT_UPGRADE_GUIDE.md new file mode 100644 index 000000000..08726fa03 --- /dev/null +++ b/docs/HTTPCLIENT_UPGRADE_GUIDE.md @@ -0,0 +1,203 @@ +# HttpClient 升级指南 + +## 概述 + +从 WxJava 4.7.x 版本开始,项目开始支持并推荐使用 **Apache HttpClient 5.x**(HttpComponents Client 5),同时保持对 HttpClient 4.x 的向后兼容。 + +## 为什么升级? + +1. **Apache HttpClient 5.x 是最新稳定版本**:提供更好的性能和更多的功能 +2. **HttpClient 4.x 已经进入维护模式**:不再积极开发新功能 +3. **更好的安全性**:HttpClient 5.x 包含最新的安全更新和改进 +4. **向前兼容**:为未来的开发做好准备 + +## 支持的 HTTP 客户端 + +| HTTP 客户端 | 版本 | 配置值 | 状态 | 说明 | +|------------|------|--------|------|------| +| Apache HttpClient 5.x | 5.5 | `HttpComponents` | ⭐ 推荐 | 最新稳定版本 | +| Apache HttpClient 4.x | 4.5.13 | `HttpClient` | ✅ 支持 | 向后兼容 | +| OkHttp | 4.12.0 | `OkHttp` | ✅ 支持 | 需自行添加依赖 | +| Jodd-http | 6.3.0 | `JoddHttp` | ✅ 支持 | 需自行添加依赖 | + +## 模块支持情况 + +| 模块 | HttpClient 5.x 支持 | 默认客户端 | +|------|-------------------|-----------| +| weixin-java-mp(公众号) | ✅ 是 | HttpComponents (5.x) | +| weixin-java-cp(企业微信) | ⚠️ 视集成方式而定 | 参考对应 starter 配置 | +| weixin-java-channel(视频号) | ✅ 是 | HttpComponents (5.x) | +| weixin-java-qidian(企点) | ✅ 是 | HttpComponents (5.x) | +| weixin-java-miniapp(小程序) | ✅ 是 | HttpClient (4.x) | +| weixin-java-pay(支付) | ✅ 是 | HttpComponents (5.x) | +| weixin-java-open(开放平台) | ✅ 是 | HttpComponents (5.x) | + +**注意**: +- **weixin-java-miniapp 模块**已在核心 SDK 中提供 HttpClient 5.x(`HttpComponents`)支持,但默认仍使用 HttpClient 4.x(`HttpClient`)。如需启用 HttpClient 5.x,可通过配置 `http-client-type=HttpComponents` 显式指定。 +- **weixin-java-cp 模块**的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档。 + +## 对现有项目的影响 + +### 对新项目 +- **无需任何修改**,直接使用最新版本即可 +- 支持 HttpClient 5.x 的模块会自动使用 HttpComponents (5.x) + +### 对现有项目 +- **向后兼容**:不需要修改任何代码 +- HttpClient 4.x 依然可用,项目同时包含两个版本的依赖 +- 如果希望继续使用 HttpClient 4.x,只需在配置中显式指定 + +## 迁移步骤 + +### 1. 更新 WxJava 版本 + +在 `pom.xml` 中更新版本: + +```xml + + com.github.binarywang + weixin-java-mp + 最新版本 + +``` + +### 2. 检查配置(可选) + +#### Spring Boot 项目 + +在 `application.properties` 或 `application.yml` 中: + +```properties +# 使用 HttpClient 5.x(推荐,无需配置,已经是默认值) +wx.mp.config-storage.http-client-type=HttpComponents + +# 或者继续使用 HttpClient 4.x +wx.mp.config-storage.http-client-type=HttpClient +``` + +#### 纯 Java 项目 + +```java +// 使用 HttpClient 5.x(推荐) +WxMpService wxMpService = new WxMpServiceHttpComponentsImpl(); + +// 或者继续使用 HttpClient 4.x +WxMpService wxMpService = new WxMpServiceHttpClientImpl(); +``` + +### 3. 测试应用 + +升级后,建议进行全面测试以确保一切正常工作。 + +## 常见问题 + +### Q: 升级后会不会破坏现有代码? +A: 不会。项目保持完全向后兼容,HttpClient 4.x 的所有实现都保持不变。 + +### Q: 我需要修改代码吗? +A: 大多数情况下不需要。如果希望继续使用 HttpClient 4.x,只需在配置中指定 `http-client-type=HttpClient` 即可。 + +### Q: MiniApp 模块支持 HttpClient 5.x 吗? +A: 支持。MiniApp 模块在核心 SDK 中已经提供了基于 HttpClient 5.x(`HttpComponents`)的支持,但默认仍会使用 HttpClient 4.x(`HttpClient`)以保持向后兼容。如果你使用的是框架集成(例如 Spring Boot Starter 或 Solon Plugin),可以通过显式配置 `http-client-type=HttpComponents` 来启用 HttpClient 5.x。 + +### Q: 我可以在同一个项目中同时使用两个版本吗? +A: 可以。不同的模块可以配置使用不同的 HTTP 客户端。例如,MP 模块使用 HttpClient 5.x,MiniApp 模块默认使用 HttpClient 4.x,但也可以按需配置为 HttpClient 5.x。 + +### Q: 如何排除不需要的依赖? +A: 如果只想使用一个版本,可以在 `pom.xml` 中排除另一个: + +```xml + + com.github.binarywang + weixin-java-mp + 最新版本 + + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpmime + + + +``` + +## 配置参考 + +### Spring Boot 完整配置示例 + +```properties +# 公众号配置 +wx.mp.app-id=your_app_id +wx.mp.secret=your_secret +wx.mp.token=your_token +wx.mp.aes-key=your_aes_key + +# HTTP 客户端配置 +wx.mp.config-storage.http-client-type=HttpComponents # HttpComponents, HttpClient, OkHttp, JoddHttp + +# HTTP 代理配置(可选) +wx.mp.config-storage.http-proxy-host=proxy.example.com +wx.mp.config-storage.http-proxy-port=8080 +wx.mp.config-storage.http-proxy-username=proxy_user +wx.mp.config-storage.http-proxy-password=proxy_pass + +# 超时配置(可选) +wx.mp.config-storage.connection-timeout=5000 +wx.mp.config-storage.so-timeout=5000 +wx.mp.config-storage.connection-request-timeout=5000 +``` + +## 技术细节 + +### HttpClient 4.x 与 5.x 的主要区别 + +1. **包名变更**: + - HttpClient 4.x: `org.apache.http.*` + - HttpClient 5.x: `org.apache.hc.client5.*`, `org.apache.hc.core5.*` + +2. **API 改进**: + - HttpClient 5.x 提供更现代的 API 设计 + - 更好的异步支持 + - 改进的连接池管理 + +3. **性能优化**: + - HttpClient 5.x 包含多项性能优化 + - 更好的资源管理 + +### 项目中的实现 + +WxJava 项目通过策略模式支持多种 HTTP 客户端: + +``` +weixin-java-common/ +├── util/http/ +│ ├── apache/ # HttpClient 4.x 实现 +│ ├── hc/ # HttpClient 5.x (HttpComponents) 实现 +│ ├── okhttp/ # OkHttp 实现 +│ └── jodd/ # Jodd-http 实现 +``` + +每个模块都有对应的 Service 实现类: +- `*ServiceHttpClientImpl` - 使用 HttpClient 4.x +- `*ServiceHttpComponentsImpl` - 使用 HttpClient 5.x +- `*ServiceOkHttpImpl` - 使用 OkHttp +- `*ServiceJoddHttpImpl` - 使用 Jodd-http + +## 反馈与支持 + +如果在升级过程中遇到问题,请: + +1. 查看 [项目 Wiki](https://github.com/binarywang/WxJava/wiki) +2. 在 [GitHub Issues](https://github.com/binarywang/WxJava/issues) 中搜索或提交问题 +3. 加入技术交流群(见 README.md) + +## 总结 + +- ✅ **推荐使用 HttpClient 5.x**:性能更好,功能更强 +- ✅ **向后兼容**:可以继续使用 HttpClient 4.x +- ✅ **灵活配置**:支持多种 HTTP 客户端,按需选择 +- ✅ **平滑迁移**:无需修改代码,仅需配置即可 diff --git a/pom.xml b/pom.xml index 0a33fbdf1..5740a2779 100644 --- a/pom.xml +++ b/pom.xml @@ -136,6 +136,7 @@ UTF-8 4.5.13 + 5.5 9.4.57.v20241219 @@ -157,13 +158,14 @@ 4.12.0 provided + org.apache.httpcomponents.client5 httpclient5 - 5.5 - provided + ${httpclient5.version} + org.apache.httpcomponents httpclient diff --git a/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/enums/HttpClientType.java b/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/enums/HttpClientType.java index 0c00dbcaa..5614f63e8 100644 --- a/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/enums/HttpClientType.java +++ b/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/enums/HttpClientType.java @@ -7,7 +7,11 @@ */ public enum HttpClientType { /** - * HttpClient + * HttpClient. */ - HttpClient + HttpClient, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelProperties.java b/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelProperties.java index 6562a02e9..89b81b7d9 100644 --- a/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelProperties.java +++ b/solon-plugins/wx-java-channel-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelProperties.java @@ -73,7 +73,7 @@ public static class ConfigStorage { /** * http客户端类型 */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机 diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/enums/HttpClientType.java b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/enums/HttpClientType.java index a4475a02c..d116a30cf 100644 --- a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/enums/HttpClientType.java +++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/enums/HttpClientType.java @@ -19,4 +19,8 @@ public enum HttpClientType { * JoddHttp. */ JoddHttp, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/enums/HttpClientType.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/enums/HttpClientType.java index 9b1a8ccbf..2858d77e4 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/enums/HttpClientType.java +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/enums/HttpClientType.java @@ -19,4 +19,8 @@ public enum HttpClientType { * JoddHttp. */ JoddHttp, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/properties/WxMpProperties.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/properties/WxMpProperties.java index cda0aa88e..0dcc6b41d 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/properties/WxMpProperties.java +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/properties/WxMpProperties.java @@ -79,7 +79,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/enums/HttpClientType.java b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/enums/HttpClientType.java index 0b94821da..5729ab8fd 100644 --- a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/enums/HttpClientType.java +++ b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/enums/HttpClientType.java @@ -19,4 +19,8 @@ public enum HttpClientType { * JoddHttp. */ JoddHttp, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/properties/WxQidianProperties.java b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/properties/WxQidianProperties.java index 67c4dba54..e99f882e6 100644 --- a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/properties/WxQidianProperties.java +++ b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/properties/WxQidianProperties.java @@ -74,7 +74,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/configuration/services/AbstractWxChannelConfiguration.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/configuration/services/AbstractWxChannelConfiguration.java index 3462bbc25..e2f9f87f5 100644 --- a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/configuration/services/AbstractWxChannelConfiguration.java +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/configuration/services/AbstractWxChannelConfiguration.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.channel.api.WxChannelService; import me.chanjar.weixin.channel.api.impl.WxChannelServiceHttpClientImpl; +import me.chanjar.weixin.channel.api.impl.WxChannelServiceHttpComponentsImpl; import me.chanjar.weixin.channel.api.impl.WxChannelServiceImpl; import me.chanjar.weixin.channel.config.WxChannelConfig; import me.chanjar.weixin.channel.config.impl.WxChannelDefaultConfigImpl; @@ -84,6 +85,9 @@ public WxChannelService wxChannelService(WxChannelConfig wxChannelConfig, WxChan case HTTP_CLIENT: wxChannelService = new WxChannelServiceHttpClientImpl(); break; + case HTTP_COMPONENTS: + wxChannelService = new WxChannelServiceHttpComponentsImpl(); + break; default: wxChannelService = new WxChannelServiceImpl(); break; diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java index 6ca09354a..adc8a2b52 100644 --- a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java @@ -8,7 +8,7 @@ */ public enum HttpClientType { /** - * HttpClient + * HttpClient. */ HTTP_CLIENT, // WxChannelServiceOkHttpImpl 实现经测试无法正常完成业务固暂不支持OK_HTTP方式 @@ -16,4 +16,8 @@ public enum HttpClientType { // * OkHttp. // */ // OK_HTTP, + /** + * HttpComponents. + */ + HTTP_COMPONENTS, } diff --git a/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java b/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java index 63a7bf0c2..e4b3f3ad1 100644 --- a/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java +++ b/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/enums/HttpClientType.java @@ -7,7 +7,11 @@ */ public enum HttpClientType { /** - * HttpClient + * HttpClient. */ - HttpClient + HttpClient, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelProperties.java b/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelProperties.java index 43c35fbd1..f43d297e0 100644 --- a/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelProperties.java +++ b/spring-boot-starters/wx-java-channel-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelProperties.java @@ -85,7 +85,7 @@ public static class ConfigStorage { /** * http客户端类型 */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机 diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/enums/HttpClientType.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/enums/HttpClientType.java index b3e4b464f..48549e439 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/enums/HttpClientType.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/enums/HttpClientType.java @@ -8,7 +8,7 @@ */ public enum HttpClientType { /** - * HttpClient. + * HttpClient (Apache HttpClient 4.x). */ HttpClient, /** @@ -19,4 +19,8 @@ public enum HttpClientType { * JoddHttp. */ JoddHttp, + /** + * HttpComponents (Apache HttpClient 5.x). + */ + HttpComponents, } diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md index 3e14f499d..091912cfa 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md @@ -27,7 +27,7 @@ #wx.mp.config-storage.redis.sentinel-ips=127.0.0.1:16379,127.0.0.1:26379 #wx.mp.config-storage.redis.sentinel-name=mymaster # http客户端配置 - wx.mp.config-storage.http-client-type=httpclient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp + wx.mp.config-storage.http-client-type=HttpComponents # http客户端类型: HttpComponents(Apache HttpClient 5.x,推荐), HttpClient(Apache HttpClient 4.x), OkHttp, JoddHttp wx.mp.config-storage.http-proxy-host= wx.mp.config-storage.http-proxy-port= wx.mp.config-storage.http-proxy-username= diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java index 377fb5b6a..a6c6e3b6b 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java @@ -80,7 +80,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/enums/HttpClientType.java b/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/enums/HttpClientType.java index 1a927211c..04589a911 100644 --- a/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/enums/HttpClientType.java +++ b/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/enums/HttpClientType.java @@ -19,4 +19,8 @@ public enum HttpClientType { * JoddHttp. */ JoddHttp, + /** + * HttpComponents. + */ + HttpComponents, } diff --git a/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/properties/WxQidianProperties.java b/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/properties/WxQidianProperties.java index ddecefb7e..bec5dfcce 100644 --- a/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/properties/WxQidianProperties.java +++ b/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/qidian/properties/WxQidianProperties.java @@ -72,7 +72,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index e5427942c..9032af97d 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -24,20 +24,13 @@ okhttp provided + org.apache.httpcomponents.client5 httpclient5 - provided - - org.slf4j - slf4j-api - - - com.thoughtworks.xstream - xstream - + org.apache.httpcomponents httpclient @@ -52,6 +45,15 @@ org.apache.httpcomponents httpmime + + + org.slf4j + slf4j-api + + + com.thoughtworks.xstream + xstream + org.slf4j jcl-over-slf4j From 37c2db9672f9b84ba33c4618571d088717d91373 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 13:01:40 +0800 Subject: [PATCH 05/33] =?UTF-8?q?:art:=20#3832=20=E3=80=90=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E3=80=91=E4=BF=AE=E5=A4=8D=20WxSign?= =?UTF-8?q?QueryResult=20=E4=B8=AD=20contract=5Fexpired=5Ftime=20=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/result/WxSignQueryResult.java | 2 +- .../bean/result/WxSignQueryResultTest.java | 125 ++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java index 524159719..af19aec60 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java @@ -112,7 +112,7 @@ protected void loadXml(Document d) { contractDisplayAccount = readXmlString(d, "contract_display_account"); contractState = readXmlInteger(d, "contract_state"); contractSignedTime = readXmlString(d, "contract_signed_time"); - contractExpiredTime = readXmlString(d, "contrace_Expired_time"); + contractExpiredTime = readXmlString(d, "contract_expired_time"); contractTerminatedTime = readXmlString(d, "contract_terminated_time"); contractTerminatedMode = readXmlInteger(d, "contract_termination_mode"); contractTerminationRemark = readXmlString(d, "contract_termination_remark"); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java new file mode 100644 index 000000000..52df2b6e2 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java @@ -0,0 +1,125 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.github.binarywang.wxpay.util.XmlConfig; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * WxSignQueryResult 单元测试 + * + * @author Binary Wang + */ +public class WxSignQueryResultTest { + + /** + * 测试 XML 解析,特别是 contract_expired_time 字段 + */ + @Test + public void testFromXML() { + /* + * xml样例字符串来自于官方文档 + * https://pay.weixin.qq.com/doc/v2/merchant/4011987640 + */ + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 203\n" + + " 66\n" + + " \n" + + " 123\n" + + " \n" + + " \n" + + " 1\n" + + " 2015-07-01 10:00:00\n" + + " 2015-07-01 10:00:00\n" + + " 2015-07-01 10:00:00\n" + + " 3\n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + ""; + + // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支 + XmlConfig.fastMode = true; + try { + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + + // 验证基本字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getMchId(), "80000000"); + Assert.assertEquals(result.getAppid(), "wx426b3015555b46be"); + + // 验证签约相关字段 + Assert.assertEquals(result.getContractId(), "203"); + Assert.assertEquals(result.getPlanId(), "66"); + Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs"); + Assert.assertEquals(result.getRequestSerial().longValue(), 123L); + Assert.assertEquals(result.getContractCode(), "1005"); + Assert.assertEquals(result.getContractDisplayAccount(), "test"); + Assert.assertEquals(result.getContractState().intValue(), 1); + + // 重点测试时间字段,特别是 contract_expired_time + Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00"); + + // 验证其他字段 + Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3); + Assert.assertEquals(result.getContractTerminationRemark(), "delete ...."); + } finally { + // 恢复默认值 + XmlConfig.fastMode = false; + } + } + + /** + * 测试 XML 解析 - 只包含必填字段 + */ + @Test + public void testFromXML_RequiredFieldsOnly() { + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Wx15463511252015071056489715\n" + + " 123\n" + + " 1695\n" + + " \n" + + " \n" + + " 0\n" + + " 2015-07-01 10:00:00\n" + + " 2016-07-01 10:00:00\n" + + " \n" + + " \n" + + ""; + + // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支 + XmlConfig.fastMode = true; + try { + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + + // 验证必填字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715"); + Assert.assertEquals(result.getPlanId(), "123"); + Assert.assertEquals(result.getContractState().intValue(), 0); + + // 验证 contract_expired_time 字段能正确解析 + Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00"); + + // 验证非必填字段为 null + Assert.assertNull(result.getContractTerminatedTime()); + Assert.assertNull(result.getContractTerminatedMode()); + Assert.assertNull(result.getContractTerminationRemark()); + } finally { + // 恢复默认值 + XmlConfig.fastMode = false; + } + } +} From 51d2ed7a3c707d6269c686dab15fcf0a27183c80 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 6 Jan 2026 16:51:30 +0800 Subject: [PATCH 06/33] =?UTF-8?q?:art:=20=E6=89=B9=E9=87=8F=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=83=A8=E5=88=86javadoc=E9=87=8C=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=A0=87=E7=AD=BE=E6=88=96=E4=B8=8D=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/common/api/WxConsts.java | 2 +- .../bean/oauth2/WxOAuth2AccessToken.java | 9 +- .../weixin/common/error/WxCpErrorMsgEnum.java | 4 +- .../chanjar/weixin/common/error/WxError.java | 4 +- .../weixin/common/error/WxMaErrorMsgEnum.java | 47 +++---- .../common/error/WxOpenErrorMsgEnum.java | 24 ++-- .../weixin/common/service/WxOcrService.java | 4 +- .../session/InternalSessionManager.java | 5 +- .../chanjar/weixin/common/util/SignUtils.java | 1 + .../weixin/common/util/crypto/SHA1.java | 5 +- .../common/util/crypto/WxCryptUtil.java | 1 + .../common/util/http/InputStreamData.java | 3 +- .../http/apache/ApacheHttpClientBuilder.java | 26 +++- .../common/util/json/WxGsonBuilder.java | 5 + .../common/util/xml/XStreamInitializer.java | 5 + .../weixin/cp/api/WxCpCorpGroupService.java | 2 +- .../weixin/cp/api/WxCpExportService.java | 2 +- .../cp/api/WxCpExternalContactService.java | 129 ++++++++++-------- .../weixin/cp/api/WxCpGroupRobotService.java | 7 +- .../chanjar/weixin/cp/api/WxCpKfService.java | 4 +- .../weixin/cp/api/WxCpLivingService.java | 2 +- .../weixin/cp/api/WxCpMediaService.java | 4 +- .../weixin/cp/api/WxCpMessageService.java | 3 +- .../weixin/cp/api/WxCpOAuth2Service.java | 13 +- .../cp/api/WxCpOaMeetingRoomService.java | 11 +- .../chanjar/weixin/cp/api/WxCpOaService.java | 5 +- .../weixin/cp/api/WxCpSchoolService.java | 5 +- .../weixin/cp/api/WxCpSchoolUserService.java | 45 +++--- .../me/chanjar/weixin/cp/api/WxCpService.java | 2 +- .../weixin/cp/api/WxCpUserService.java | 4 +- .../cp/api/impl/WxCpCorpGroupServiceImpl.java | 2 +- .../impl/WxCpExternalContactServiceImpl.java | 2 +- .../chanjar/weixin/cp/bean/WxCpBaseResp.java | 3 +- .../weixin/cp/bean/WxCpTpAuthInfo.java | 2 +- .../cp/bean/WxCpTpPermanentCodeInfo.java | 2 +- .../me/chanjar/weixin/cp/bean/WxCpTpTag.java | 2 +- .../bean/WxCpTpTagAddOrRemoveUsersResult.java | 2 +- .../weixin/cp/bean/WxCpTpTagGetResult.java | 2 +- .../cp/bean/external/WxCpMsgTemplate.java | 5 +- .../WxCpUserExternalUnassignList.java | 3 +- .../WxCpCustomerAcquisitionStatistic.java | 2 +- .../interceptrule/WxCpInterceptRuleInfo.java | 7 +- .../interceptrule/WxCpInterceptRuleList.java | 7 +- .../cp/bean/external/msg/Attachment.java | 5 + .../weixin/cp/bean/kf/WxCpKfAccountLink.java | 4 +- .../cp/bean/media/MediaUploadByUrlReq.java | 3 +- .../cp/bean/media/MediaUploadByUrlResult.java | 3 +- .../bean/message/WxCpLinkedCorpMessage.java | 14 +- .../cp/bean/message/WxCpXmlMessage.java | 24 ++-- .../messagebuilder/TemplateCardBuilder.java | 3 +- .../cp/bean/oa/WxCpCheckinGroupBase.java | 4 +- .../weixin/cp/bean/oa/WxCpOaSchedule.java | 2 +- .../WxCpOaMeetingRoomBookResult.java | 2 +- .../cp/bean/oa/templatedata/TemplateTips.java | 2 +- .../oa/templatedata/TemplateTipsContent.java | 2 +- .../oa/templatedata/TemplateTipsSubText.java | 2 +- .../TemplateTipsSubTextContent.java | 2 +- .../TemplateTipsSubTextContentLink.java | 2 +- .../TemplateTipsSubTextContentPlainText.java | 6 +- .../oa/templatedata/TemplateTipsText.java | 6 +- .../cp/config/WxCpCorpGroupConfigStorage.java | 23 ++-- .../weixin/cp/config/WxCpTpConfigStorage.java | 2 +- .../impl/AbstractWxCpTpInRedisConfigImpl.java | 4 +- .../config/impl/WxCpTpDefaultConfigImpl.java | 6 +- .../weixin/cp/constant/WxCpConsts.java | 2 +- .../cp/corpgroup/service/WxCpCgService.java | 38 ++++-- .../service/impl/BaseWxCpCgServiceImpl.java | 4 + .../cp/tp/service/WxCpTpEditionService.java | 2 +- .../cp/tp/service/WxCpTpIdConvertService.java | 32 +++-- .../weixin/cp/tp/service/WxCpTpOAService.java | 3 +- .../cp/tp/service/WxCpTpOrderService.java | 4 +- .../weixin/cp/tp/service/WxCpTpService.java | 14 +- .../cp/tp/service/WxCpTpTagService.java | 2 +- .../impl/WxCpTpEditionServiceImpl.java | 2 +- .../service/impl/WxCpTpOrderServiceImpl.java | 4 +- .../tp/service/impl/WxCpTpTagServiceImpl.java | 2 +- .../cp/util/xml/XStreamTransformer.java | 4 +- .../wx/miniapp/config/WxMaConfig.java | 26 ++++ .../wx/miniapp/util/crypt/WxMaCryptUtils.java | 2 + .../miniapp/util/xml/XStreamTransformer.java | 22 ++- .../weixin/mp/api/WxMpCardService.java | 4 +- .../weixin/mp/api/WxMpCommentService.java | 4 +- .../weixin/mp/api/WxMpDataCubeService.java | 98 +++++++++---- .../me/chanjar/weixin/mp/api/WxMpService.java | 86 ++++++------ .../mp/api/impl/BaseWxMpServiceImpl.java | 5 +- .../mp/bean/WxMpMassOpenIdsMessage.java | 12 +- .../mp/bean/WxMpMassPreviewMessage.java | 10 +- .../weixin/mp/bean/WxMpMassTagMessage.java | 10 +- .../chanjar/weixin/mp/bean/WxMpUserQuery.java | 5 +- .../card/WxMpCardMpnewsGethtmlResult.java | 4 +- .../MemberCardActivateUserFormRequest.java | 8 +- .../card/membercard/MemberCardUserForm.java | 3 + .../bean/card/membercard/NotifyOptional.java | 9 +- .../WxMpMemberCardUpdateResult.java | 6 +- .../WxMpMemberCardUserInfoResult.java | 7 +- .../weixin/mp/bean/kefu/WxMpKefuMessage.java | 31 ++++- .../mp/bean/message/WxMpXmlMessage.java | 31 +++-- .../mp/bean/message/WxMpXmlOutMessage.java | 27 ++++ .../mp/bean/result/WxMpMassGetResult.java | 3 +- .../weixin/mp/config/WxMpConfigStorage.java | 6 +- .../mp/config/impl/WxMpRedisConfigImpl.java | 2 + .../config/impl/WxMpRedissonConfigImpl.java | 2 + .../mp/constant/WxMpEventConstants.java | 2 +- .../weixin/mp/util/crypto/WxMpCryptUtil.java | 2 +- .../mp/util/xml/XStreamTransformer.java | 22 ++- .../bean/notify/MiPayNotifyV3Result.java | 2 +- .../bean/notify/WxPayBaseNotifyV3Result.java | 13 +- .../bean/notify/WxPayNotifyV3Response.java | 6 +- .../binarywang/wxpay/config/WxPayConfig.java | 5 +- .../binarywang/wxpay/util/RequestUtils.java | 2 +- .../binarywang/wxpay/util/ResourcesUtils.java | 11 ++ .../binarywang/wxpay/util/SignUtils.java | 24 +++- 112 files changed, 751 insertions(+), 419 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index 70c4e4793..d7e8936e6 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -12,7 +12,7 @@ /** * 微信开发所使用到的常量类. * - * @author Daniel Qian & binarywang & Wang_Wong + * @author Daniel Qian, binarywang, Wang_Wong */ @UtilityClass public class WxConsts { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java index c08a49063..b339844ad 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java @@ -7,7 +7,10 @@ import java.io.Serializable; /** - * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 + * OAuth2 AccessToken + *

+ * 参考:{@code https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842} + *

* * @author Daniel Qian */ @@ -36,8 +39,10 @@ public class WxOAuth2AccessToken implements Serializable { private Integer snapshotUser; /** - * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN. * 本接口在scope参数为snsapi_base时不再提供unionID字段。 + *

+ * 参考:{@code https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN} + *

*/ @SerializedName("unionid") private String unionId; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java index ea1e9e7c6..356d1dbbf 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java @@ -453,7 +453,7 @@ public enum WxCpErrorMsgEnum { */ CODE_60008(60008, "部门已存在;部门ID或者部门名称已存在"), /** - * 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符. + * {@code 部门名称含有非法字符;不能含有 \\:?*"< >| 等字符.} */ CODE_60009(60009, "部门名称含有非法字符;不能含有 \\ :?*“< >| 等字符"), /** @@ -521,7 +521,7 @@ public enum WxCpErrorMsgEnum { */ CODE_60124(60124, "无效的父部门id;父部门不存在通讯录中"), /** - * 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符. + * {@code 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?"< >|等字符.} */ CODE_60125(60125, "非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符"), /** diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java index b45fba341..1aab7f1f2 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java @@ -12,11 +12,13 @@ /** * 微信错误码. + *

* 请阅读: * 公众平台:全局返回码说明 * 企业微信:全局错误码 + *

* - * @author Daniel Qian & Binary Wang + * @author Daniel Qian, Binary Wang */ @Data @NoArgsConstructor 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 1bb3f6472..ffe9b5e3e 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 @@ -46,23 +46,23 @@ public enum WxMaErrorMsgEnum { */ CODE_40003(40003, "openid 不正确"), /** - *
    * 无效媒体文件类型
-   * 对应操作:uploadTempMedia
+   * 

+ * 对应操作:{@code uploadTempMedia} * 对应地址: - * POST https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE + * {@code POST https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE} * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/uploadTempMedia.html - *

+ *

*/ CODE_40004(40004, "无效媒体文件类型"), /** - *
    * 无效媒体文件 ID.
-   * 对应操作:getTempMedia
+   * 

+ * 对应操作:{@code getTempMedia} * 对应地址: - * GET https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID + * {@code GET https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID} * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/getTempMedia.html - *

+ *

*/ CODE_40007(40007, "无效媒体文件 ID"), /** @@ -99,29 +99,29 @@ public enum WxMaErrorMsgEnum { */ CODE_41028(41028, "form_id 不正确,或者过期"), /** - *
    * code 或 template_id 不正确.
-   * 对应操作:code2Session, sendUniformMessage, sendTemplateMessage
+   * 

+ * 对应操作:{@code code2Session}, {@code sendUniformMessage}, {@code sendTemplateMessage} * 对应地址: - * GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code + * {@code GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code} * POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN * POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/code2Session.html * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/template-message/sendTemplateMessage.html - *

+ *

*/ CODE_41029(41029, "请求的参数不正确"), /** - *
    * form_id 已被使用,或者所传page页面不存在,或者小程序没有发布
-   * 对应操作:sendUniformMessage, getWXACodeUnlimit
+   * 

+ * 对应操作:{@code sendUniformMessage}, {@code getWXACodeUnlimit} * 对应地址: * POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN * POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html - * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html - *

+ * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html + *

*/ CODE_41030(41030, "请求的参数不正确"), /** @@ -138,13 +138,13 @@ public enum WxMaErrorMsgEnum { */ CODE_45009(45009, "调用分钟频率受限"), /** - *
    * 频率限制,每个用户每分钟100次.
-   * 对应操作:code2Session
+   * 

+ * 对应操作:{@code code2Session} * 对应地址: - * GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code + * {@code GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code} * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/code2Session.html - *

+ *

*/ CODE_45011(45011, "频率限制,每个用户每分钟100次"), /** @@ -190,12 +190,13 @@ public enum WxMaErrorMsgEnum { */ CODE_45072(45072, "command字段取值不对"), /** - *
    * 下发输入状态,需要之前30秒内跟用户有过消息交互.
-   * 对应操作:customerTyping
+   * 

+ * 对应操作:{@code customerTyping} * 对应地址: * POST https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=ACCESS_TOKEN * 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/customerTyping.html + *

*/ CODE_45080(45080, "下发输入状态,需要之前30秒内跟用户有过消息交互"), /** @@ -686,7 +687,7 @@ public enum WxMaErrorMsgEnum { /** * 89252 - * 法人&企业信息一致性校验中 front checking + * {@code 法人&企业信息一致性校验中 front checking} */ CODE_89252(89252, "法人&企业信息一致性校验中"), diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java index 28fb5de8a..ba910e988 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java @@ -527,7 +527,7 @@ public enum WxOpenErrorMsgEnum { CODE_40099(40099, "invalid code, this code has consumed."), /** - * invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime + * {@code invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime} */ CODE_40100(40100, "invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime"), @@ -572,7 +572,7 @@ public enum WxOpenErrorMsgEnum { CODE_40108(40108, "invalid client version"), /** - * too many code size, must <= 100 + * {@code too many code size, must <= 100} */ CODE_40109(40109, "too many code size, must <= 100"), @@ -702,7 +702,7 @@ public enum WxOpenErrorMsgEnum { CODE_40135(40135, "invalid not supply bonus, can not change card_id which supply bonus to be not supply"), /** - * invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity + * {@code invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity} */ CODE_40136(40136, "invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity"), @@ -1082,7 +1082,7 @@ public enum WxOpenErrorMsgEnum { CODE_40211(40211, "invalid scope_data"), /** - * paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2 invalid query + * {@code paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2 invalid query} */ CODE_40212(40212, "paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2"), @@ -4242,7 +4242,7 @@ public enum WxOpenErrorMsgEnum { CODE_71005(71005, "limit exe count"), /** - * limit coin count, 1 <= coin_count <= 100000 + * {@code limit coin count, 1 <= coin_count <= 100000} */ CODE_71006(71006, "limit coin count, 1 <= coin_count <= 100000"), @@ -4347,7 +4347,7 @@ public enum WxOpenErrorMsgEnum { CODE_72018(72018, "duplicate order id, invoice had inserted to user"), /** - * limit msg operation card list size, must <= 5 + * {@code limit msg operation card list size, must <= 5} */ CODE_72019(72019, "limit msg operation card list size, must <= 5"), @@ -6432,7 +6432,7 @@ public enum WxOpenErrorMsgEnum { CODE_88009(88009, "reply is not exists"), /** - * count range error. cout <= 0 or count > 50 + * {@code count range error. cout <= 0 or count > 50} */ CODE_88010(88010, "count range error. cout <= 0 or count > 50"), @@ -6682,7 +6682,7 @@ public enum WxOpenErrorMsgEnum { CODE_89251(89251, "模板消息已下发,待法人人脸核身校验"), /** - * 法人&企业信息一致性校验中 front checking + * {@code 法人&企业信息一致性校验中 front checking} */ CODE_89253(89253, "法人&企业信息一致性校验中"), @@ -7257,7 +7257,7 @@ public enum WxOpenErrorMsgEnum { CODE_200021(200021, "场景描述 sceneDesc 参数错误"), /** - * 禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间 + * {@code 禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间} */ CODE_300001(300001, "禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间"), @@ -8382,7 +8382,7 @@ public enum WxOpenErrorMsgEnum { CODE_9300003(9300003, "begin_time must less than end_time"), /** - * end_time - begin_time > 1year + * {@code end_time - begin_time > 1year} */ CODE_9300004(9300004, "end_time - begin_time > 1year"), @@ -8397,7 +8397,7 @@ public enum WxOpenErrorMsgEnum { CODE_9300006(9300006, "invalid activity status"), /** - * gift_num must >0 and <=15 + * {@code gift_num must >0 and <=15} */ CODE_9300007(9300007, "gift_num must >0 and <=15"), @@ -8412,7 +8412,7 @@ public enum WxOpenErrorMsgEnum { CODE_9300009(9300009, "activity can not finish"), /** - * card_info_list must >= 2 + * {@code card_info_list must >= 2} */ CODE_9300010(9300010, "card_info_list must >= 2"), diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java index 39a8a9375..d0aeef849 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java @@ -12,7 +12,9 @@ /** * 基于小程序或 H5 的身份证、银行卡、行驶证 OCR 识别. - * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712284rHWMX + *

+ * 参考:{@code https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712284rHWMX} + *

* * @author Binary Wang * created on 2019-06-22 diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java index e3d9ab835..24ea58ef3 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java @@ -7,13 +7,12 @@ public interface InternalSessionManager { /** * Return the active Session, associated with this Manager, with the - * specified session id (if any); otherwise return null. + * specified session id (if any); otherwise return {@code null}. * * @param id The session id for the session to be returned + * @return the session or null * @throws IllegalStateException if a new session cannot be * instantiated for any reason - * @throws java.io.IOException if an input/output error occurs while - * processing this request */ InternalSession findSession(String id); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java index fc3579d45..1886209f9 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java @@ -25,6 +25,7 @@ public class SignUtils { * * @param message 签名数据 * @param key 签名密钥 + * @return 签名结果 */ public static String createHmacSha256Sign(String message, String key) { try { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java index 9b9f77676..43cc54b43 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java @@ -29,7 +29,10 @@ public static String gen(String... arr) { } /** - * 用&串接arr参数,生成sha1 digest. + * {@code 用&串接arr参数,生成sha1 digest.} + * + * @param arr 参数数组 + * @return sha1摘要 */ public static String genWithAmple(String... arr) { if (StringUtils.isAnyEmpty(arr)) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java index 0b0590b1e..50362636f 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java @@ -197,6 +197,7 @@ public EncryptContext encryptContext(String plainText) { /** * 对明文进行加密. * + * @param randomStr 随机字符串 * @param plainText 需要加密的明文 * @return 加密后base64编码的字符串 */ diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamData.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamData.java index d07873f3c..f03932984 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamData.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamData.java @@ -10,8 +10,9 @@ /** * 输入流数据. - *

+ *

* InputStreamData + *

* * @author zichuan.zhou91@gmail.com * created on 2022/2/15 diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java index de34ca5bd..5b13e7cc1 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java @@ -21,42 +21,66 @@ public interface ApacheHttpClientBuilder { /** * 代理服务器地址. + * + * @param httpProxyHost 代理服务器地址 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); /** * 代理服务器端口. + * + * @param httpProxyPort 代理服务器端口 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); /** * 代理服务器用户名. + * + * @param httpProxyUsername 代理服务器用户名 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); /** * 代理服务器密码. + * + * @param httpProxyPassword 代理服务器密码 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); /** * 重试策略. + * + * @param httpRequestRetryHandler 重试处理器 + * @return ApacheHttpClientBuilder */ - ApacheHttpClientBuilder httpRequestRetryHandler(HttpRequestRetryHandler httpRequestRetryHandler ); + ApacheHttpClientBuilder httpRequestRetryHandler(HttpRequestRetryHandler httpRequestRetryHandler); /** * 超时时间. + * + * @param keepAliveStrategy 保持连接策略 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder keepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy); /** * ssl连接socket工厂. + * + * @param sslConnectionSocketFactory SSL连接Socket工厂 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); /** * 支持的TLS协议版本. * Supported TLS protocol versions. + * + * @param supportedProtocols 支持的协议版本数组 + * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder supportedProtocols(String[] supportedProtocols); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java index 6ea269f7e..8f3dafe48 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java @@ -43,6 +43,11 @@ public boolean shouldSkipClass(Class aClass) { }); } + /** + * 创建Gson实例 + * + * @return Gson实例 + */ public static Gson create() { if (Objects.isNull(GSON_INSTANCE)) { synchronized (INSTANCE) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java index 3fa91fa70..51cd1e980 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java @@ -22,6 +22,11 @@ public class XStreamInitializer { public static ClassLoader classLoader; + /** + * 设置类加载器 + * + * @param classLoaderInfo 类加载器 + */ public static void setClassLoader(ClassLoader classLoaderInfo) { classLoader = classLoaderInfo; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpGroupService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpGroupService.java index 4da13d3fd..69aea4bca 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpGroupService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpGroupService.java @@ -9,7 +9,7 @@ * 企业互联相关接口 * * @author libo <422423229@qq.com> - * Created on 27/2/2023 9:57 PM + * @since 2023-02-27 9:57 PM */ public interface WxCpCorpGroupService { /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExportService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExportService.java index 24c6ea9dc..a2c7adabe 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExportService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExportService.java @@ -85,7 +85,7 @@ public interface WxCpExportService { * 获取导出结果 * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/export/get_result?access_token=ACCESS_TOKEN&jobid=jobid_xxxxxxxxxxxxxxx + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/export/get_result?access_token=ACCESS_TOKEN&jobid=jobid_xxxxxxxxxxxxxxx} * * 文档地址:https://developer.work.weixin.qq.com/document/path/94854 * 返回的url文件下载解密可参考 CSDN 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 7f3cdeab7..6de9f9226 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 @@ -146,7 +146,7 @@ public interface WxCpExternalContactService { * 企业可通过此接口,根据外部联系人的userid(如何获取?),拉取客户详情。 * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid=EXTERNAL_USERID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid=EXTERNAL_USERID} * * 权限说明: * @@ -252,9 +252,9 @@ public interface WxCpExternalContactService { * * 权限说明: * - * 该企业授权了该服务商第三方应用,且授权的第三方应用具备“企业客户权限->客户基础信息”权限 + * {@code 该企业授权了该服务商第三方应用,且授权的第三方应用具备“企业客户权限->客户基础信息”权限} * 该客户的跟进人必须在应用的可见范围之内 - * 应用需具备“企业客户权限->客户基础信息”权限 + * {@code 应用需具备“企业客户权限->客户基础信息”权限} *
* * @param externalUserid 代开发自建应用获取到的外部联系人ID @@ -276,8 +276,8 @@ public interface WxCpExternalContactService { * * @param externalUserid 服务商主体的external_userid,必须是source_agentid对应的应用所获取 * @param sourceAgentId 企业授权的代开发自建应用或第三方应用的agentid - * @return - * @throws WxErrorException + * @return 企业的external_userid + * @throws WxErrorException 微信错误异常 */ String fromServiceExternalUserid(String externalUserid, String sourceAgentId) throws WxErrorException; @@ -362,7 +362,7 @@ public interface WxCpExternalContactService { * 权限说明: * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?) - * 第三方应用需具有“企业客户权限->客户基础信息”权限 + * {@code 第三方应用需具有“企业客户权限->客户基础信息”权限} * 对于第三方/自建应用,群主必须在应用的可见范围 * 仅支持企业服务人员创建的客户群 * 仅可转换出自己企业下的客户群chat_id @@ -410,11 +410,12 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String[] userIdList, String c * 文档地址: https://developer.work.weixin.qq.com/document/path/99434 * * + * 注意:企业可通过外部联系人临时ID排除重复数据,外部联系人临时ID有效期为4小时。 + * * @param cursor the cursor * @param limit the limit * @return 已服务的外部联系人列表 * @throws WxErrorException . - * @apiNote 企业可通过外部联系人临时ID排除重复数据,外部联系人临时ID有效期为4小时。 */ WxCpExternalContactListInfo getContactList(String cursor, Integer limit) throws WxErrorException; @@ -438,7 +439,7 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String[] userIdList, String c * 企业可通过此接口获取指定成员添加的客户列表。客户是指配置了客户联系功能的成员所添加的外部联系人。没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。 * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=ACCESS_TOKEN&userid=USERID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=ACCESS_TOKEN&userid=USERID} * * 权限说明: * @@ -469,7 +470,8 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String[] userIdList, String c /** * 获取待分配的离职成员列表 * 企业和第三方可通过此接口,获取所有离职成员的客户列表,并可进一步调用分配离职成员的客户接口将这些客户重新分配给其他企业成员。 - *

+ + * * 请求方式:POST(HTTPS) * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=ACCESS_TOKEN * @@ -496,17 +498,17 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String[] userIdList, String c /** * 企业可通过此接口,转接在职成员的客户给其他成员。 - * + *

    * external_userid必须是handover_userid的客户(即配置了客户联系功能的成员所添加的联系人)。
    * 在职成员的每位客户最多被分配2次。客户被转接成功后,将有90个自然日的服务关系保护期,保护期内的客户无法再次被分配。
-   * 

+ * * 权限说明: - * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 - * 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限 + * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 + * {@code 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限} * 接替成员必须在此第三方应用或自建应用的可见范围内。 * 接替成员需要配置了客户联系功能。 * 接替成员需要在企业微信激活且已经过实名认证。 - * + *

* * @param req 转接在职成员的客户给其他成员请求实体 * @return wx cp base resp @@ -516,13 +518,13 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String[] userIdList, String c /** * 企业和第三方可通过此接口查询在职成员的客户转接情况。 - * + *
    * 权限说明:
-   * 

+ * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 - * 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限 + * {@code 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限} * 接替成员必须在此第三方应用或自建应用的可见范围内。 - * + *

* * @param handOverUserid 原添加成员的userid * @param takeOverUserid 接替成员的userid @@ -535,19 +537,21 @@ WxCpUserTransferResultResp transferResult(String handOverUserid, String takeOver /** * 企业可通过此接口,分配离职成员的客户给其他成员。 - * + *
    * handover_userid必须是已离职用户。
    * external_userid必须是handover_userid的客户(即配置了客户联系功能的成员所添加的联系人)。
    * 在职成员的每位客户最多被分配2次。客户被转接成功后,将有90个自然日的服务关系保护期,保护期内的客户无法再次被分配。
-   * 

+ + * * 权限说明: - *

+ + * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 - * 第三方应用需拥有“企业客户权限->客户联系->离职分配”权限 + * {@code 第三方应用需拥有“企业客户权限->客户联系->离职分配”权限} * 接替成员必须在此第三方应用或自建应用的可见范围内。 * 接替成员需要配置了客户联系功能。 * 接替成员需要在企业微信激活且已经过实名认证。 - * + *

* * @param req 转接在职成员的客户给其他成员请求实体 * @return wx cp base resp @@ -557,13 +561,14 @@ WxCpUserTransferResultResp transferResult(String handOverUserid, String takeOver /** * 企业和第三方可通过此接口查询离职成员的客户分配情况。 - * + *
    * 权限说明:
-   * 

+ + * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 - * 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限 + * {@code 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限} * 接替成员必须在此第三方应用或自建应用的可见范围内。 - * + *

* * @param handOverUserid 原添加成员的userid * @param takeOverUserid 接替成员的userid @@ -630,21 +635,24 @@ WxCpUserExternalGroupChatList listGroupChat(Integer pageIndex, Integer pageSize, /** * 企业可通过此接口,将已离职成员为群主的群,分配给另一个客服成员。 * - * + *
    * 注意::
-   * 

+ + * * 群主离职了的客户群,才可继承 * 继承给的新群主,必须是配置了客户联系功能的成员 * 继承给的新群主,必须有设置实名 * 继承给的新群主,必须有激活企业微信 * 同一个人的群,限制每天最多分配300个给新群主 - *

+ + * * 权限说明: - *

+ + * * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。 - * 第三方应用需拥有“企业客户权限->客户联系->分配离职成员的客户群”权限 + * {@code 第三方应用需拥有“企业客户权限->客户联系->分配离职成员的客户群”权限} * 对于第三方/自建应用,群主必须在应用的可见范围。 - * + *

* * @param chatIds 需要转群主的客户群ID列表。取值范围: 1 ~ 100 * @param newOwner 新群主ID @@ -656,7 +664,7 @@ WxCpUserExternalGroupChatList listGroupChat(Integer pageIndex, Integer pageSize, /** * 企业可通过此接口,将在职成员为群主的群,分配给另一个客服成员。 - * + *
    * 注意:
    * 继承给的新群主,必须是配置了客户联系功能的成员
    * 继承给的新群主,必须有设置实名
@@ -716,11 +724,14 @@ WxCpUserExternalGroupChatStatistic getGroupChatStatistic(Date startTime, Integer
    * 企业可通过此接口添加企业群发消息的任务并通知客服人员发送给相关客户或客户群。(注:企业微信终端需升级到2.7.5版本及以上)
    * 注意:调用该接口并不会直接发送消息给客户/客户群,需要相关的客服人员操作以后才会实际发送(客服人员的企业微信需要升级到2.7.5及以上版本)
    * 同一个企业每个自然月内仅可针对一个客户/客户群发送4条消息,超过限制的用户将会被忽略。
-   * 

+ + * * 请求方式: POST(HTTP) - *

+ + * * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=ACCESS_TOKEN - *

+ + * * 文档地址 * * @param wxCpMsgTemplate the wx cp msg template @@ -733,15 +744,18 @@ WxCpUserExternalGroupChatStatistic getGroupChatStatistic(Date startTime, Integer /** * 提醒成员群发 * 企业和第三方应用可调用此接口,重新触发群发通知,提醒成员完成群发任务,24小时内每个群发最多触发三次提醒。 - *

+ + * * 请求方式: POST(HTTPS) - *

+ + * * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remind_groupmsg_send?access_token=ACCESS_TOKEN - *

+ * * 文档地址 * * @param msgId 群发消息的id,通过获取群发记录列表接口返回 * @return the wx cp msg template add result + * @throws WxErrorException 微信错误异常 */ WxCpBaseResp remindGroupMsgSend(String msgId) throws WxErrorException; @@ -753,11 +767,12 @@ WxCpUserExternalGroupChatStatistic getGroupChatStatistic(Date startTime, Integer * 请求方式: POST(HTTPS) *

* 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/cancel_groupmsg_send?access_token=ACCESS_TOKEN - *

+ * * 文档地址 * * @param msgId 群发消息的id,通过获取群发记录列表接口返回 * @return the wx cp msg template add result + * @throws WxErrorException 微信错误异常 */ WxCpBaseResp cancelGroupMsgSend(String msgId) throws WxErrorException; @@ -1002,7 +1017,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *

    * 企业和第三方应用可通过此接口获取企业与成员的群发记录。
-   * 获取企业群发成员执行结果
+   * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/93338
    * 
* * @param msgid 群发消息的id,通过获取群发记录列表接口返回 @@ -1031,7 +1046,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
    * 获取群发成员发送任务列表。
-   * 获取群发成员发送任务列表
+   * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/93338
    * 
* * @param msgid 群发消息的id,通过获取群发记录列表接口返回 @@ -1045,7 +1060,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
    * 添加入群欢迎语素材。
-   * 添加入群欢迎语素材
+   * 文档地址:https://open.work.weixin.qq.com/api/doc/90000/90135/92366
    * 
* * @param template 素材内容 @@ -1057,7 +1072,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
    * 编辑入群欢迎语素材。
-   * 编辑入群欢迎语素材
+   * 文档地址:https://open.work.weixin.qq.com/api/doc/90000/90135/92366
    * 
* * @param template the template @@ -1069,7 +1084,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
    * 获取入群欢迎语素材。
-   * 获取入群欢迎语素材
+   * 文档地址:https://open.work.weixin.qq.com/api/doc/90000/90135/92366
    * 
* * @param templateId 群欢迎语的素材id @@ -1082,7 +1097,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e *
    * 删除入群欢迎语素材。
    * 企业可通过此API删除入群欢迎语素材,且仅能删除调用方自己创建的入群欢迎语素材。
-   * 删除入群欢迎语素材
+   * 文档地址:https://open.work.weixin.qq.com/api/doc/90000/90135/92366
    * 
* * @param templateId 群欢迎语的素材id @@ -1094,8 +1109,8 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
-   * 获取商品图册
-   * 获取商品图册列表
+   * 获取商品图册列表
+   * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/95096
    * 
* * @param limit 返回的最大记录数,整型,最大值100,默认值50,超过最大值时取默认值 @@ -1108,7 +1123,7 @@ WxCpGroupMsgListResult getGroupMsgListV2(String chatType, Date startTime, Date e /** *
    * 获取商品图册
-   * 获取商品图册
+   * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/95096
    * 
* * @param productId 商品id @@ -1155,7 +1170,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 企业和第三方应用可以通过此接口新建敏感词规则 * 请求方式:POST(HTTPS) * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_intercept_rule?access_token=ACCESS_TOKEN - *
+   * 
* @param ruleAddRequest the rule add request * @return 规则id * @throws WxErrorException the wx error exception @@ -1169,7 +1184,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 企业和第三方应用可以通过此接口修改敏感词规则 * 请求方式:POST(HTTPS) * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_intercept_rule?access_token=ACCESS_TOKEN - *
+   * 
* @param interceptRule the rule * @throws WxErrorException the wx error exception */ @@ -1181,7 +1196,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 企业和第三方应用可以通过此接口修改敏感词规则 * 请求方式:POST(HTTPS) * 请求地址 - *
+   * 
* @param ruleId 规则id * @throws WxErrorException the wx error exception */ @@ -1220,7 +1235,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 请求地址: * https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_product_album?access_token=ACCESS_TOKEN * 文档地址 - *
+   * 
* @param wxCpProductAlbumInfo 商品图册信息 * @return 商品id string * @throws WxErrorException the wx error exception @@ -1235,7 +1250,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 请求地址: * https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_product_album?access_token=ACCESS_TOKEN * 文档地址 - *
+   * 
* @param wxCpProductAlbumInfo 商品图册信息 * @throws WxErrorException the wx error exception */ @@ -1250,7 +1265,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * https://qyapi.weixin.qq.com/cgi-bin/externalcontact/delete_product_album?access_token=ACCESS_TOKEN * * 文档地址 - *
+   * 
* @param productId 商品id * @throws WxErrorException the wx error exception */ @@ -1379,7 +1394,7 @@ WxMediaUploadResult uploadAttachment(String mediaType, Integer attachmentType, F * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/statistic?access_token=ACCESS_TOKEN * * @author Hugo - * @date 2023/12/5 14:34 + * @since 2023/12/5 14:34 * @param linkId 获客链接的id * @param startTime 统计起始时间 * @param endTime 统计结束时间 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpGroupRobotService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpGroupRobotService.java index c1a8d5625..b8ccea5e5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpGroupRobotService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpGroupRobotService.java @@ -126,9 +126,10 @@ public interface WxCpGroupRobotService { /** * 发送模板卡片消息 - * @param webhookUrl - * @param wxCpGroupRobotMessage - * @throws WxErrorException + * + * @param webhookUrl webhook地址 + * @param wxCpGroupRobotMessage 群机器人消息 + * @throws WxErrorException 异常 */ void sendTemplateCardMessage(String webhookUrl, WxCpGroupRobotMessage wxCpGroupRobotMessage) throws WxErrorException; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java index 5a53829dc..046cfbc5b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java @@ -222,7 +222,7 @@ WxCpKfCustomerBatchGetResp customerBatchGet(List externalUserIdList) * https://qyapi.weixin.qq.com/cgi-bin/kf/get_corp_statistic?access_token=ACCESS_TOKEN * 文档地址: * https://developer.work.weixin.qq.com/document/path/95489 - *
+   * 
* @param request 查询参数 * @return 客户数据统计 -企业汇总数据 * @throws WxErrorException the wx error exception @@ -238,7 +238,7 @@ WxCpKfCustomerBatchGetResp customerBatchGet(List externalUserIdList) * https://qyapi.weixin.qq.com/cgi-bin/kf/get_servicer_statistic?access_token=ACCESS_TOKEN * 文档地址: * https://developer.work.weixin.qq.com/document/path/95490 - *
+   * 
* @param request 查询参数 * @return 客户数据统计 -企业汇总数据 * @throws WxErrorException the wx error exception diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpLivingService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpLivingService.java index a2e234419..63fabad7a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpLivingService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpLivingService.java @@ -27,7 +27,7 @@ public interface WxCpLivingService { /** * 获取直播详情 * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/living/get_living_info?access_token=ACCESS_TOKEN&livingid=LIVINGID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/living/get_living_info?access_token=ACCESS_TOKEN&livingid=LIVINGID} * * @param livingId 直播id * @return 获取的直播详情 living info diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java index e874b26f4..dd5ce594b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java @@ -110,9 +110,9 @@ WxMediaUploadResult upload(String mediaType, String filename, String url) * 获取高清语音素材. * 可以使用本接口获取从JSSDK的uploadVoice接口上传的临时语音素材,格式为speex,16K采样率。该音频比上文的临时素材获取接口(格式为amr,8K采样率)更加清晰,适合用作语音识别等对音质要求较高的业务。 * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=ACCESS_TOKEN&media_id=MEDIA_ID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=ACCESS_TOKEN&media_id=MEDIA_ID} * 仅企业微信2.4及以上版本支持。 - * 文档地址:https://work.weixin.qq.com/api/doc#90000/90135/90255 + * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/90255 *
* * @param mediaId 媒体id diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java index e49a36ba5..534cc89b3 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java @@ -72,8 +72,9 @@ public interface WxCpMessageService { * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/recall?access_token=ACCESS_TOKEN * 文档地址: https://developer.work.weixin.qq.com/document/path/94867 * + * * @param msgId 消息id - * @throws WxErrorException + * @throws WxErrorException 异常 */ void recall(String msgId) throws WxErrorException; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java index b7a44047a..182419672 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java @@ -90,9 +90,10 @@ public interface WxCpOAuth2Service { /** * 获取家校访问用户身份 * 该接口用于根据code获取家长或者学生信息 - *

+ *

    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/getuserinfo?access_token=ACCESS_TOKEN&code=CODE}
+   * 
* * @param code the code * @return school user info @@ -123,7 +124,7 @@ public interface WxCpOAuth2Service { /** *
    * 获取用户登录身份
-   * https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
+   * {@code https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE}
    * 该接口可使用用户登录成功颁发的code来获取成员信息,适用于自建应用与代开发应用
    *
    * 注意: 旧的/user/getuserinfo 接口的url已变更为auth/getuserinfo,不过旧接口依旧可以使用,建议是关注新接口即可
@@ -140,13 +141,15 @@ public interface WxCpOAuth2Service {
 
   /**
    * 获取用户二次验证信息
-   * 

+ *

    * api: https://qyapi.weixin.qq.com/cgi-bin/auth/get_tfa_info?access_token=ACCESS_TOKEN
    * 权限说明:仅『通讯录同步』或者自建应用可调用,如用自建应用调用,用户需要在二次验证范围和应用可见范围内。
    * 并发限制:20
+   * 
* * @param code 用户进入二次验证页面时,企业微信颁发的code,每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期 - * @return me.chanjar.weixin.cp.bean.workbench.WxCpSecondVerificationInfo 二次验证授权码,开发者可以调用通过二次验证接口,解锁企业微信终端.tfa_code有效期五分钟,且只能使用一次。 + * @return 二次验证授权码,开发者可以调用通过二次验证接口,解锁企业微信终端.tfa_code有效期五分钟,且只能使用一次。 + * @throws WxErrorException 微信错误异常 */ WxCpSecondVerificationInfo getTfaInfo(String code) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaMeetingRoomService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaMeetingRoomService.java index c2e6c5c87..cc039fd9f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaMeetingRoomService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaMeetingRoomService.java @@ -84,6 +84,7 @@ public interface WxCpOaMeetingRoomService { *
* * @param wxCpOaMeetingRoomBookingInfoRequest 会议室预定信息查询对象 + * @return 会议室预定信息 * @throws WxErrorException . */ WxCpOaMeetingRoomBookingInfoResult getMeetingRoomBookingInfo(WxCpOaMeetingRoomBookingInfoRequest wxCpOaMeetingRoomBookingInfoRequest) throws WxErrorException; @@ -99,6 +100,7 @@ public interface WxCpOaMeetingRoomService { * * * @param wxCpOaMeetingRoomBookRequest 会议室预定对象 + * @return 预定结果 * @throws WxErrorException . */ WxCpOaMeetingRoomBookResult bookingMeetingRoom(WxCpOaMeetingRoomBookRequest wxCpOaMeetingRoomBookRequest) throws WxErrorException; @@ -114,6 +116,7 @@ public interface WxCpOaMeetingRoomService { * * * @param wxCpOaMeetingRoomBookByScheduleRequest 会议室预定对象 + * @return 预定结果 * @throws WxErrorException . */ WxCpOaMeetingRoomBookResult bookingMeetingRoomBySchedule(WxCpOaMeetingRoomBookByScheduleRequest wxCpOaMeetingRoomBookByScheduleRequest) throws WxErrorException; @@ -129,6 +132,7 @@ public interface WxCpOaMeetingRoomService { * * * @param wxCpOaMeetingRoomBookByMeetingRequest 会议室预定对象 + * @return 预定结果 * @throws WxErrorException . */ WxCpOaMeetingRoomBookResult bookingMeetingRoomByMeeting(WxCpOaMeetingRoomBookByMeetingRequest wxCpOaMeetingRoomBookByMeetingRequest) throws WxErrorException; @@ -147,10 +151,10 @@ public interface WxCpOaMeetingRoomService { * @param wxCpOaMeetingRoomCancelBookRequest 取消预定会议室对象 * @throws WxErrorException . */ - void cancelBookMeetingRoom(WxCpOaMeetingRoomCancelBookRequest wxCpOaMeetingRoomCancelBookRequest) throws WxErrorException; + void cancelBookMeetingRoom(WxCpOaMeetingRoomCancelBookRequest wxCpOaMeetingRoomCancelBookRequest) throws WxErrorException; - /** + /** * 根据会议室预定ID查询预定详情. *
    * 企业可通过此接口根据预定id查询相关会议室的预定情况
@@ -161,8 +165,9 @@ public interface WxCpOaMeetingRoomService {
    * 
* * @param wxCpOaMeetingRoomBookingInfoByBookingIdRequest 根据会议室预定ID查询预定详情对象 + * @return 预定详情 * @throws WxErrorException . */ - WxCpOaMeetingRoomBookingInfoByBookingIdResult getBookingInfoByBookingId(WxCpOaMeetingRoomBookingInfoByBookingIdRequest wxCpOaMeetingRoomBookingInfoByBookingIdRequest) throws WxErrorException; + WxCpOaMeetingRoomBookingInfoByBookingIdResult getBookingInfoByBookingId(WxCpOaMeetingRoomBookingInfoByBookingIdRequest wxCpOaMeetingRoomBookingInfoByBookingIdRequest) throws WxErrorException; } 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 ee57107b5..3494dcfa4 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 @@ -11,7 +11,8 @@ /** * 企业微信OA相关接口. * - * @author Element & Wang_Wong created on 2019-04-06 10:52 + * @author Element, Wang_Wong + * @since 2019-04-06 10:52 */ public interface WxCpOaService { @@ -331,7 +332,7 @@ List getDialRecord(Date startTime, Date endTime, Integer offset, * https://qyapi.weixin.qq.com/cgi-bin/checkin/addcheckinuserface?access_token=ACCESS_TOKEN * 文档地址: * https://developer.work.weixin.qq.com/document/path/93378 - *
+   * 
* @param userId 需要录入的用户id * @param userFace 需要录入的人脸图片数据,需要将图片数据base64处理后填入,对已录入的人脸会进行更新处理 * @throws WxErrorException the wx error exception diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolService.java index 56687c9cb..5f1d41c19 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolService.java @@ -80,9 +80,10 @@ public interface WxCpSchoolService { /** * 获取直播详情 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/living/get_living_info?access_token=ACCESS_TOKEN&livingid
-   * =LIVINGID
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/living/get_living_info?access_token=ACCESS_TOKEN&livingid=LIVINGID}
+   * 
* * @param livingId the living id * @return living info diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java index a92bfcc10..d004ca8aa 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java @@ -19,9 +19,10 @@ public interface WxCpSchoolUserService { /** * 获取访问用户身份 * 该接口用于根据code获取成员信息 - *

+ *

    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE}
+   * 
* * @param code the code * @return user info @@ -32,9 +33,10 @@ public interface WxCpSchoolUserService { /** * 获取家校访问用户身份 * 该接口用于根据code获取家长或者学生信息 - *

+ *

    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/getuserinfo?access_token=ACCESS_TOKEN&code=CODE}
+   * 
* * @param code the code * @return school user info @@ -90,8 +92,10 @@ public interface WxCpSchoolUserService { /** * 删除学生 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_student?access_token=ACCESS_TOKEN&userid=USERID
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_student?access_token=ACCESS_TOKEN&userid=USERID}
+   * 
* * @param studentUserId the student user id * @return wx cp base resp @@ -160,8 +164,10 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 读取学生或家长 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/get?access_token=ACCESS_TOKEN&userid=USERID
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/get?access_token=ACCESS_TOKEN&userid=USERID}
+   * 
* * @param userId the user id * @return user @@ -171,9 +177,10 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 获取部门成员详情 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID
-   * &fetch_child=FETCH_CHILD
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD}
+   * 
* * @param departmentId 获取的部门id * @param fetchChild 1/0:是否递归获取子部门下面的成员 @@ -184,9 +191,10 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 获取部门家长详情 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/list_parent?access_token=ACCESS_TOKEN&department_id
-   * =DEPARTMENT_ID
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/list_parent?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID}
+   * 
* * @param departmentId 获取的部门id * @return user list parent @@ -207,8 +215,10 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 删除家长 + *
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_parent?access_token=ACCESS_TOKEN&userid=USERID
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_parent?access_token=ACCESS_TOKEN&userid=USERID}
+   * 
* * @param userId the user id * @return wx cp base resp @@ -256,7 +266,7 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 删除部门 * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/department/delete?access_token=ACCESS_TOKEN&id=ID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/department/delete?access_token=ACCESS_TOKEN&id=ID} * * @param id the id * @return wx cp base resp @@ -292,10 +302,9 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 获取外部联系人详情 * 学校可通过此接口,根据外部联系人的userid(如何获取?),拉取外部联系人详情。 - *

+ * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid - * =EXTERNAL_USERID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid=EXTERNAL_USERID} * * @param externalUserId 外部联系人的userid,注意不是学校成员的帐号 * @return external contact @@ -306,9 +315,9 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 获取可使用的家长范围 * 获取可在微信「学校通知-学校应用」使用该应用的家长范围,以学生或部门列表的形式返回。应用只能给该列表下的家长发送「学校通知」。注意该范围只能由学校的系统管理员在「管理端-家校沟通-配置」配置。 - *

+ * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/agent/get_allow_scope?access_token=ACCESS_TOKEN&agentid=AGENTID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/agent/get_allow_scope?access_token=ACCESS_TOKEN&agentid=AGENTID} * * @param agentId the agent id * @return allow scope @@ -332,7 +341,7 @@ WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserI /** * 获取部门列表 * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/department/list?access_token=ACCESS_TOKEN&id=ID + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/department/list?access_token=ACCESS_TOKEN&id=ID} * * @param id 部门id。获取指定部门及其下的子部门。 如果不填,默认获取全量组织架构 * @return wx cp department list diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 0b601ca50..76012a281 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -584,7 +584,7 @@ public interface WxCpService extends WxService { /** * 企业互联的服务类对象 * - * @return + * @return 企业互联服务对象 */ WxCpCorpGroupService getCorpGroupService(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java index 2368386b2..7a7b5f40a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java @@ -38,7 +38,7 @@ public interface WxCpUserService { *

    * 获取部门成员详情
    * 请求方式:GET(HTTPS)
-   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD
+   * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD}
    *
    * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/90201
    * 
@@ -213,7 +213,7 @@ public interface WxCpUserService { * 获取加入企业二维码。 * * 请求方式:GET(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/corp/get_join_qrcode?access_token=ACCESS_TOKEN&size_type=SIZE_TYPE + * {@code 请求地址:https://qyapi.weixin.qq.com/cgi-bin/corp/get_join_qrcode?access_token=ACCESS_TOKEN&size_type=SIZE_TYPE} * * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/91714 * diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java index 48bd952a8..e3dc1cbe1 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java @@ -18,7 +18,7 @@ * 企业互联相关接口实现类 * * @author libo <422423229@qq.com> - * Created on 27/2/2023 9:57 PM + * @since 2023-02-27 9:57 PM */ @RequiredArgsConstructor public class WxCpCorpGroupServiceImpl implements WxCpCorpGroupService { 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 8e3a8d7b9..d43589595 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 @@ -38,7 +38,7 @@ /** * The type Wx cp external contact service. * - * @author 曹祖鹏 & yuanqixun & Mr.Pan & Wang_Wong + * @author 曹祖鹏, yuanqixun, Mr.Pan, Wang_Wong */ @RequiredArgsConstructor public class WxCpExternalContactServiceImpl implements WxCpExternalContactService { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpBaseResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpBaseResp.java index 6bf9a30ae..a895c38a8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpBaseResp.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpBaseResp.java @@ -10,7 +10,8 @@ /** * 返回结果 * - * @author yqx & WangWong created on 2020/3/16 + * @author yqx, WangWong + * @since 2020/3/16 */ @Getter @Setter diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpAuthInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpAuthInfo.java index fa5021615..9919fd72b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpAuthInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpAuthInfo.java @@ -216,7 +216,7 @@ public static class Agent implements Serializable { /** * 付费状态 - *
+ *
*
    *
  • 0-没有付费;
  • *
  • 1-限时试用;
  • diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpPermanentCodeInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpPermanentCodeInfo.java index 522e606a2..5330194ab 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpPermanentCodeInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpPermanentCodeInfo.java @@ -225,7 +225,7 @@ public static class Agent implements Serializable { /** * 付费状态 - *
    + *
    *
      *
    • 0-没有付费;
    • *
    • 1-限时试用;
    • diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTag.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTag.java index 74e1fec3f..a73ec171b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTag.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTag.java @@ -10,7 +10,7 @@ * The type Wx cp tp tag. * * @author zhangq - * @since 2021 -02-14 16:15 16:15 + * @since 2021-02-14 16:15 */ @Data public class WxCpTpTag implements Serializable { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagAddOrRemoveUsersResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagAddOrRemoveUsersResult.java index dfbf25048..565cbb408 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagAddOrRemoveUsersResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagAddOrRemoveUsersResult.java @@ -6,7 +6,7 @@ * 企业微信第三方开发-增加标签成员成员api响应体 * * @author zhangq - * @since 2021 /2/14 16:44 + * @since 2021/2/14 16:44 */ public class WxCpTpTagAddOrRemoveUsersResult extends WxCpTagAddOrRemoveUsersResult { private static final long serialVersionUID = 3490401800490702052L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagGetResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagGetResult.java index 162030c95..134656e43 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagGetResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTagGetResult.java @@ -6,7 +6,7 @@ * 获取标签成员接口响应体 * * @author zhangq - * @since 2021 /2/14 16:28 + * @since 2021/2/14 16:28 */ public class WxCpTpTagGetResult extends WxCpTagGetResult { private static final long serialVersionUID = 9051748686315562400L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpMsgTemplate.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpMsgTemplate.java index 6c546daa8..42e51afbb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpMsgTemplate.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpMsgTemplate.java @@ -14,10 +14,9 @@ /** * 企业群发消息任务 - *

      - * Created by songfan on 2020/7/14. * - * @author songfan & Mr.Pan + * @author songfan, Mr.Pan + * @since 2020/7/14 */ @Data @Builder diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalUnassignList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalUnassignList.java index 8605760fa..f3fdd96ce 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalUnassignList.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalUnassignList.java @@ -12,7 +12,8 @@ /** * 离职员工外部联系人列表 * - * @author yqx & Wang_Wong created on 2020/3/15 + * @author yqx, Wang_Wong + * @since 2020/3/15 */ @Getter @Setter diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/acquisition/WxCpCustomerAcquisitionStatistic.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/acquisition/WxCpCustomerAcquisitionStatistic.java index bb02b039b..87e3d5580 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/acquisition/WxCpCustomerAcquisitionStatistic.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/acquisition/WxCpCustomerAcquisitionStatistic.java @@ -10,7 +10,7 @@ * 获客链接的使用详情 * * @author Hugo - * @date 2023/12/11 10:31 + * @since 2023/12/11 10:31 */ @Data @EqualsAndHashCode(callSuper = true) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleInfo.java index 20d6b3244..23bb70a24 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleInfo.java @@ -10,9 +10,10 @@ import java.util.List; /** - * @Date: 2024-03-07 17:02 - * @Author: shenliuming - * @return: + * 防骚扰规则详情 + * + * @author shenliuming + * @since 2024-03-07 17:02 */ @Data @EqualsAndHashCode(callSuper = true) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleList.java index 6826413e1..543d32fcb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleList.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/interceptrule/WxCpInterceptRuleList.java @@ -9,9 +9,10 @@ import java.util.List; /** - * @Date: 2024-03-07 15:54 - * @Author: shenliuming - * @return: + * 防骚扰规则列表 + * + * @author shenliuming + * @since 2024-03-07 15:54 */ @Data @EqualsAndHashCode(callSuper = true) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/Attachment.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/Attachment.java index be9dcc9dd..1fff457f9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/Attachment.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/Attachment.java @@ -33,6 +33,7 @@ public class Attachment implements Serializable { * Sets image. * * @param image the image + * @return this */ public Attachment setImage(Image image) { this.image = image; @@ -44,6 +45,7 @@ public Attachment setImage(Image image) { * Sets link. * * @param link the link + * @return this */ public Attachment setLink(Link link) { this.link = link; @@ -55,6 +57,7 @@ public Attachment setLink(Link link) { * Sets mini program. * * @param miniProgram the mini program + * @return this */ public Attachment setMiniProgram(MiniProgram miniProgram) { this.miniProgram = miniProgram; @@ -66,6 +69,7 @@ public Attachment setMiniProgram(MiniProgram miniProgram) { * Sets video. * * @param video the video + * @return this */ public Attachment setVideo(Video video) { this.video = video; @@ -77,6 +81,7 @@ public Attachment setVideo(Video video) { * Sets file. * * @param file the file + * @return this */ public Attachment setFile(File file) { this.file = file; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfAccountLink.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfAccountLink.java index a903d0fa5..38d25e61c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfAccountLink.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfAccountLink.java @@ -27,10 +27,10 @@ public class WxCpKfAccountLink implements Serializable { * 场景值,字符串类型,由开发者自定义。 * 不多于32字节 * 字符串取值范围(正则表达式):[0-9a-zA-Z_-]* - *

      + * * 1. 若scene非空,返回的客服链接开发者可拼接scene_param=SCENE_PARAM参数使用,用户进入会话事件会将SCENE_PARAM原样返回。 * 其中SCENE_PARAM需要urlencode,且长度不能超过128字节。 - * 如 https://work.weixin.qq.com/kf/kfcbf8f8d07ac7215f?enc_scene=ENCGFSDF567DF&scene_param=a%3D1%26b%3D2 + * {@code 如 https://work.weixin.qq.com/kf/kfcbf8f8d07ac7215f?enc_scene=ENCGFSDF567DF&scene_param=a%3D1%26b%3D2} * 2. 历史调用接口返回的客服链接(包含encScene=XXX参数),不支持scene_param参数。 * 3. 返回的客服链接,不能修改或复制参数到其他链接使用。否则进入会话事件参数校验不通过,导致无法回调。 */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlReq.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlReq.java index c5cb21bde..0149a426f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlReq.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlReq.java @@ -5,8 +5,9 @@ /** * 生成异步上传任务 + * * @author imyzt - * @date 2025/04/27 + * @since 2025/04/27 */ @Data public class MediaUploadByUrlReq { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlResult.java index cc931eed3..595f85dff 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/media/MediaUploadByUrlResult.java @@ -10,8 +10,9 @@ /** * 异步上传企微素材 + * * @author imyzt - * @date 2025/4/27 + * @since 2025/4/27 */ @EqualsAndHashCode(callSuper = true) @Data diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java index 92209fd4e..7e777384e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java @@ -85,13 +85,13 @@ public class WxCpLinkedCorpMessage implements Serializable { /** *

          * 请使用.
      -   * {@link LinkedCorpMsgType#TEXT}
      -   * {@link LinkedCorpMsgType#IMAGE}
      -   * {@link LinkedCorpMsgType#VIDEO}
      -   * {@link LinkedCorpMsgType#NEWS}
      -   * {@link LinkedCorpMsgType#MPNEWS}
      -   * {@link LinkedCorpMsgType#MARKDOWN}
      -   * {@link LinkedCorpMsgType#MINIPROGRAM_NOTICE}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#TEXT}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#IMAGE}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#VIDEO}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#NEWS}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#MPNEWS}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#MARKDOWN}
      +   * {@link me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType#MINIPROGRAM_NOTICE}
          * 
      * * @param msgType 消息类型 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java index 4001c7d0e..08a093631 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java @@ -68,19 +68,19 @@ public class WxCpXmlMessage implements Serializable { /** *
          * 当接受用户消息时,可能会获得以下值:
      -   * {@link WxConsts.XmlMsgType#TEXT}
      -   * {@link WxConsts.XmlMsgType#IMAGE}
      -   * {@link WxConsts.XmlMsgType#VOICE}
      -   * {@link WxConsts.XmlMsgType#VIDEO}
      -   * {@link WxConsts.XmlMsgType#LOCATION}
      -   * {@link WxConsts.XmlMsgType#LINK}
      -   * {@link WxConsts.XmlMsgType#EVENT}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#TEXT}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#IMAGE}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VOICE}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VIDEO}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#LOCATION}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#LINK}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#EVENT}
          * 当发送消息的时候使用:
      -   * {@link WxConsts.XmlMsgType#TEXT}
      -   * {@link WxConsts.XmlMsgType#IMAGE}
      -   * {@link WxConsts.XmlMsgType#VOICE}
      -   * {@link WxConsts.XmlMsgType#VIDEO}
      -   * {@link WxConsts.XmlMsgType#NEWS}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#TEXT}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#IMAGE}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VOICE}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VIDEO}
      +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#NEWS}
          * 
      */ @XStreamAlias("MsgType") diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java index d3cbb89a3..1ab92630a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java @@ -12,7 +12,8 @@ * 用法: WxCustomMessage m = WxCustomMessage.TEMPLATECARD().title(...)....toUser(...).build(); * * - * @author yzts created on 2019-05-16 + * @author yzts + * @since 2019-05-16 */ public class TemplateCardBuilder extends BaseBuilder { /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinGroupBase.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinGroupBase.java index 3bc542ccd..81e5dcc32 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinGroupBase.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinGroupBase.java @@ -10,8 +10,8 @@ * 打卡规则基础信息 * * @author zhongjun96 - * @date 2023/7/7 - **/ + * @since 2023/7/7 + */ @Data public class WxCpCheckinGroupBase implements Serializable { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOaSchedule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOaSchedule.java index 20b1f45e2..9836a3291 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOaSchedule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOaSchedule.java @@ -157,7 +157,7 @@ public static class Reminder implements Serializable { /** * 提醒时间与日程开始时间(start_time)的差值,当is_remind为1时有效。例如:-300表示日程开始前5分钟提醒。 * 特殊情况:企业微信终端设置的“全天”类型的日程,由于start_time是0点时间戳,提醒如果设置了当天9点,则会出现正数32400。 - *
      + *
      * 取值范围:-604800 ~ 86399 */ @SerializedName("remind_time_diffs") diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/meetingroom/WxCpOaMeetingRoomBookResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/meetingroom/WxCpOaMeetingRoomBookResult.java index 16cf32fa5..4f74bab79 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/meetingroom/WxCpOaMeetingRoomBookResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/meetingroom/WxCpOaMeetingRoomBookResult.java @@ -39,7 +39,7 @@ public static WxCpOaMeetingRoomBookResult fromJson(String json) { private String schedule_id; /** * 通过会议预定会议室 和 通过日程预定会议室 接口返回 - *
      + *
      * 会议室冲突日期列表,为当天0点的时间戳;使用重复会议预定会议室,部分日期与会议室预定情况冲突时返回 */ @SerializedName("conflict_date") diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTips.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTips.java index 58daeb007..eada2ad10 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTips.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTips.java @@ -8,7 +8,7 @@ /** * @author mrsiu@msn.com * @version 1.0 - * @date 2025/1/16 09:40 + * @since 2025/1/16 09:40 */ @Data public class TemplateTips { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsContent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsContent.java index 939e6819a..0af8be8be 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsContent.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsContent.java @@ -5,7 +5,7 @@ /** * @author mrsiu@msn.com * @version 1.0 - * @date 2025/1/16 09:42 + * @since 2025/1/16 09:42 */ @Data public class TemplateTipsContent { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubText.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubText.java index ac4681038..78e88562e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubText.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubText.java @@ -5,7 +5,7 @@ /** * @author mrsiu@msn.com * @version 1.0 - * @date 2025/1/16 09:45 + * @since 2025/1/16 09:45 */ @Data public class TemplateTipsSubText { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContent.java index 9c99b2688..f33c31d05 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContent.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContent.java @@ -6,7 +6,7 @@ /** * @author mrsiu@msn.com * @version 1.0 - * @date 2025/1/16 09:46 + * @since 2025/1/16 09:46 */ @Data public class TemplateTipsSubTextContent { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentLink.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentLink.java index 4cd198409..fd4db2c18 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentLink.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentLink.java @@ -5,7 +5,7 @@ /** * @author mrsiu@msn.com * @version 1.0 - * @date 2025/1/16 09:49 + * @since 2025/1/16 09:49 */ @Data public class TemplateTipsSubTextContentLink { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentPlainText.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentPlainText.java index 12969cdcd..0a2e792ed 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentPlainText.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsSubTextContentPlainText.java @@ -3,9 +3,9 @@ import lombok.Data; /** - * @author mrsiu@msn.com - * @date 2025/1/16 09:47 - * @version 1.0 + * @author mrsiu@msn.com + * @version 1.0 + * @since 2025/1/16 09:47 */ @Data public class TemplateTipsSubTextContentPlainText { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsText.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsText.java index 100c5bb13..c9dbe68ab 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsText.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTipsText.java @@ -6,9 +6,9 @@ import java.util.List; /** - * @author mrsiu@msn.com - * @date 2025/1/16 09:43 - * @version 1.0 + * @author mrsiu@msn.com + * @version 1.0 + * @since 2025/1/16 09:43 */ @Data public class TemplateTipsText { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java index 07acb189a..df758ac3a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java @@ -31,8 +31,8 @@ public interface WxCpCorpGroupConfigStorage { /** * Update corp access token. * - * @param corpId - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID * @param corpAccessToken the corp access token * @param expiresInSeconds the expires in seconds */ @@ -41,8 +41,8 @@ public interface WxCpCorpGroupConfigStorage { /** * 授权企业的access token相关 * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID * @return the access token */ String getCorpAccessToken(String corpId, Integer agentId); @@ -50,8 +50,8 @@ public interface WxCpCorpGroupConfigStorage { /** * Gets access token entity. * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID * @return the access token entity */ WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId); @@ -59,8 +59,8 @@ public interface WxCpCorpGroupConfigStorage { /** * Is access token expired boolean. * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID * @return the boolean */ boolean isCorpAccessTokenExpired(String corpId, Integer agentId); @@ -68,8 +68,8 @@ public interface WxCpCorpGroupConfigStorage { /** * Expire access token. * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID */ void expireCorpAccessToken(String corpId, Integer agentId); @@ -118,7 +118,8 @@ public interface WxCpCorpGroupConfigStorage { /** * Gets access token lock. * - * @param corpId the corp id + * @param corpId 企业ID + * @param agentId 应用ID * @return the access token lock */ Lock getCorpAccessTokenLock(String corpId, Integer agentId); 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 2cd37821b..0a2ed0e76 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 @@ -133,7 +133,7 @@ public interface WxCpTpConfigStorage { String getEncodingAESKey(); /** - * 企微服务商企业ID & 企业secret + * {@code 企微服务商企业ID & 企业secret} * * @return the corp id */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpTpInRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpTpInRedisConfigImpl.java index 08eed33c1..6d1260fe6 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpTpInRedisConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpTpInRedisConfigImpl.java @@ -187,7 +187,9 @@ public String getEncodingAESKey() { /** - * 企微服务商企业ID & 企业secret, 来自于企微配置 + * {@code 企微服务商企业ID & 企业secret, 来自于企微配置} + * + * @return 企业ID */ @Override public String getCorpId() { 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 fc124251f..7fbbc9ccc 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 @@ -29,7 +29,7 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl private final transient Map authCorpJsapiTicketLocker = new ConcurrentHashMap<>(); private final transient Map authSuiteJsapiTicketLocker = new ConcurrentHashMap<>(); /** - * 企微服务商企业ID & 企业secret,来自于企微配置 + * {@code 企微服务商企业ID & 企业secret,来自于企微配置} */ protected volatile String corpId; /** @@ -198,7 +198,7 @@ public String getSuiteId() { /** * Sets suite id. * - * @param suiteId + * @param suiteId 套件ID */ public void setSuiteId(String suiteId) { this.suiteId = suiteId; @@ -211,6 +211,8 @@ public String getSuiteSecret() { /** * Sets suite secret. + * + * @param corpSecret 套件密钥 */ public void setSuiteSecret(String corpSecret) { this.suiteSecret = corpSecret; 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 ff3f8e0e6..df8524901 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 @@ -124,7 +124,7 @@ public static class EventType { public static final String REOPEN_INACTIVE_AGENT = "reopen_inactive_agent"; /** - * 企业成员添加外部联系人事件推送 & 会话存档客户同意进行聊天内容存档事件回调事件 + * {@code 企业成员添加外部联系人事件推送 & 会话存档客户同意进行聊天内容存档事件回调事件} */ public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java index b9b2c5d77..f94c14a4f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java @@ -33,28 +33,31 @@ public interface WxCpCgService { /** * 授权企业的access token相关 * - * @param corpId the corp id - * @param agentId - * @param businessType + * @param corpId 企业ID + * @param agentId 应用ID + * @param businessType 业务类型 * @return the access token + * @throws WxErrorException 微信错误异常 */ WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType) throws WxErrorException; /** * Gets access token entity. * - * @param corpId the corp id - * @param agentId - * @param businessType + * @param corpId 企业ID + * @param agentId 应用ID + * @param businessType 业务类型 + * @param forceRefresh 是否强制刷新 * @return the access token entity + * @throws WxErrorException 微信错误异常 */ WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType, boolean forceRefresh) throws WxErrorException; /** * Is access token expired boolean. * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID * @return the boolean */ boolean isCorpAccessTokenExpired(String corpId, Integer agentId); @@ -62,8 +65,8 @@ public interface WxCpCgService { /** * Expire access token. * - * @param corpId the corp id - * @param agentId + * @param corpId 企业ID + * @param agentId 应用ID */ void expireCorpAccessToken(String corpId, Integer agentId); @@ -72,6 +75,7 @@ public interface WxCpCgService { * * @param url 接口地址 * @param queryParam 请求参数 + * @param req 获取token请求参数 * @return the string * @throws WxErrorException the wx error exception */ @@ -83,6 +87,7 @@ public interface WxCpCgService { * @param url 接口地址 * @param queryParam 请求参数 * @param withoutCorpAccessToken 请求是否忽略CorpAccessToken 默认不忽略-false + * @param req 获取token请求参数 * @return the string * @throws WxErrorException the wx error exception */ @@ -93,6 +98,7 @@ public interface WxCpCgService { * * @param url 接口地址 * @param postData 请求body字符串 + * @param req 获取token请求参数 * @return the string * @throws WxErrorException the wx error exception */ @@ -110,6 +116,7 @@ public interface WxCpCgService { * @param executor 执行器 * @param uri 请求地址 * @param data 参数 + * @param req 获取token请求参数 * @return the t * @throws WxErrorException the wx error exception */ @@ -156,7 +163,7 @@ public interface WxCpCgService { /** * 互联企业的服务类对象 * - * @return + * @return 互联企业服务对象 */ WxCpLinkedCorpService getLinkedCorpService(); @@ -164,10 +171,11 @@ public interface WxCpCgService { * 获取下级/下游企业小程序session * https://developer.work.weixin.qq.com/document/path/93355 * - * @param userId - * @param sessionKey - * @return - * @throws WxErrorException + * @param userId 用户ID + * @param sessionKey 会话密钥 + * @param req 请求参数 + * @return 小程序session结果 + * @throws WxErrorException 微信错误异常 */ WxCpMaTransferSession getCorpTransferSession(String userId, String sessionKey, WxCpCorpGroupCorpGetTokenReq req) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java index 999107373..e4fe2a686 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java @@ -112,6 +112,7 @@ public String post(String url, String postData, WxCpCorpGroupCorpGetTokenReq req * @param url the url * @param postData the post data * @param withoutCorpAccessToken the without Corp access token + * @param req 获取token请求参数 * @return the string * @throws WxErrorException the wx error exception */ @@ -136,6 +137,7 @@ public T execute(RequestExecutor executor, String uri, E data, WxCp * @param uri the uri * @param data the data * @param withoutCorpAccessToken the without Corp access token + * @param req 获取token请求参数 * @return the t * @throws WxErrorException the wx error exception */ @@ -181,6 +183,7 @@ public T execute(RequestExecutor executor, String uri, E data, bool * @param executor the executor * @param uri the uri * @param data the data + * @param req 获取token请求参数 * @return the t * @throws WxErrorException the wx error exception */ @@ -197,6 +200,7 @@ protected T executeInternal(RequestExecutor executor, String uri, E * @param uri the uri * @param data the data * @param withoutCorpAccessToken the without Corp access token + * @param req 获取token请求参数 * @return the t * @throws WxErrorException the wx error exception */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpEditionService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpEditionService.java index 2c2f11628..d539f03bc 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpEditionService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpEditionService.java @@ -15,7 +15,7 @@ public interface WxCpTpEditionService { * 延长试用期 *

      * 文档地址 - *

      + *

      * 注意: *
        *
      • 一个应用可以多次延长试用,但是试用总天数不能超过60天
      • diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpIdConvertService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpIdConvertService.java index 10268bcb3..83dd6fe36 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpIdConvertService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpIdConvertService.java @@ -20,9 +20,11 @@ public interface WxCpTpIdConvertService { * unionid与external_userid的关联 * 查看文档 * + * @param cropId 企业ID * @param unionid 微信客户的unionid * @param openid 微信客户的openid * @param subjectType 程序或公众号的主体类型: 0表示主体名称是企业的,1表示主体名称是服务商的 + * @return 转换结果 * @throws WxErrorException 。 */ WxCpTpUnionidToExternalUseridResult unionidToExternalUserid(String cropId, String unionid, String openid, @@ -31,29 +33,33 @@ WxCpTpUnionidToExternalUseridResult unionidToExternalUserid(String cropId, Strin /** * 将企业主体下的客户标签ID转换成服务商主体下的客户标签ID - * @param corpId 企业微信 ID - * @param externalTagIdList 企业主体下的客户标签ID列表,最多不超过1000个 - * @return 客户标签转换结果 + * + * @param corpId 企业微信 ID + * @param externalTagIdList 企业主体下的客户标签ID列表,最多不超过1000个 + * @return 客户标签转换结果 * @throws WxErrorException . */ WxCpTpTagIdListConvertResult externalTagId(String corpId, String... externalTagIdList) throws WxErrorException; /** * 将企业主体下的微信客服ID转换成服务商主体下的微信客服ID - * @param corpId 企业微信 ID - * @param openKfIdList 微信客服ID列表,最多不超过1000个 - * @return 微信客服ID转换结果 - * @throws WxErrorException . + * + * @param corpId 企业微信 ID + * @param openKfIdList 微信客服ID列表,最多不超过1000个 + * @return 微信客服ID转换结果 + * @throws WxErrorException . */ - WxCpTpOpenKfIdConvertResult ConvertOpenKfId (String corpId, String... openKfIdList ) throws WxErrorException; + WxCpTpOpenKfIdConvertResult ConvertOpenKfId(String corpId, String... openKfIdList) throws WxErrorException; /** * 将应用获取的外部用户临时idtmp_external_userid,转换为external_userid - * @param corpId 企业微信Id - * @param businessType 业务类型。1-会议 2-收集表 - * @param userType 转换的目标用户类型。1-客户 2-企业互联 3-上下游 4-互联企业(圈子) - * @param tmpExternalUserIdList 外部用户临时id,最多不超过100个 - * @return 转换成功的结果列表 + * + * @param corpId 企业微信Id + * @param businessType 业务类型。1-会议 2-收集表 + * @param userType 转换的目标用户类型。1-客户 2-企业互联 3-上下游 4-互联企业(圈子) + * @param tmpExternalUserIdList 外部用户临时id,最多不超过100个 + * @return 转换成功的结果列表 + * @throws WxErrorException . */ WxCpTpConvertTmpExternalUserIdResult convertTmpExternalUserId(String corpId, int businessType, int userType, String... tmpExternalUserIdList) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOAService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOAService.java index 85321213a..4aed96b7b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOAService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOAService.java @@ -51,8 +51,7 @@ public interface WxCpTpOAService { String copyTemplate(@NonNull String openTemplateId, String corpId) throws WxErrorException; /** - *
        -   *   获取审批申请详情
        +   * 获取审批申请详情
            *
            * @param spNo 审批单编号。
            * @param corpId the corp id
        diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOrderService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOrderService.java
        index 3aff90bb5..6e0acb7de 100644
        --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOrderService.java
        +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpOrderService.java
        @@ -18,7 +18,7 @@ public interface WxCpTpOrderService {
            * 获取订单详情
            * 

        * 文档地址 - *

        + *

        * * @param orderId 订单号 * @return the order @@ -31,7 +31,7 @@ public interface WxCpTpOrderService { * 获取订单列表 *

        * 文档地址 - *

        + *

        * * @param startTime 起始时间 * @param endTime 终止时间 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java index b24be535d..93855d1a4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java @@ -199,7 +199,7 @@ public interface WxCpTpService { * @return permanent code info * @throws WxErrorException the wx error exception * @author yuan - * @since 2020 -03-18 + * @since 2020-03-18 */ WxCpTpPermanentCodeInfo getPermanentCodeInfo(String authCode) throws WxErrorException; @@ -227,7 +227,7 @@ public interface WxCpTpService { * @param authType 授权类型:0 正式授权, 1 测试授权。 * @return pre auth url * @throws WxErrorException the wx error exception - * @link https ://work.weixin.qq.com/api/doc/90001/90143/90602 + * @see 文档地址 */ String getPreAuthUrl(String redirectUri, String state, int authType) throws WxErrorException; @@ -558,12 +558,12 @@ WxCpTpXmlMessage fromEncryptedXml(String encryptedXml, WxCpTpAppQrcode getAppQrcode(String suiteId, String appId, String state, Integer style, Integer resultType) throws WxErrorException ; /** - * * 明文corpid转换为加密corpid 为更好地保护企业与用户的数据,第三方应用获取的corpid不再是明文的corpid,将升级为第三方服务商级别的加密corpid。文档说明 * 第三方可以将已有的明文corpid转换为第三方的加密corpid。 - * @param corpId - * @return - * @throws WxErrorException + * + * @param corpId 企业ID + * @return 加密的企业ID + * @throws WxErrorException 微信错误异常 */ WxCpTpCorpId2OpenCorpId corpId2OpenCorpId(String corpId) throws WxErrorException; @@ -655,6 +655,8 @@ WxCpTpXmlMessage fromEncryptedXml(String encryptedXml, /** * 构造第三方应用oauth2链接 + * + * @return OAuth2服务 */ WxCpTpOAuth2Service getWxCpTpOAuth2Service(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpTagService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpTagService.java index b508df59a..df6004186 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpTagService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpTagService.java @@ -13,7 +13,7 @@ *
        * * @author zhangq - * @since 2021 -02-14 16:02 + * @since 2021-02-14 16:02 */ public interface WxCpTpTagService { /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpEditionServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpEditionServiceImpl.java index 34ca852c3..b77fb924c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpEditionServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpEditionServiceImpl.java @@ -26,7 +26,7 @@ public class WxCpTpEditionServiceImpl implements WxCpTpEditionService { * 延长试用期 *

        * 文档地址 - *

        + *

        *
          *
        • 一个应用可以多次延长试用,但是试用总天数不能超过60天
        • *
        • 仅限时试用或试用过期状态下的应用可以延长试用期
        • diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpOrderServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpOrderServiceImpl.java index b8aff54d3..7b2d45b5c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpOrderServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpOrderServiceImpl.java @@ -30,7 +30,7 @@ public class WxCpTpOrderServiceImpl implements WxCpTpOrderService { * 获取订单详情 *

          * 文档地址 - *

          + *

          * * @param orderId 订单号 * @return the order @@ -49,7 +49,7 @@ public WxCpTpOrderDetails getOrder(String orderId) throws WxErrorException { * 获取订单列表 *

          * 文档地址 - *

          + *

          * * @param startTime 起始时间 * @param endTime 终止时间 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpTagServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpTagServiceImpl.java index b81760e72..1b03f18c7 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpTagServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpTagServiceImpl.java @@ -25,7 +25,7 @@ * * * @author zhangq - * @since 2021 -02-14 16:02 + * @since 2021-02-14 16:02 */ @RequiredArgsConstructor public class WxCpTpTagServiceImpl implements WxCpTpTagService { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java index 098a781c6..09c6ce828 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java @@ -20,7 +20,7 @@ public class XStreamTransformer { protected static final Map, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); /** - * xml -> pojo + * {@code xml -> pojo} * * @param the type parameter * @param clazz the clazz @@ -58,7 +58,7 @@ public static void register(Class clz, XStream xStream) { } /** - * pojo -> xml. + * {@code pojo -> xml.} * * @param the type parameter * @param clazz the clazz diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java index 8164d4834..e39836c06 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java @@ -13,6 +13,11 @@ */ public interface WxMaConfig { + /** + * 设置更新access_token之前的回调 + * + * @param updateAccessTokenBefore 回调函数 + */ default void setUpdateAccessTokenBefore(Consumer updateAccessTokenBefore) {} /** @@ -23,8 +28,18 @@ default void setUpdateAccessTokenBefore(Consumer updateAcce String getAccessToken(); // region 稳定版access token + /** + * 是否使用稳定版access_token + * + * @return 是否使用稳定版access_token + */ boolean isStableAccessToken(); + /** + * 设置是否使用稳定版access_token + * + * @param useStableAccessToken 是否使用稳定版access_token + */ void useStableAccessToken(boolean useStableAccessToken); // endregion @@ -65,6 +80,12 @@ default void updateAccessToken(WxAccessToken accessToken) { */ void updateAccessToken(String accessToken, int expiresInSeconds); + /** + * 更新access_token处理器 + * + * @param accessToken 新的 access_token 值 + * @param expiresInSeconds 过期时间,单位:秒 + */ default void updateAccessTokenProcessor(String accessToken, int expiresInSeconds) { WxAccessTokenEntity wxAccessTokenEntity = new WxAccessTokenEntity(); wxAccessTokenEntity.setAppid(getAppid()); @@ -74,6 +95,11 @@ default void updateAccessTokenProcessor(String accessToken, int expiresInSeconds updateAccessToken(accessToken, expiresInSeconds); } + /** + * 更新access_token之前的回调 + * + * @param wxAccessTokenEntity access_token实体 + */ default void updateAccessTokenBefore(WxAccessTokenEntity wxAccessTokenEntity) {} /** diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java index 08346dbbb..2343634bf 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java @@ -36,6 +36,7 @@ public WxMaCryptUtils(WxMaConfig config) { * @param sessionKey session_key * @param encryptedData 消息密文 * @param ivStr iv字符串 + * @return 解密后的字符串 */ public static String decrypt(String sessionKey, String encryptedData, String ivStr) { try { @@ -58,6 +59,7 @@ public static String decrypt(String sessionKey, String encryptedData, String ivS * @param sessionKey session_key * @param encryptedData 消息密文 * @param ivStr iv字符串 + * @return 解密后的字符串 */ public static String decryptAnotherWay(String sessionKey, String encryptedData, String ivStr) { byte[] keyBytes = Base64.decodeBase64(sessionKey.getBytes(UTF_8)); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java index f36d8c8fb..b9e80d734 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java @@ -24,7 +24,12 @@ public class XStreamTransformer { } /** - * xml -> pojo. + * {@code xml -> pojo.} + * + * @param 返回类型 + * @param clazz 类型 + * @param xml xml字符串 + * @return 转换后的对象 */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, String xml) { @@ -32,6 +37,14 @@ public static T fromXml(Class clazz, String xml) { return object; } + /** + * {@code xml -> pojo.} + * + * @param 返回类型 + * @param clazz 类型 + * @param is 输入流 + * @return 转换后的对象 + */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, InputStream is) { T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); @@ -39,7 +52,12 @@ public static T fromXml(Class clazz, InputStream is) { } /** - * pojo -> xml. + * {@code pojo -> xml.} + * + * @param 类型参数 + * @param clazz 类型 + * @param object 对象 + * @return xml字符串 */ public static String toXml(Class clazz, T object) { return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); 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 188e4be78..ddce68e76 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 @@ -255,11 +255,9 @@ public interface WxMpCardService { String addTestWhiteList(String openid) throws WxErrorException; /** - *
                * 创建卡券
          -     * 
          * - * @param cardCreateRequest 卡券创建请求对象 + * @param cardCreateMessage 卡券创建请求对象 * @return 卡券创建结果对象 * @throws WxErrorException 微信API调用异常,可能包括: *
            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 25463061f..738c1ea65 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 @@ -37,8 +37,8 @@ public interface WxMpCommentService { * @param msgDataId 群发返回的msg_data_id * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 * @param begin 起始位置 - * @param count 获取数目(>=50会被拒绝) - * @param type type=0 普通评论&精选评论 type=1 普通评论 type=2 精选评论 + * @param count 获取数目(大于等于50会被拒绝) + * @param type type=0 普通评论和精选评论 type=1 普通评论 type=2 精选评论 * @return 评论列表数据 wx mp comment list vo * @throws WxErrorException 异常 */ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java index d107444e2..83dd2342e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java @@ -60,10 +60,13 @@ public interface WxMpDataCubeService { List getArticleSummary(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取图文群发总数据(getarticletotal)
            -     * 详情请见文档:图文分析数据接口
            +     * 

            + * {@code 详情请见文档:图文分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getarticletotal?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度1天,endDate不能早于begingDate @@ -73,10 +76,13 @@ public interface WxMpDataCubeService { List getArticleTotal(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取图文统计数据(getuserread)
            -     * 详情请见文档:图文分析数据接口
            +     * 

            + * {@code 详情请见文档:图文分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getuserread?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度3天,endDate不能早于begingDate @@ -86,10 +92,13 @@ public interface WxMpDataCubeService { List getUserRead(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取图文统计分时数据(getuserreadhour)
            -     * 详情请见文档:图文分析数据接口
            +     * 

            + * {@code 详情请见文档:图文分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getuserreadhour?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度1天,endDate不能早于begingDate @@ -99,10 +108,13 @@ public interface WxMpDataCubeService { List getUserReadHour(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取图文分享转发数据(getusershare)
            -     * 详情请见文档:图文分析数据接口
            +     * 

            + * {@code 详情请见文档:图文分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getusershare?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度7天,endDate不能早于begingDate @@ -112,10 +124,13 @@ public interface WxMpDataCubeService { List getUserShare(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取图文分享转发分时数据(getusersharehour)
            -     * 详情请见文档:图文分析数据接口
            +     * 

            + * {@code 详情请见文档:图文分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getusersharehour?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度1天,endDate不能早于begingDate @@ -127,10 +142,13 @@ public interface WxMpDataCubeService { //*******************消息分析数据接口***********************// /** - *
                  * 获取消息发送概况数据(getupstreammsg)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsg?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度7天,endDate不能早于begingDate @@ -140,10 +158,13 @@ public interface WxMpDataCubeService { List getUpstreamMsg(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息分送分时数据(getupstreammsghour)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsghour?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度1天,endDate不能早于begingDate @@ -153,10 +174,13 @@ public interface WxMpDataCubeService { List getUpstreamMsgHour(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息发送周数据(getupstreammsgweek)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsgweek?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度30天,endDate不能早于begingDate @@ -166,10 +190,13 @@ public interface WxMpDataCubeService { List getUpstreamMsgWeek(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息发送月数据(getupstreammsgmonth)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsgmonth?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度30天,endDate不能早于begingDate @@ -179,10 +206,13 @@ public interface WxMpDataCubeService { List getUpstreamMsgMonth(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息发送分布数据(getupstreammsgdist)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsgdist?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度15天,endDate不能早于begingDate @@ -192,10 +222,13 @@ public interface WxMpDataCubeService { List getUpstreamMsgDist(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息发送分布周数据(getupstreammsgdistweek)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsgdistweek?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度30天,endDate不能早于begingDate @@ -205,10 +238,13 @@ public interface WxMpDataCubeService { List getUpstreamMsgDistWeek(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取消息发送分布月数据(getupstreammsgdistmonth)
            -     * 详情请见文档:消息分析数据接口
            +     * 

            + * {@code 详情请见文档:消息分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getupstreammsgdistmonth?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度30天,endDate不能早于begingDate @@ -220,10 +256,13 @@ public interface WxMpDataCubeService { //*******************接口分析数据接口***********************// /** - *
                  * 获取接口分析数据(getinterfacesummary)
            -     * 详情请见文档:接口分析数据接口
            +     * 

            + * {@code 详情请见文档:接口分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getinterfacesummary?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度30天,endDate不能早于begingDate @@ -233,10 +272,13 @@ public interface WxMpDataCubeService { List getInterfaceSummary(Date beginDate, Date endDate) throws WxErrorException; /** - *
                  * 获取接口分析分时数据(getinterfacesummaryhour)
            -     * 详情请见文档:接口分析数据接口
            +     * 

            + * {@code 详情请见文档:接口分析数据接口} + *

            + *

            * 接口url格式:https://api.weixin.qq.com/datacube/getinterfacesummaryhour?access_token=ACCESS_TOKEN + *

            * * @param beginDate 开始时间 * @param endDate 最大时间跨度1天,endDate不能早于begingDate diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 468dced13..2d965bf8d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -54,10 +54,10 @@ public interface WxMpService extends WxService { WxMpShortKeyResult fetchShorten(String shortKey) throws WxErrorException; /** - *
                * 验证消息的确来自微信服务器.
            -   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319&token=&lang=zh_CN
            -   * 
            + *

            + * {@code 详情请见: 接入指南} + *

            * * @param timestamp 时间戳,字符串格式 * @param nonce 随机串,字符串格式 @@ -76,16 +76,19 @@ public interface WxMpService extends WxService { String getAccessToken() throws WxErrorException; /** - *
                * 获取access_token,本方法线程安全.
            +   * 

            * 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限 - * + *

            + *

            * 另:本service的所有方法都会在access_token过期时调用此方法 - * + *

            + *

            * 程序员在非必要情况下尽量不要主动调用此方法 - * - * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183&token=&lang=zh_CN - *

            + *

            + *

            + * {@code 详情请见: 获取access_token} + *

            * * @param forceRefresh 是否强制刷新,true表示强制刷新,false表示使用缓存 * @return token access token,字符串格式 @@ -126,12 +129,13 @@ public interface WxMpService extends WxService { String getJsapiTicket() throws WxErrorException; /** - *
                * 获得jsapi_ticket.
            +   * 

            * 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干 - * - * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN - *

            + *

            + *

            + * {@code 详情请见:JS-SDK使用权限签名算法} + *

            * * @param forceRefresh 强制刷新,true表示强制刷新,false表示使用缓存 * @return jsapi ticket,字符串格式 @@ -140,11 +144,10 @@ public interface WxMpService extends WxService { String getJsapiTicket(boolean forceRefresh) throws WxErrorException; /** - *
                * 创建调用jsapi时所需要的签名.
            -   *
            -   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
            -   * 
            + *

            + * {@code 详情请见:JS-SDK使用权限签名算法} + *

            * * @param url 当前网页的URL,不包括#及其后面部分 * @return 生成的签名对象,包含签名、时间戳、随机串等信息 @@ -153,10 +156,10 @@ public interface WxMpService extends WxService { WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; /** - *
                * 长链接转短链接接口.
            -   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=长链接转短链接接口
            -   * 
            + *

            + * 详情请见: 长链接转短链接接口 + *

            * * @param longUrl 长url,需要转换的原始URL * @return 生成的短地址,字符串格式 @@ -167,10 +170,10 @@ public interface WxMpService extends WxService { String shortUrl(String longUrl) throws WxErrorException; /** - *
                * 语义查询接口.
            -   * 详情请见:http://mp.weixin.qq.com/wiki/index.php?title=语义理解
            -   * 
            + *

            + * 详情请见:语义理解 + *

            * * @param semanticQuery 查询条件,包含查询内容、类型等信息 * @return 查询结果,包含语义理解的结果和建议回复 @@ -179,11 +182,13 @@ public interface WxMpService extends WxService { WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; /** - *
                * 构造第三方使用网站应用授权登录的url.
            -   * 详情请见: 网站应用微信登录开发指南
            -   * URL格式为:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
            -   * 
            + *

            + * {@code 详情请见: 网站应用微信登录开发指南} + *

            + *

            + * {@code URL格式为:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect} + *

            * * @param redirectUri 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode * @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 @@ -193,10 +198,7 @@ public interface WxMpService extends WxService { String buildQrConnectUrl(String redirectUri, String scope, String state); /** - *
                * 获取微信服务器IP地址
            -   * http://mp.weixin.qq.com/wiki/0/2ad4b6bfd29f30f71d39616c2a0fcedc.html
            -   * 
            * * @return 微信服务器ip地址数组,包含所有微信服务器IP地址 * @throws WxErrorException 微信API调用异常 @@ -204,11 +206,10 @@ public interface WxMpService extends WxService { String[] getCallbackIP() throws WxErrorException; /** - *
            -   *  网络检测
            -   *  https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21541575776DtsuT
            -   *  为了帮助开发者排查回调连接失败的问题,提供这个网络检测的API。它可以对开发者URL做域名解析,然后对所有IP进行一次ping操作,得到丢包率和耗时。
            -   * 
            + * 网络检测 + *

            + * 为了帮助开发者排查回调连接失败的问题,提供这个网络检测的API。它可以对开发者URL做域名解析,然后对所有IP进行一次ping操作,得到丢包率和耗时。 + *

            * * @param action 执行的检测动作,可选值:all(全部检测)、dns(仅域名解析)、ping(仅网络连通性检测) * @param operator 指定平台从某个运营商进行检测,可选值:CHINANET(中国电信)、UNICOM(中国联通)、CAP(中国联通)、CUCC(中国联通) @@ -239,12 +240,13 @@ public interface WxMpService extends WxService { WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException; /** - *
            -   *  公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零:
            -   *  HTTP调用:https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=ACCESS_TOKEN
            -   *  接口文档地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592
            -   *
            -   * 
            + * 公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零. + *

            + * HTTP调用:https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=ACCESS_TOKEN + *

            + *

            + * {@code 接口文档地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592} + *

            * * @param appid 公众号的APPID,需要清零调用的公众号的appid * @throws WxErrorException 微信API调用异常 @@ -252,11 +254,9 @@ public interface WxMpService extends WxService { void clearQuota(String appid) throws WxErrorException; /** - *
                * Service没有实现某个API的时候,可以用这个,
                * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
                * 可以参考,{@link MediaUploadRequestExecutor}的实现方法
            -   * 
            * * @param 返回值类型 * @param 参数类型 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 63ca608eb..76ab46615 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 @@ -304,8 +304,9 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { /** * 通过网络请求获取稳定版接口调用凭据 * - * @return . - * @throws IOException . + * @param forceRefresh 是否强制刷新 + * @return access_token字符串 + * @throws IOException IO异常 */ protected abstract String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java index 80e1658c1..936996ef6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java @@ -25,11 +25,11 @@ public class WxMpMassOpenIdsMessage implements Serializable { /** *
                * 请使用
            -   * {@link WxConsts.MassMsgType#IMAGE}
            -   * {@link WxConsts.MassMsgType#MPNEWS}
            -   * {@link WxConsts.MassMsgType#TEXT}
            -   * {@link WxConsts.MassMsgType#MPVIDEO}
            -   * {@link WxConsts.MassMsgType#VOICE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#IMAGE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPNEWS}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#TEXT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPVIDEO}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#VOICE}
                * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
                * 
            */ @@ -60,6 +60,8 @@ public String toJson() { /** * 添加openid,最多支持10,000个 + * + * @param openid 用户openid */ public void addUser(String openid) { this.toUsers.add(openid); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java index dca743c9c..57b34d352 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java @@ -19,11 +19,11 @@ public class WxMpMassPreviewMessage implements Serializable { *
                * 消息类型
                * 请使用
            -   * {@link WxConsts.MassMsgType#IMAGE}
            -   * {@link WxConsts.MassMsgType#MPNEWS}
            -   * {@link WxConsts.MassMsgType#TEXT}
            -   * {@link WxConsts.MassMsgType#MPVIDEO}
            -   * {@link WxConsts.MassMsgType#VOICE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#IMAGE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPNEWS}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#TEXT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPVIDEO}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#VOICE}
                * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
                * 
            */ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java index 598e5754f..466ef8d96 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java @@ -24,11 +24,11 @@ public class WxMpMassTagMessage implements Serializable { *
                * 消息类型.
                * 请使用
            -   * {@link WxConsts.MassMsgType#IMAGE}
            -   * {@link WxConsts.MassMsgType#MPNEWS}
            -   * {@link WxConsts.MassMsgType#TEXT}
            -   * {@link WxConsts.MassMsgType#MPVIDEO}
            -   * {@link WxConsts.MassMsgType#VOICE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#IMAGE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPNEWS}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#TEXT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#MPVIDEO}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.MassMsgType#VOICE}
                * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
                * 
            */ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java index 9e73b4615..ac4a596dd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java @@ -63,9 +63,8 @@ public WxMpUserQuery add(String openid, String lang) { /** * 添加一个OpenId到列表中,并返回本对象 *

            - *

                * 该方法默认lang = zh_CN
            -   * 
            + *

            * * @param openid openid * @return {@link WxMpUserQuery} @@ -100,6 +99,8 @@ public WxMpUserQuery remove(String openid, String lang) { /** * 获取查询参数列表 + * + * @return 查询参数列表 */ public List getQueryParamList() { return this.queryParamList; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java index 6d7dde1ad..34a9c56b9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java @@ -8,7 +8,9 @@ /** - * @author S + * 卡券图文消息HTML结果 + * + * @author S (sshzh90@gmail.com) */ @Data public class WxMpCardMpnewsGethtmlResult implements Serializable { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardActivateUserFormRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardActivateUserFormRequest.java index d8634cfa3..0adb41386 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardActivateUserFormRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardActivateUserFormRequest.java @@ -39,8 +39,8 @@ public class MemberCardActivateUserFormRequest implements Serializable { /** * 绑定老会员卡信息 * - * @param name - * @param url + * @param name 名称 + * @param url 链接地址 */ public void setBindOldCard(String name, String url) { if (StringUtils.isAnyEmpty(name, url)) { @@ -56,8 +56,8 @@ public void setBindOldCard(String name, String url) { /** * 设置服务声明,用于放置商户会员卡守则 * - * @param name - * @param url + * @param name 名称 + * @param url 链接地址 */ public void setServiceStatement(String name, String url) { if (StringUtils.isAnyEmpty(name, url)) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardUserForm.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardUserForm.java index 0c0fae3e2..b3b0c9be5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardUserForm.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/MemberCardUserForm.java @@ -50,6 +50,7 @@ public class MemberCardUserForm implements Serializable { /** * 添加富文本类型字段 * + * @param field 富文本字段 */ public void addRichField(MemberCardUserFormRichField field) { if (field == null) { @@ -64,6 +65,7 @@ public void addRichField(MemberCardUserFormRichField field) { /** * 添加微信选项类型字段 * + * @param fieldType 微信字段类型 */ public void addWechatField(CardWechatFieldType fieldType) { if (fieldType == null) { @@ -78,6 +80,7 @@ public void addWechatField(CardWechatFieldType fieldType) { /** * 添加文本类型字段 * + * @param field 文本字段 */ public void addCustomField(String field) { if (StringUtils.isBlank(field)) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/NotifyOptional.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/NotifyOptional.java index 139db6855..1ba8a0e60 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/NotifyOptional.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/NotifyOptional.java @@ -6,12 +6,13 @@ import java.io.Serializable; /** - *
              * 控制原生消息结构体,包含各字段的消息控制字段。
            - *
            + * 

            * 用于 `7 更新会员信息` 的接口参数调用 - * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025283 - *

            + *

            + *

            + * {@code 参考:会员卡接口} + *

            * * @author YuJian(mgcnrx11@gmail.com) * @version 2017/7/15 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUpdateResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUpdateResult.java index 663fe1f1e..b4ad8eb13 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUpdateResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUpdateResult.java @@ -6,10 +6,10 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** - *
              * 用于 `7 更新会员信息` 的接口调用后的返回结果
            - * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025283
            - * 
            + *

            + * {@code 参考:会员卡接口} + *

            * * @author YuJian(mgcnrx11@gmail.com) * @version 2017/7/15 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUserInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUserInfoResult.java index 8fad40ccf..9a2b47f5b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUserInfoResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/membercard/WxMpMemberCardUserInfoResult.java @@ -6,11 +6,10 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** - *
              * 拉取会员信息返回的结果
            - *
            - * 字段格式参考https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025283  6.2.1小节的步骤5
            - * 
            + *

            + * {@code 字段格式参考:会员卡接口 6.2.1小节的步骤5} + *

            * * @author YuJian * @version 2017/7/9 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java index f066c1d93..01be3c08d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java @@ -45,6 +45,8 @@ public class WxMpKefuMessage implements Serializable { /** * 获得文本消息builder. + * + * @return 文本消息builder */ public static TextBuilder TEXT() { return new TextBuilder(); @@ -52,6 +54,8 @@ public static TextBuilder TEXT() { /** * 获得图片消息builder. + * + * @return 图片消息builder */ public static ImageBuilder IMAGE() { return new ImageBuilder(); @@ -59,6 +63,8 @@ public static ImageBuilder IMAGE() { /** * 获得语音消息builder. + * + * @return 语音消息builder */ public static VoiceBuilder VOICE() { return new VoiceBuilder(); @@ -66,6 +72,8 @@ public static VoiceBuilder VOICE() { /** * 获得视频消息builder. + * + * @return 视频消息builder */ public static VideoBuilder VIDEO() { return new VideoBuilder(); @@ -73,6 +81,8 @@ public static VideoBuilder VIDEO() { /** * 获得音乐消息builder. + * + * @return 音乐消息builder */ public static MusicBuilder MUSIC() { return new MusicBuilder(); @@ -80,6 +90,8 @@ public static MusicBuilder MUSIC() { /** * 获得图文消息(点击跳转到外链)builder. + * + * @return 图文消息builder */ public static NewsBuilder NEWS() { return new NewsBuilder(); @@ -87,6 +99,8 @@ public static NewsBuilder NEWS() { /** * 获得图文消息(点击跳转到图文消息页面)builder. + * + * @return 图文消息builder */ public static MpNewsBuilder MPNEWS() { return new MpNewsBuilder(); @@ -94,6 +108,8 @@ public static MpNewsBuilder MPNEWS() { /** * 获得卡券消息builder. + * + * @return 卡券消息builder */ public static WxCardBuilder WXCARD() { return new WxCardBuilder(); @@ -101,6 +117,8 @@ public static WxCardBuilder WXCARD() { /** * 获得菜单消息builder. + * + * @return 菜单消息builder */ public static WxMsgMenuBuilder MSGMENU() { return new WxMsgMenuBuilder(); @@ -108,20 +126,25 @@ public static WxMsgMenuBuilder MSGMENU() { /** * 小程序卡片. + * + * @return 小程序卡片builder */ public static MiniProgramPageBuilder MINIPROGRAMPAGE() { return new MiniProgramPageBuilder(); } /** - * 发送图文消息(点击跳转到图文消息页面)使用通过 “发布” 系列接口得到的 article_id(草稿箱功能上线后不再支持客服接口中带 media_id 的 mpnews 类型的图文消息) + * 发送图文消息(点击跳转到图文消息页面)使用通过 “发布” 系列接口得到的 article_id + * + * @return 图文消息builder */ public static MpNewsArticleBuilder MPNEWSARTICLE() { return new MpNewsArticleBuilder(); } /** - *
            +   * 设置消息类型
            +   * 

            * 请使用 * {@link me.chanjar.weixin.common.api.WxConsts.KefuMsgType#TEXT} * {@link me.chanjar.weixin.common.api.WxConsts.KefuMsgType#IMAGE} @@ -135,7 +158,9 @@ public static MpNewsArticleBuilder MPNEWSARTICLE() { * {@link me.chanjar.weixin.common.api.WxConsts.KefuMsgType#TASKCARD} * {@link me.chanjar.weixin.common.api.WxConsts.KefuMsgType#MSGMENU} * {@link me.chanjar.weixin.common.api.WxConsts.KefuMsgType#MP_NEWS_ARTICLE} - *

            + *

            + * + * @param msgType 消息类型 */ public void setMsgType(String msgType) { this.msgType = msgType; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java index 3d5f4ac3a..dfc88ab13 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java @@ -927,6 +927,7 @@ public static WxMpXmlMessage fromXml(InputStream is) { * @param timestamp 时间戳 * @param nonce 随机串 * @param msgSignature 签名串 + * @return 解密后的消息对象 */ public static WxMpXmlMessage fromEncryptedXml(String encryptedXml, WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce, String msgSignature) { @@ -956,14 +957,16 @@ public WxMpXmlMessage decryptField(WxMpConfigStorage wxMpConfigStorage, /** *
                * 当接受用户消息时,可能会获得以下值:
            -   * {@link WxConsts.XmlMsgType#TEXT}
            -   * {@link WxConsts.XmlMsgType#IMAGE}
            -   * {@link WxConsts.XmlMsgType#VOICE}
            -   * {@link WxConsts.XmlMsgType#VIDEO}
            -   * {@link WxConsts.XmlMsgType#LOCATION}
            -   * {@link WxConsts.XmlMsgType#LINK}
            -   * {@link WxConsts.XmlMsgType#EVENT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#TEXT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#IMAGE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VOICE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VIDEO}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#LOCATION}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#LINK}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#EVENT}
                * 
            + * + * @return 消息类型 */ public String getMsgType() { return this.msgType; @@ -972,13 +975,15 @@ public String getMsgType() { /** *
                * 当发送消息的时候使用:
            -   * {@link WxConsts.XmlMsgType#TEXT}
            -   * {@link WxConsts.XmlMsgType#IMAGE}
            -   * {@link WxConsts.XmlMsgType#VOICE}
            -   * {@link WxConsts.XmlMsgType#VIDEO}
            -   * {@link WxConsts.XmlMsgType#NEWS}
            -   * {@link WxConsts.XmlMsgType#MUSIC}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#TEXT}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#IMAGE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VOICE}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#VIDEO}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#NEWS}
            +   * {@link me.chanjar.weixin.common.api.WxConsts.XmlMsgType#MUSIC}
                * 
            + * + * @param msgType 消息类型 */ public void setMsgType(String msgType) { this.msgType = msgType; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java index a44aea740..1f3143df7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java @@ -70,6 +70,8 @@ public abstract class WxMpXmlOutMessage implements Serializable { /** * 获得文本消息builder + * + * @return 文本消息构建器 */ public static TextBuilder TEXT() { return new TextBuilder(); @@ -77,6 +79,8 @@ public static TextBuilder TEXT() { /** * 获得图片消息builder + * + * @return 图片消息构建器 */ public static ImageBuilder IMAGE() { return new ImageBuilder(); @@ -84,6 +88,8 @@ public static ImageBuilder IMAGE() { /** * 获得语音消息builder + * + * @return 语音消息构建器 */ public static VoiceBuilder VOICE() { return new VoiceBuilder(); @@ -91,6 +97,8 @@ public static VoiceBuilder VOICE() { /** * 获得视频消息builder + * + * @return 视频消息构建器 */ public static VideoBuilder VIDEO() { return new VideoBuilder(); @@ -98,6 +106,8 @@ public static VideoBuilder VIDEO() { /** * 获得音乐消息builder + * + * @return 音乐消息构建器 */ public static MusicBuilder MUSIC() { return new MusicBuilder(); @@ -105,6 +115,8 @@ public static MusicBuilder MUSIC() { /** * 获得图文消息builder + * + * @return 图文消息构建器 */ public static NewsBuilder NEWS() { return new NewsBuilder(); @@ -112,6 +124,8 @@ public static NewsBuilder NEWS() { /** * 获得客服消息builder + * + * @return 客服消息构建器 */ public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { return new TransferCustomerServiceBuilder(); @@ -119,11 +133,18 @@ public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { /** * 获得设备消息builder + * + * @return 设备消息builder */ public static DeviceBuilder DEVICE() { return new DeviceBuilder(); } + /** + * 转换成xml格式 + * + * @return xml格式字符串 + */ @SuppressWarnings("unchecked") public String toXml() { return XStreamTransformer.toXml((Class) this.getClass(), this); @@ -131,6 +152,9 @@ public String toXml() { /** * 转换成加密的结果 + * + * @param wxMpConfigStorage 公众号配置 + * @return 加密后的消息对象 */ public WxMpXmlOutMessage toEncrypted(WxMpConfigStorage wxMpConfigStorage) { String plainXml = toXml(); @@ -146,6 +170,9 @@ public WxMpXmlOutMessage toEncrypted(WxMpConfigStorage wxMpConfigStorage) { /** * 转换成加密的xml格式 + * + * @param wxMpConfigStorage 公众号配置 + * @return 加密后的xml格式字符串 */ public String toEncryptedXml(WxMpConfigStorage wxMpConfigStorage) { String plainXml = toXml(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java index fe8f6e404..58f2ea269 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java @@ -9,7 +9,8 @@ /** *
              * 查询群发消息发送状态【订阅号与服务号认证后均可用】
            - * https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html#%E6%9F%A5%E8%AF%A2%E7%BE%A4%E5%8F%91%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E7%8A%B6%E6%80%81%E3%80%90%E8%AE%A2%E9%98%85%E5%8F%B7%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%8F%B7%E8%AE%A4%E8%AF%81%E5%90%8E%E5%9D%87%E5%8F%AF%E7%94%A8%E3%80%91
            + * 文档地址:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html
            + * 
            * @author S */ @Data diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/WxMpConfigStorage.java index 11aeef612..1bebe8688 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/WxMpConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/WxMpConfigStorage.java @@ -24,7 +24,7 @@ public interface WxMpConfigStorage { * Is use stable access token api * * @return the boolean - * @link https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/getStableAccessToken.html + * @see 文档 */ boolean isStableAccessToken(); @@ -211,6 +211,8 @@ public interface WxMpConfigStorage { *
                *   {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
                * 
            + * + * @return 重试间隔毫秒数 */ int getRetrySleepMillis(); @@ -219,6 +221,8 @@ public interface WxMpConfigStorage { *
                *   {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
                * 
            + * + * @return 最大重试次数 */ int getMaxRetryTimes(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java index 870fa1e27..7939d57a1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java @@ -39,6 +39,8 @@ public WxMpRedisConfigImpl(WxRedisOps redisOps, String keyPrefix) { /** * 每个公众号生成独有的存储key. + * + * @param appId 公众号appId */ @Override public void setAppId(String appId) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedissonConfigImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedissonConfigImpl.java index e0d9e92af..4982336f8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedissonConfigImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedissonConfigImpl.java @@ -42,6 +42,8 @@ private WxMpRedissonConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) { /** * 每个公众号生成独有的存储key. + * + * @param appId 公众号appId */ @Override public void setAppId(String appId) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java index b2e984b0f..4dfee6295 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java @@ -20,7 +20,7 @@ public class WxMpEventConstants { public static final String SUBMIT_MEMBERCARD_USER_INFO = "submit_membercard_user_info"; /** - * 微信摇一摇周边>>摇一摇事件通知. + * 微信摇一摇周边-摇一摇事件通知. */ public static final String SHAKEAROUND_USER_SHAKE = "ShakearoundUserShake"; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java index 99d759f32..7757ad78b 100755 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java @@ -27,7 +27,7 @@ public class WxMpCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptU /** * 构造函数 * - * @param wxMpConfigStorage + * @param wxMpConfigStorage 公众号配置存储 */ public WxMpCryptUtil(WxMpConfigStorage wxMpConfigStorage) { /* diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java index ace711a23..55e92700d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java @@ -33,7 +33,12 @@ public class XStreamTransformer { } /** - * xml -> pojo. + * {@code xml -> pojo.} + * + * @param 返回类型 + * @param clazz 类型 + * @param xml xml字符串 + * @return 转换后的对象 */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, String xml) { @@ -41,6 +46,14 @@ public static T fromXml(Class clazz, String xml) { return object; } + /** + * {@code xml -> pojo.} + * + * @param 返回类型 + * @param clazz 类型 + * @param is 输入流 + * @return 转换后的对象 + */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, InputStream is) { T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); @@ -48,7 +61,12 @@ public static T fromXml(Class clazz, InputStream is) { } /** - * pojo -> xml. + * {@code pojo -> xml.} + * + * @param 类型参数 + * @param clazz 类型 + * @param object 对象 + * @return xml字符串 */ public static String toXml(Class clazz, T object) { return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/MiPayNotifyV3Result.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/MiPayNotifyV3Result.java index a0641379f..346d427fc 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/MiPayNotifyV3Result.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/MiPayNotifyV3Result.java @@ -13,7 +13,7 @@ *
            * * @author xgl - * @date 2025/12/20 + * @since 2025/12/20 */ @Data @NoArgsConstructor diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayBaseNotifyV3Result.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayBaseNotifyV3Result.java index 86915d095..364c9080d 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayBaseNotifyV3Result.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayBaseNotifyV3Result.java @@ -5,7 +5,8 @@ * * @author Pursuer * @version 1.0 - * @date 2023/6/15 + * @since 2023/6/15 + * @param 解密后的数据类型 */ public interface WxPayBaseNotifyV3Result { /** @@ -13,9 +14,8 @@ public interface WxPayBaseNotifyV3Result { * * @param rawData 原始数据 * @author Pursuer - * @date 2023/6/15 - * @since 1.0 - **/ + * @since 2023/6/15 + */ void setRawData(OriginNotifyResponse rawData); /** @@ -23,8 +23,7 @@ public interface WxPayBaseNotifyV3Result { * * @param data 解密后的数据 * @author Pursuer - * @date 2023/6/15 - * @since 1.0 - **/ + * @since 2023/6/15 + */ void setResult(T data); } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyV3Response.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyV3Response.java index b9d7f4d9f..eac5f7c9d 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyV3Response.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyV3Response.java @@ -28,8 +28,8 @@ public class WxPayNotifyV3Response { /** * 返回成功 * - * @param msg - * @return + * @param msg 返回消息 + * @return 成功响应的JSON字符串 */ public static String success(String msg) { WxPayNotifyV3Response response = new WxPayNotifyV3Response(SUCCESS, msg); @@ -40,7 +40,7 @@ public static String success(String msg) { * 返回失败 * * @param msg 返回信息,如非空,为错误原因 - * @return + * @return 失败响应的JSON字符串 */ public static String fail(String msg) { WxPayNotifyV3Response response = new WxPayNotifyV3Response(FAIL, msg); 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 a3a9dc7a9..b42451a66 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 @@ -325,7 +325,8 @@ public SSLContext initSSLContext() throws WxPayException { * * @return org.apache.http.impl.client.CloseableHttpClient * @author doger.wang - **/ + * @throws WxPayException 微信支付异常 + */ public CloseableHttpClient initApiV3HttpClient() throws WxPayException { if (StringUtils.isBlank(this.getApiV3Key())) { throw new WxPayException("请确保apiV3Key值已设置"); @@ -663,6 +664,8 @@ public CloseableHttpClient initSslHttpClient() throws WxPayException { /** * 配置HTTP代理 + * + * @param httpClientBuilder HttpClient构建器 */ private void configureProxy(org.apache.http.impl.client.HttpClientBuilder httpClientBuilder) { if (StringUtils.isNotBlank(this.getHttpProxyHost()) && this.getHttpProxyPort() > 0) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java index b641cbe53..c4ad96641 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java @@ -17,7 +17,7 @@ public class RequestUtils { /** * 获取请求头数据,微信V3版本回调使用 * - * @param request + * @param request HTTP请求对象 * @return 字符串 */ public static String readData(HttpServletRequest request) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java index ac68b00bb..51dd8fbbb 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java @@ -23,6 +23,10 @@ public class ResourcesUtils { *
          • {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
          • *
          • if callingClass is provided: {@link Class#getClassLoader() callingClass.getClassLoader()}
          • *
          + * + * @param resourceName 资源名称 + * @param classLoader 类加载器 + * @return 资源URL */ public static URL getResourceUrl(String resourceName, final ClassLoader classLoader) { @@ -64,6 +68,9 @@ public static URL getResourceUrl(String resourceName, final ClassLoader classLoa /** * Opens a resource of the specified name for reading. * + * @param resourceName 资源名称 + * @return 输入流 + * @throws IOException IO异常 * @see #getResourceAsStream(String, ClassLoader) */ public static InputStream getResourceAsStream(final String resourceName) throws IOException { @@ -73,6 +80,10 @@ public static InputStream getResourceAsStream(final String resourceName) throws /** * Opens a resource of the specified name for reading. * + * @param resourceName 资源名称 + * @param callingClass 类加载器 + * @return 输入流 + * @throws IOException IO异常 * @see #getResourceUrl(String, ClassLoader) */ public static InputStream getResourceAsStream(final String resourceName, final ClassLoader callingClass) throws IOException { 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 6c0009fd1..9d4a9b023 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 @@ -112,7 +112,16 @@ public static String createSign(Map params, String signType, Str /** * 企业微信签名 * - * @param signType md5 目前接口要求使用的加密类型 + * @param actName 活动名称 + * @param mchBillNo 商户订单号 + * @param mchId 商户号 + * @param nonceStr 随机字符串 + * @param reOpenid 用户openid + * @param totalAmount 金额 + * @param wxAppId 微信appid + * @param signKey 签名密钥 + * @param signType md5 目前接口要求使用的加密类型 + * @return 签名字符串 */ public static String createEntSign(String actName, String mchBillNo, String mchId, String nonceStr, String reOpenid, Integer totalAmount, String wxAppId, String signKey, @@ -131,7 +140,18 @@ public static String createEntSign(String actName, String mchBillNo, String mchI /** * 企业微信签名 - * @param signType md5 目前接口要求使用的加密类型 + * + * @param totalAmount 金额 + * @param appId 应用ID + * @param description 描述 + * @param mchId 商户号 + * @param nonceStr 随机字符串 + * @param openid 用户openid + * @param partnerTradeNo 商户订单号 + * @param wwMsgType 消息类型 + * @param signKey 签名密钥 + * @param signType md5 目前接口要求使用的加密类型 + * @return 签名字符串 */ public static String createEntSign(Integer totalAmount, String appId, String description, String mchId, String nonceStr, String openid, String partnerTradeNo, String wwMsgType, From e572ddfba61e7ada2cb0a4a8915a6afb08118d4b Mon Sep 17 00:00:00 2001 From: buaazyl Date: Wed, 7 Jan 2026 09:52:21 +0800 Subject: [PATCH 07/33] =?UTF-8?q?:art:=20#3833=20=E3=80=90=E5=85=AC?= =?UTF-8?q?=E4=BC=97=E5=8F=B7=E3=80=91=E9=87=8D=E6=9E=84Starter=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E9=85=8D=E7=BD=AE=E5=AD=98=E5=82=A8=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=8C=89=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E7=B1=BB=E5=9E=8B=E6=8B=86=E5=88=86=E4=B8=BA=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E9=85=8D=E7=BD=AE=E7=B1=BB=EF=BC=8C=E5=B9=B6=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8F=AF=E9=80=89=E7=9A=84=20Redisson=20=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solon-plugins/wx-java-mp-solon-plugin/pom.xml | 7 +- .../config/WxMpStorageAutoConfiguration.java | 128 ------------- ...bstractWxMpConfigStorageConfiguration.java | 27 +++ ...WxMpInJedisConfigStorageConfiguration.java | 76 ++++++++ ...xMpInMemoryConfigStorageConfiguration.java | 29 +++ ...pInRedissonConfigStorageConfiguration.java | 65 +++++++ .../wxjava/mp/integration/WxMpPluginImpl.java | 15 +- .../wx-java-mp-spring-boot-starter/pom.xml | 7 +- .../config/WxMpStorageAutoConfiguration.java | 171 ++---------------- ...bstractWxMpConfigStorageConfiguration.java | 54 ++++++ ...WxMpInJedisConfigStorageConfiguration.java | 80 ++++++++ ...xMpInMemoryConfigStorageConfiguration.java | 33 ++++ ...disTemplateConfigStorageConfiguration.java | 46 +++++ ...pInRedissonConfigStorageConfiguration.java | 69 +++++++ 14 files changed, 514 insertions(+), 293 deletions(-) delete mode 100644 solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpStorageAutoConfiguration.java create mode 100644 solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java create mode 100644 solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java create mode 100644 solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java create mode 100644 solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedisTemplateConfigStorageConfiguration.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java diff --git a/solon-plugins/wx-java-mp-solon-plugin/pom.xml b/solon-plugins/wx-java-mp-solon-plugin/pom.xml index d2507cc0d..d72a5f7fc 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-mp-solon-plugin/pom.xml @@ -22,7 +22,12 @@ redis.clients jedis - compile + provided + + + org.redisson + redisson + provided org.jodd diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpStorageAutoConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpStorageAutoConfiguration.java deleted file mode 100644 index ac995dd1e..000000000 --- a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpStorageAutoConfiguration.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.binarywang.solon.wxjava.mp.config; - -import com.binarywang.solon.wxjava.mp.enums.StorageType; -import com.binarywang.solon.wxjava.mp.properties.RedisProperties; -import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; -import com.google.common.collect.Sets; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.redis.JedisWxRedisOps; -import me.chanjar.weixin.common.redis.WxRedisOps; -import me.chanjar.weixin.mp.config.WxMpConfigStorage; -import me.chanjar.weixin.mp.config.WxMpHostConfig; -import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; -import org.apache.commons.lang3.StringUtils; -import org.noear.solon.annotation.Bean; -import org.noear.solon.annotation.Condition; -import org.noear.solon.annotation.Configuration; -import org.noear.solon.core.AppContext; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.JedisSentinelPool; -import redis.clients.jedis.util.Pool; - -import java.util.Set; - -/** - * 微信公众号存储策略自动配置. - * - * @author Luo - */ -@Slf4j -@Configuration -@RequiredArgsConstructor -public class WxMpStorageAutoConfiguration { - private final AppContext applicationContext; - - private final WxMpProperties wxMpProperties; - - @Bean - @Condition(onMissingBean=WxMpConfigStorage.class) - public WxMpConfigStorage wxMpConfigStorage() { - StorageType type = wxMpProperties.getConfigStorage().getType(); - WxMpConfigStorage config; - switch (type) { - case Jedis: - config = jedisConfigStorage(); - break; - default: - config = defaultConfigStorage(); - break; - } - // wx host config - if (null != wxMpProperties.getHosts() && StringUtils.isNotEmpty(wxMpProperties.getHosts().getApiHost())) { - WxMpHostConfig hostConfig = new WxMpHostConfig(); - hostConfig.setApiHost(wxMpProperties.getHosts().getApiHost()); - hostConfig.setMpHost(wxMpProperties.getHosts().getMpHost()); - hostConfig.setOpenHost(wxMpProperties.getHosts().getOpenHost()); - config.setHostConfig(hostConfig); - } - return config; - } - - private WxMpConfigStorage defaultConfigStorage() { - WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); - setWxMpInfo(config); - return config; - } - - private WxMpConfigStorage jedisConfigStorage() { - Pool jedisPool; - if (wxMpProperties.getConfigStorage() != null && wxMpProperties.getConfigStorage().getRedis() != null - && StringUtils.isNotEmpty(wxMpProperties.getConfigStorage().getRedis().getHost())) { - jedisPool = getJedisPool(); - } else { - jedisPool = applicationContext.getBean(JedisPool.class); - } - WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); - WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, - wxMpProperties.getConfigStorage().getKeyPrefix()); - setWxMpInfo(wxMpRedisConfig); - return wxMpRedisConfig; - } - - private void setWxMpInfo(WxMpDefaultConfigImpl config) { - WxMpProperties properties = wxMpProperties; - WxMpProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); - config.setAppId(properties.getAppId()); - config.setSecret(properties.getSecret()); - config.setToken(properties.getToken()); - config.setAesKey(properties.getAesKey()); - config.setUseStableAccessToken(wxMpProperties.isUseStableAccessToken()); - config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); - config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); - config.setHttpProxyPassword(configStorageProperties.getHttpProxyPassword()); - if (configStorageProperties.getHttpProxyPort() != null) { - config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); - } - } - - private Pool getJedisPool() { - RedisProperties redis = wxMpProperties.getConfigStorage().getRedis(); - - JedisPoolConfig config = new JedisPoolConfig(); - if (redis.getMaxActive() != null) { - config.setMaxTotal(redis.getMaxActive()); - } - if (redis.getMaxIdle() != null) { - config.setMaxIdle(redis.getMaxIdle()); - } - if (redis.getMaxWaitMillis() != null) { - config.setMaxWaitMillis(redis.getMaxWaitMillis()); - } - if (redis.getMinIdle() != null) { - config.setMinIdle(redis.getMinIdle()); - } - config.setTestOnBorrow(true); - config.setTestWhileIdle(true); - if (StringUtils.isNotEmpty(redis.getSentinelIps())) { - Set sentinels = Sets.newHashSet(redis.getSentinelIps().split(",")); - return new JedisSentinelPool(redis.getSentinelName(), sentinels); - } - - return new JedisPool(config, redis.getHost(), redis.getPort(), redis.getTimeout(), redis.getPassword(), - redis.getDatabase()); - } -} diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java new file mode 100644 index 000000000..663bb1334 --- /dev/null +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java @@ -0,0 +1,27 @@ +package com.binarywang.solon.wxjava.mp.config.storage; + +import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; + +/** + * @author zhangyl + */ +public abstract class AbstractWxMpConfigStorageConfiguration { + + protected WxMpDefaultConfigImpl config(WxMpDefaultConfigImpl config, WxMpProperties properties) { + config.setAppId(properties.getAppId()); + config.setSecret(properties.getSecret()); + config.setToken(properties.getToken()); + config.setAesKey(properties.getAesKey()); + config.setUseStableAccessToken(properties.isUseStableAccessToken()); + + WxMpProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); + config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); + config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); + config.setHttpProxyPassword(configStorageProperties.getHttpProxyPassword()); + if (configStorageProperties.getHttpProxyPort() != null) { + config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); + } + return config; + } +} diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java new file mode 100644 index 000000000..a949ccfac --- /dev/null +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java @@ -0,0 +1,76 @@ +package com.binarywang.solon.wxjava.mp.config.storage; + +import com.binarywang.solon.wxjava.mp.properties.RedisProperties; +import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; +import org.apache.commons.lang3.StringUtils; +import org.noear.solon.annotation.Bean; +import org.noear.solon.annotation.Condition; +import org.noear.solon.annotation.Configuration; +import org.noear.solon.core.AppContext; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +/** + * @author zhangyl + */ +@Configuration +@Condition( + onProperty = "${" + WxMpProperties.PREFIX + ".config-storage.type} = jedis", + onClass = Jedis.class +) +@RequiredArgsConstructor +public class WxMpInJedisConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + private final AppContext applicationContext; + + @Bean + @Condition(onMissingBean = WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpRedisConfigImpl config = getWxMpRedisConfigImpl(); + return this.config(config, properties); + } + + private WxMpRedisConfigImpl getWxMpRedisConfigImpl() { + RedisProperties redisProperties = properties.getConfigStorage().getRedis(); + JedisPool jedisPool; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + jedisPool = applicationContext.getBean("wxMpJedisPool"); + } else { + jedisPool = applicationContext.getBean(JedisPool.class); + } + WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); + return new WxMpRedisConfigImpl(redisOps, properties.getConfigStorage().getKeyPrefix()); + } + + @Bean + @Condition(onProperty = "${" + WxMpProperties.PREFIX + ".config-storage.redis.host}") + public JedisPool wxMpJedisPool() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + JedisPoolConfig config = new JedisPoolConfig(); + if (redis.getMaxActive() != null) { + config.setMaxTotal(redis.getMaxActive()); + } + if (redis.getMaxIdle() != null) { + config.setMaxIdle(redis.getMaxIdle()); + } + if (redis.getMaxWaitMillis() != null) { + config.setMaxWaitMillis(redis.getMaxWaitMillis()); + } + if (redis.getMinIdle() != null) { + config.setMinIdle(redis.getMinIdle()); + } + config.setTestOnBorrow(true); + config.setTestWhileIdle(true); + + return new JedisPool(config, redis.getHost(), redis.getPort(), redis.getTimeout(), redis.getPassword(), + redis.getDatabase()); + } +} diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java new file mode 100644 index 000000000..88994fcf4 --- /dev/null +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java @@ -0,0 +1,29 @@ +package com.binarywang.solon.wxjava.mp.config.storage; + +import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.noear.solon.annotation.Bean; +import org.noear.solon.annotation.Condition; +import org.noear.solon.annotation.Configuration; + +/** + * @author zhangyl + */ +@Configuration +@Condition( + onProperty = "${" + WxMpProperties.PREFIX + ".config-storage.type:memory} = memory" +) +@RequiredArgsConstructor +public class WxMpInMemoryConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + + @Bean + @Condition(onMissingBean = WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); + config(config, properties); + return config; + } +} diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java new file mode 100644 index 000000000..c1f5ebf0f --- /dev/null +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java @@ -0,0 +1,65 @@ +package com.binarywang.solon.wxjava.mp.config.storage; + +import com.binarywang.solon.wxjava.mp.properties.RedisProperties; +import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpRedissonConfigImpl; +import org.apache.commons.lang3.StringUtils; +import org.noear.solon.annotation.Bean; +import org.noear.solon.annotation.Condition; +import org.noear.solon.annotation.Configuration; +import org.noear.solon.core.AppContext; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.redisson.config.TransportMode; + +/** + * @author zhangyl + */ +@Configuration +@Condition( + onProperty = "${" + WxMpProperties.PREFIX + ".config-storage.type} = redisson", + onClass = Redisson.class +) +@RequiredArgsConstructor +public class WxMpInRedissonConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + private final AppContext applicationContext; + + @Bean + @Condition(onMissingBean = WxMpConfigStorage.class) + public WxMpConfigStorage wxMaConfig() { + WxMpRedissonConfigImpl config = getWxMpInRedissonConfigStorage(); + return this.config(config, properties); + } + + private WxMpRedissonConfigImpl getWxMpInRedissonConfigStorage() { + RedisProperties redisProperties = properties.getConfigStorage().getRedis(); + RedissonClient redissonClient; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + redissonClient = applicationContext.getBean("wxMpRedissonClient"); + } else { + redissonClient = applicationContext.getBean(RedissonClient.class); + } + return new WxMpRedissonConfigImpl(redissonClient, properties.getConfigStorage().getKeyPrefix()); + } + + @Bean + @Condition(onProperty = "${" + WxMpProperties.PREFIX + ".config-storage.redis.host}") + public RedissonClient wxMpRedissonClient() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + Config config = new Config(); + config.useSingleServer() + .setAddress("redis://" + redis.getHost() + ":" + redis.getPort()) + .setDatabase(redis.getDatabase()); + if (StringUtils.isNotBlank(redis.getPassword())) { + config.useSingleServer().setPassword(redis.getPassword()); + } + config.setTransportMode(TransportMode.NIO); + return Redisson.create(config); + } +} diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/integration/WxMpPluginImpl.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/integration/WxMpPluginImpl.java index 3368d3426..285d871f2 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/integration/WxMpPluginImpl.java +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/integration/WxMpPluginImpl.java @@ -1,10 +1,13 @@ package com.binarywang.solon.wxjava.mp.integration; import com.binarywang.solon.wxjava.mp.config.WxMpServiceAutoConfiguration; -import com.binarywang.solon.wxjava.mp.config.WxMpStorageAutoConfiguration; +import com.binarywang.solon.wxjava.mp.config.storage.WxMpInJedisConfigStorageConfiguration; +import com.binarywang.solon.wxjava.mp.config.storage.WxMpInMemoryConfigStorageConfiguration; +import com.binarywang.solon.wxjava.mp.config.storage.WxMpInRedissonConfigStorageConfiguration; import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; import org.noear.solon.core.AppContext; import org.noear.solon.core.Plugin; +import org.noear.solon.core.util.ClassUtil; /** * @author noear 2024/9/2 created @@ -13,8 +16,14 @@ public class WxMpPluginImpl implements Plugin { @Override public void start(AppContext context) throws Throwable { context.beanMake(WxMpProperties.class); - - context.beanMake(WxMpStorageAutoConfiguration.class); context.beanMake(WxMpServiceAutoConfiguration.class); + + context.beanMake(WxMpInMemoryConfigStorageConfiguration.class); + if (ClassUtil.loadClass("redis.clients.jedis.Jedis") != null) { + context.beanMake(WxMpInJedisConfigStorageConfiguration.class); + } + if (ClassUtil.loadClass("org.redisson.api.RedissonClient") != null) { + context.beanMake(WxMpInRedissonConfigStorageConfiguration.class); + } } } 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 273364c9a..38e484b45 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 @@ -22,7 +22,7 @@ redis.clients jedis - compile + provided org.springframework.data @@ -44,6 +44,11 @@ httpclient5 provided + + org.redisson + redisson + provided + 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 4c0938454..cab3cb17b 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 @@ -1,175 +1,26 @@ package com.binarywang.spring.starter.wxjava.mp.config; -import com.binarywang.spring.starter.wxjava.mp.enums.StorageType; -import com.binarywang.spring.starter.wxjava.mp.properties.RedisProperties; -import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; -import com.google.common.collect.Sets; +import com.binarywang.spring.starter.wxjava.mp.config.storage.WxMpInJedisConfigStorageConfiguration; +import com.binarywang.spring.starter.wxjava.mp.config.storage.WxMpInMemoryConfigStorageConfiguration; +import com.binarywang.spring.starter.wxjava.mp.config.storage.WxMpInRedisTemplateConfigStorageConfiguration; +import com.binarywang.spring.starter.wxjava.mp.config.storage.WxMpInRedissonConfigStorageConfiguration; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.redis.JedisWxRedisOps; -import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; -import me.chanjar.weixin.common.redis.WxRedisOps; -import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; -import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; -import me.chanjar.weixin.mp.config.WxMpConfigStorage; -import me.chanjar.weixin.mp.config.WxMpHostConfig; -import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; -import org.apache.commons.lang3.StringUtils; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.core.StringRedisTemplate; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.JedisSentinelPool; -import redis.clients.jedis.util.Pool; - -import java.util.Set; +import org.springframework.context.annotation.Import; /** * 微信公众号存储策略自动配置. * * @author Luo */ -@Slf4j @Configuration +@Import({ + WxMpInMemoryConfigStorageConfiguration.class, + WxMpInJedisConfigStorageConfiguration.class, + WxMpInRedisTemplateConfigStorageConfiguration.class, + WxMpInRedissonConfigStorageConfiguration.class +}) @RequiredArgsConstructor public class WxMpStorageAutoConfiguration { - private final ApplicationContext applicationContext; - - private final WxMpProperties wxMpProperties; - - @Bean - @ConditionalOnMissingBean(WxMpConfigStorage.class) - public WxMpConfigStorage wxMpConfigStorage() { - StorageType type = wxMpProperties.getConfigStorage().getType(); - WxMpConfigStorage config; - switch (type) { - case Jedis: - config = jedisConfigStorage(); - break; - case RedisTemplate: - config = redisTemplateConfigStorage(); - break; - default: - config = defaultConfigStorage(); - break; - } - // wx host config - if (null != wxMpProperties.getHosts() && StringUtils.isNotEmpty(wxMpProperties.getHosts().getApiHost())) { - WxMpHostConfig hostConfig = new WxMpHostConfig(); - hostConfig.setApiHost(wxMpProperties.getHosts().getApiHost()); - hostConfig.setMpHost(wxMpProperties.getHosts().getMpHost()); - hostConfig.setOpenHost(wxMpProperties.getHosts().getOpenHost()); - config.setHostConfig(hostConfig); - } - return config; - } - - private WxMpConfigStorage defaultConfigStorage() { - WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); - setWxMpInfo(config); - return config; - } - - private WxMpConfigStorage jedisConfigStorage() { - Pool jedisPool; - if (wxMpProperties.getConfigStorage() != null && wxMpProperties.getConfigStorage().getRedis() != null - && StringUtils.isNotEmpty(wxMpProperties.getConfigStorage().getRedis().getHost())) { - jedisPool = getJedisPool(); - } else { - jedisPool = applicationContext.getBean(JedisPool.class); - } - WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); - WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, - wxMpProperties.getConfigStorage().getKeyPrefix()); - setWxMpInfo(wxMpRedisConfig); - return wxMpRedisConfig; - } - - private WxMpConfigStorage redisTemplateConfigStorage() { - StringRedisTemplate redisTemplate = null; - try { - redisTemplate = applicationContext.getBean(StringRedisTemplate.class); - } catch (Exception e) { - log.error(e.getMessage(), e); - } - try { - if (null == redisTemplate) { - redisTemplate = (StringRedisTemplate) applicationContext.getBean("stringRedisTemplate"); - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } - - if (null == redisTemplate) { - redisTemplate = (StringRedisTemplate) applicationContext.getBean("redisTemplate"); - } - - WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate); - WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, - wxMpProperties.getConfigStorage().getKeyPrefix()); - - setWxMpInfo(wxMpRedisConfig); - return wxMpRedisConfig; - } - - private void setWxMpInfo(WxMpDefaultConfigImpl config) { - WxMpProperties properties = wxMpProperties; - WxMpProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); - config.setAppId(properties.getAppId()); - config.setSecret(properties.getSecret()); - config.setToken(properties.getToken()); - config.setAesKey(properties.getAesKey()); - WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); - // 设置自定义的HttpClient超时配置 - ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); - if (clientBuilder == null) { - clientBuilder = DefaultApacheHttpClientBuilder.get(); - } - if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { - DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; - defaultBuilder.setConnectionTimeout(storage.getConnectionTimeout()); - defaultBuilder.setSoTimeout(storage.getSoTimeout()); - defaultBuilder.setConnectionRequestTimeout(storage.getConnectionRequestTimeout()); - config.setApacheHttpClientBuilder(defaultBuilder); - } - config.setUseStableAccessToken(wxMpProperties.isUseStableAccessToken()); - config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); - config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); - config.setHttpProxyPassword(configStorageProperties.getHttpProxyPassword()); - if (configStorageProperties.getHttpProxyPort() != null) { - config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); - } - } - - private Pool getJedisPool() { - RedisProperties redis = wxMpProperties.getConfigStorage().getRedis(); - - JedisPoolConfig config = new JedisPoolConfig(); - if (redis.getMaxActive() != null) { - config.setMaxTotal(redis.getMaxActive()); - } - if (redis.getMaxIdle() != null) { - config.setMaxIdle(redis.getMaxIdle()); - } - if (redis.getMaxWaitMillis() != null) { - config.setMaxWaitMillis(redis.getMaxWaitMillis()); - } - if (redis.getMinIdle() != null) { - config.setMinIdle(redis.getMinIdle()); - } - config.setTestOnBorrow(true); - config.setTestWhileIdle(true); - if (StringUtils.isNotEmpty(redis.getSentinelIps())) { - Set sentinels = Sets.newHashSet(redis.getSentinelIps().split(",")); - return new JedisSentinelPool(redis.getSentinelName(), sentinels); - } - return new JedisPool(config, redis.getHost(), redis.getPort(), redis.getTimeout(), redis.getPassword(), - redis.getDatabase()); - } } diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java new file mode 100644 index 000000000..e39a8bf4d --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/AbstractWxMpConfigStorageConfiguration.java @@ -0,0 +1,54 @@ +package com.binarywang.spring.starter.wxjava.mp.config.storage; + +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import me.chanjar.weixin.mp.config.WxMpHostConfig; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.apache.commons.lang3.StringUtils; + +/** + * @author zhangyl + */ +public abstract class AbstractWxMpConfigStorageConfiguration { + + protected WxMpDefaultConfigImpl config(WxMpDefaultConfigImpl config, WxMpProperties properties) { + config.setAppId(properties.getAppId()); + config.setSecret(properties.getSecret()); + config.setToken(properties.getToken()); + config.setAesKey(properties.getAesKey()); + config.setUseStableAccessToken(properties.isUseStableAccessToken()); + + WxMpProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); + config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); + config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); + config.setHttpProxyPassword(configStorageProperties.getHttpProxyPassword()); + if (configStorageProperties.getHttpProxyPort() != null) { + config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); + } + + // 设置自定义的 HttpClient 超时配置 + ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); + if (clientBuilder == null) { + clientBuilder = DefaultApacheHttpClientBuilder.get(); + } + if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { + DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; + defaultBuilder.setConnectionTimeout(configStorageProperties.getConnectionTimeout()); + defaultBuilder.setSoTimeout(configStorageProperties.getSoTimeout()); + defaultBuilder.setConnectionRequestTimeout(configStorageProperties.getConnectionRequestTimeout()); + config.setApacheHttpClientBuilder(defaultBuilder); + } + + // wx host config + if (null != properties.getHosts() && StringUtils.isNotEmpty(properties.getHosts().getApiHost())) { + WxMpHostConfig hostConfig = new WxMpHostConfig(); + hostConfig.setApiHost(properties.getHosts().getApiHost()); + hostConfig.setOpenHost(properties.getHosts().getOpenHost()); + hostConfig.setMpHost(properties.getHosts().getMpHost()); + config.setHostConfig(hostConfig); + } + + return config; + } +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java new file mode 100644 index 000000000..c21418a6f --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInJedisConfigStorageConfiguration.java @@ -0,0 +1,80 @@ +package com.binarywang.spring.starter.wxjava.mp.config.storage; + +import com.binarywang.spring.starter.wxjava.mp.properties.RedisProperties; +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +/** + * @author zhangyl + */ +@Configuration +@ConditionalOnProperty( + prefix = WxMpProperties.PREFIX + ".config-storage", + name = "type", + havingValue = "jedis" +) +@ConditionalOnClass(Jedis.class) +@RequiredArgsConstructor +public class WxMpInJedisConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + private final ApplicationContext applicationContext; + + @Bean + @ConditionalOnMissingBean(WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpRedisConfigImpl config = getWxMpRedisConfigImpl(); + return this.config(config, properties); + } + + private WxMpRedisConfigImpl getWxMpRedisConfigImpl() { + RedisProperties redisProperties = properties.getConfigStorage().getRedis(); + JedisPool jedisPool; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + jedisPool = applicationContext.getBean("wxMpJedisPool", JedisPool.class); + } else { + jedisPool = applicationContext.getBean(JedisPool.class); + } + WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); + return new WxMpRedisConfigImpl(redisOps, properties.getConfigStorage().getKeyPrefix()); + } + + @Bean + @ConditionalOnProperty(prefix = WxMpProperties.PREFIX + ".config-storage.redis", name = "host") + public JedisPool wxMpJedisPool() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + JedisPoolConfig config = new JedisPoolConfig(); + if (redis.getMaxActive() != null) { + config.setMaxTotal(redis.getMaxActive()); + } + if (redis.getMaxIdle() != null) { + config.setMaxIdle(redis.getMaxIdle()); + } + if (redis.getMaxWaitMillis() != null) { + config.setMaxWaitMillis(redis.getMaxWaitMillis()); + } + if (redis.getMinIdle() != null) { + config.setMinIdle(redis.getMinIdle()); + } + config.setTestOnBorrow(true); + config.setTestWhileIdle(true); + + return new JedisPool(config, redis.getHost(), redis.getPort(), redis.getTimeout(), redis.getPassword(), + redis.getDatabase()); + } +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java new file mode 100644 index 000000000..16eada73a --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInMemoryConfigStorageConfiguration.java @@ -0,0 +1,33 @@ +package com.binarywang.spring.starter.wxjava.mp.config.storage; + +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author zhangyl + */ +@Configuration +@ConditionalOnProperty( + prefix = WxMpProperties.PREFIX + ".config-storage", + name = "type", + havingValue = "memory", + matchIfMissing = true +) +@RequiredArgsConstructor +public class WxMpInMemoryConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + + @Bean + @ConditionalOnMissingBean(WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); + config(config, properties); + return config; + } +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedisTemplateConfigStorageConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedisTemplateConfigStorageConfiguration.java new file mode 100644 index 000000000..0305ca4f8 --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedisTemplateConfigStorageConfiguration.java @@ -0,0 +1,46 @@ +package com.binarywang.spring.starter.wxjava.mp.config.storage; + +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.StringRedisTemplate; + +/** + * @author zhangyl + */ +@Slf4j +@Configuration +@ConditionalOnProperty( + prefix = WxMpProperties.PREFIX + ".config-storage", + name = "type", + havingValue = "redistemplate" +) +@ConditionalOnClass(StringRedisTemplate.class) +@RequiredArgsConstructor +public class WxMpInRedisTemplateConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + private final ApplicationContext applicationContext; + + @Bean + @ConditionalOnMissingBean(WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpRedisConfigImpl config = getWxMpInRedisTemplateConfigStorage(); + return this.config(config, properties); + } + + private WxMpRedisConfigImpl getWxMpInRedisTemplateConfigStorage() { + StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class); + WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate); + return new WxMpRedisConfigImpl(redisOps, properties.getConfigStorage().getKeyPrefix()); + } +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java new file mode 100644 index 000000000..75b736f53 --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/storage/WxMpInRedissonConfigStorageConfiguration.java @@ -0,0 +1,69 @@ +package com.binarywang.spring.starter.wxjava.mp.config.storage; + +import com.binarywang.spring.starter.wxjava.mp.properties.RedisProperties; +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpRedissonConfigImpl; +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.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author zhangyl + */ +@Configuration +@ConditionalOnProperty( + prefix = WxMpProperties.PREFIX + ".config-storage", + name = "type", + havingValue = "redisson" +) +@ConditionalOnClass({Redisson.class, RedissonClient.class}) +@RequiredArgsConstructor +public class WxMpInRedissonConfigStorageConfiguration extends AbstractWxMpConfigStorageConfiguration { + private final WxMpProperties properties; + private final ApplicationContext applicationContext; + + @Bean + @ConditionalOnMissingBean(WxMpConfigStorage.class) + public WxMpConfigStorage wxMpConfigStorage() { + WxMpRedissonConfigImpl config = getWxMpInRedissonConfigStorage(); + return this.config(config, properties); + } + + private WxMpRedissonConfigImpl getWxMpInRedissonConfigStorage() { + RedisProperties redisProperties = properties.getConfigStorage().getRedis(); + RedissonClient redissonClient; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + redissonClient = applicationContext.getBean("wxMpRedissonClient", RedissonClient.class); + } else { + redissonClient = applicationContext.getBean(RedissonClient.class); + } + return new WxMpRedissonConfigImpl(redissonClient, properties.getConfigStorage().getKeyPrefix()); + } + + @Bean + @ConditionalOnProperty(prefix = WxMpProperties.PREFIX + ".config-storage.redis", name = "host") + public RedissonClient wxMpRedissonClient() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + Config config = new Config(); + config.useSingleServer() + .setAddress("redis://" + redis.getHost() + ":" + redis.getPort()) + .setDatabase(redis.getDatabase()); + if (StringUtils.isNotBlank(redis.getPassword())) { + config.useSingleServer().setPassword(redis.getPassword()); + } + config.setTransportMode(TransportMode.NIO); + return Redisson.create(config); + } +} From 2c5a33917e7991543a1469ef08bcf64a88cae243 Mon Sep 17 00:00:00 2001 From: buaazyl Date: Thu, 8 Jan 2026 15:08:58 +0800 Subject: [PATCH 08/33] =?UTF-8?q?:art:=20#3834=20=E3=80=90=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=9E=B6=E6=9E=84=E3=80=91=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=92=8C=E5=BC=80=E6=94=BE=E5=B9=B3=E5=8F=B0=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E8=A1=A5=E5=85=85=E4=BA=86=20Apache=20HttpCl?= =?UTF-8?q?ient=205.x=20=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E5=B9=B6=E5=B0=86=E5=A4=9A=E4=B8=AA=E6=A8=A1=E5=9D=97=E7=9A=84?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=9C=8D=E5=8A=A1=E5=AE=9E=E7=8E=B0=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E8=87=B3=20Apache=20HttpClient=205.x=20=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HTTPCLIENT_UPGRADE_GUIDE.md | 6 +- .../properties/WxChannelMultiProperties.java | 2 +- .../properties/WxCpMultiProperties.java | 2 +- .../services/AbstractWxMaConfiguration.java | 4 + .../properties/WxMaMultiProperties.java | 8 +- .../config/WxMaServiceAutoConfiguration.java | 4 + .../miniapp/properties/WxMaProperties.java | 2 +- .../services/AbstractWxMpConfiguration.java | 4 + .../properties/WxMpMultiProperties.java | 8 +- .../config/WxMpServiceAutoConfiguration.java | 8 ++ .../WxQidianServiceAutoConfiguration.java | 8 ++ .../config/WxMaServiceAutoConfiguration.java | 4 + .../miniapp/properties/WxMaProperties.java | 2 +- .../api/impl/WxChannelServiceImpl.java | 2 +- .../impl/WxMaServiceHttpComponentsImpl.java | 101 ++++++++++++++++++ .../wx/miniapp/api/impl/WxMaServiceImpl.java | 2 +- .../weixin/mp/api/impl/WxMpServiceImpl.java | 4 +- .../impl/WxOpenServiceHttpComponentsImpl.java | 74 +++++++++++++ .../open/api/impl/WxOpenServiceImpl.java | 2 +- .../wxpay/service/impl/WxPayServiceImpl.java | 4 +- .../qidian/api/impl/WxQidianServiceImpl.java | 4 +- 21 files changed, 233 insertions(+), 22 deletions(-) create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceHttpComponentsImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceHttpComponentsImpl.java diff --git a/docs/HTTPCLIENT_UPGRADE_GUIDE.md b/docs/HTTPCLIENT_UPGRADE_GUIDE.md index 08726fa03..945341966 100644 --- a/docs/HTTPCLIENT_UPGRADE_GUIDE.md +++ b/docs/HTTPCLIENT_UPGRADE_GUIDE.md @@ -28,12 +28,11 @@ | weixin-java-cp(企业微信) | ⚠️ 视集成方式而定 | 参考对应 starter 配置 | | weixin-java-channel(视频号) | ✅ 是 | HttpComponents (5.x) | | weixin-java-qidian(企点) | ✅ 是 | HttpComponents (5.x) | -| weixin-java-miniapp(小程序) | ✅ 是 | HttpClient (4.x) | +| weixin-java-miniapp(小程序) | ✅ 是 | HttpComponents (5.x) | | weixin-java-pay(支付) | ✅ 是 | HttpComponents (5.x) | | weixin-java-open(开放平台) | ✅ 是 | HttpComponents (5.x) | **注意**: -- **weixin-java-miniapp 模块**已在核心 SDK 中提供 HttpClient 5.x(`HttpComponents`)支持,但默认仍使用 HttpClient 4.x(`HttpClient`)。如需启用 HttpClient 5.x,可通过配置 `http-client-type=HttpComponents` 显式指定。 - **weixin-java-cp 模块**的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档。 ## 对现有项目的影响 @@ -97,9 +96,6 @@ A: 不会。项目保持完全向后兼容,HttpClient 4.x 的所有实现都 ### Q: 我需要修改代码吗? A: 大多数情况下不需要。如果希望继续使用 HttpClient 4.x,只需在配置中指定 `http-client-type=HttpClient` 即可。 -### Q: MiniApp 模块支持 HttpClient 5.x 吗? -A: 支持。MiniApp 模块在核心 SDK 中已经提供了基于 HttpClient 5.x(`HttpComponents`)的支持,但默认仍会使用 HttpClient 4.x(`HttpClient`)以保持向后兼容。如果你使用的是框架集成(例如 Spring Boot Starter 或 Solon Plugin),可以通过显式配置 `http-client-type=HttpComponents` 来启用 HttpClient 5.x。 - ### Q: 我可以在同一个项目中同时使用两个版本吗? A: 可以。不同的模块可以配置使用不同的 HTTP 客户端。例如,MP 模块使用 HttpClient 5.x,MiniApp 模块默认使用 HttpClient 4.x,但也可以按需配置为 HttpClient 5.x。 diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiProperties.java b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiProperties.java index 2e2da1add..ca99e522b 100644 --- a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiProperties.java +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiProperties.java @@ -55,7 +55,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HTTP_CLIENT; + private HttpClientType httpClientType = HttpClientType.HTTP_COMPONENTS; /** * http代理主机. diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiProperties.java b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiProperties.java index 821f885f9..2d4bffae6 100644 --- a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiProperties.java +++ b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiProperties.java @@ -52,7 +52,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HTTP_CLIENT; + private HttpClientType httpClientType = HttpClientType.HTTP_COMPONENTS; /** * http代理主机 diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/configuration/services/AbstractWxMaConfiguration.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/configuration/services/AbstractWxMaConfiguration.java index fd94200e5..8ad85c96b 100644 --- a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/configuration/services/AbstractWxMaConfiguration.java +++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/configuration/services/AbstractWxMaConfiguration.java @@ -2,6 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpClientImpl; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpComponentsImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceJoddHttpImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl; @@ -89,6 +90,9 @@ public WxMaService wxMaService(WxMaConfig wxMaConfig, WxMaMultiProperties wxMaMu case HTTP_CLIENT: wxMaService = new WxMaServiceHttpClientImpl(); break; + case HTTP_COMPONENTS: + wxMaService = new WxMaServiceHttpComponentsImpl(); + break; default: wxMaService = new WxMaServiceImpl(); break; diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiProperties.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiProperties.java index 87fcd42f0..f99d6280e 100644 --- a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiProperties.java +++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiProperties.java @@ -77,7 +77,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HTTP_CLIENT; + private HttpClientType httpClientType = HttpClientType.HTTP_COMPONENTS; /** * http代理主机. @@ -149,6 +149,10 @@ public enum HttpClientType { /** * JoddHttp */ - JODD_HTTP + JODD_HTTP, + /** + * HttpComponents + */ + HTTP_COMPONENTS } } diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java index 5463ec08e..78f95380b 100644 --- a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java +++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java @@ -2,6 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpClientImpl; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpComponentsImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceJoddHttpImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl; @@ -44,6 +45,9 @@ public WxMaService wxMaService(WxMaConfig wxMaConfig) { case HttpClient: wxMaService = new WxMaServiceHttpClientImpl(); break; + case HttpComponents: + wxMaService = new WxMaServiceHttpComponentsImpl(); + break; default: wxMaService = new WxMaServiceImpl(); break; diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaProperties.java b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaProperties.java index 1c3e495f4..4493b6aec 100644 --- a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaProperties.java +++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaProperties.java @@ -76,7 +76,7 @@ public static class ConfigStorage { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/configuration/services/AbstractWxMpConfiguration.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/configuration/services/AbstractWxMpConfiguration.java index d534b9874..a51c6eaae 100644 --- a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/configuration/services/AbstractWxMpConfiguration.java +++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/configuration/services/AbstractWxMpConfiguration.java @@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; +import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpComponentsImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceJoddHttpImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl; @@ -91,6 +92,9 @@ public WxMpService wxMpService(WxMpConfigStorage configStorage, WxMpMultiPropert case HTTP_CLIENT: wxMpService = new WxMpServiceHttpClientImpl(); break; + case HTTP_COMPONENTS: + wxMpService = new WxMpServiceHttpComponentsImpl(); + break; default: wxMpService = new WxMpServiceImpl(); break; diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiProperties.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiProperties.java index 1929e9260..3d47f7138 100644 --- a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiProperties.java +++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiProperties.java @@ -77,7 +77,7 @@ public static class ConfigStorage implements Serializable { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HTTP_CLIENT; + private HttpClientType httpClientType = HttpClientType.HTTP_COMPONENTS; /** * http代理主机. @@ -149,6 +149,10 @@ public enum HttpClientType { /** * JoddHttp */ - JODD_HTTP + JODD_HTTP, + /** + * HttpComponents + */ + HTTP_COMPONENTS } } diff --git a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpServiceAutoConfiguration.java b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpServiceAutoConfiguration.java index 3e7a59849..334ccf7ab 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpServiceAutoConfiguration.java +++ b/solon-plugins/wx-java-mp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp/config/WxMpServiceAutoConfiguration.java @@ -4,6 +4,7 @@ import com.binarywang.solon.wxjava.mp.properties.WxMpProperties; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; +import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpComponentsImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceJoddHttpImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl; @@ -35,6 +36,9 @@ public WxMpService wxMpService(WxMpConfigStorage configStorage, WxMpProperties w case HttpClient: wxMpService = newWxMpServiceHttpClientImpl(); break; + case HttpComponents: + wxMpService = newWxMpServiceHttpComponentsImpl(); + break; default: wxMpService = newWxMpServiceImpl(); break; @@ -60,4 +64,8 @@ private WxMpService newWxMpServiceJoddHttpImpl() { return new WxMpServiceJoddHttpImpl(); } + private WxMpService newWxMpServiceHttpComponentsImpl() { + return new WxMpServiceHttpComponentsImpl(); + } + } diff --git a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/config/WxQidianServiceAutoConfiguration.java b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/config/WxQidianServiceAutoConfiguration.java index f3dce59a7..02ec06cd2 100644 --- a/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/config/WxQidianServiceAutoConfiguration.java +++ b/solon-plugins/wx-java-qidian-solon-plugin/src/main/java/com/binarywang/solon/wxjava/qidian/config/WxQidianServiceAutoConfiguration.java @@ -4,6 +4,7 @@ import com.binarywang.solon.wxjava.qidian.properties.WxQidianProperties; import me.chanjar.weixin.qidian.api.WxQidianService; import me.chanjar.weixin.qidian.api.impl.WxQidianServiceHttpClientImpl; +import me.chanjar.weixin.qidian.api.impl.WxQidianServiceHttpComponentsImpl; import me.chanjar.weixin.qidian.api.impl.WxQidianServiceImpl; import me.chanjar.weixin.qidian.api.impl.WxQidianServiceJoddHttpImpl; import me.chanjar.weixin.qidian.api.impl.WxQidianServiceOkHttpImpl; @@ -35,6 +36,9 @@ public WxQidianService wxQidianService(WxQidianConfigStorage configStorage, WxQi case HttpClient: wxQidianService = newWxQidianServiceHttpClientImpl(); break; + case HttpComponents: + wxQidianService = newWxQidianServiceHttpComponentsImpl(); + break; default: wxQidianService = newWxQidianServiceImpl(); break; @@ -60,4 +64,8 @@ private WxQidianService newWxQidianServiceJoddHttpImpl() { return new WxQidianServiceJoddHttpImpl(); } + private WxQidianService newWxQidianServiceHttpComponentsImpl() { + return new WxQidianServiceHttpComponentsImpl(); + } + } diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java index 79c16fb05..f03d3f149 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaServiceAutoConfiguration.java @@ -2,6 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpClientImpl; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpComponentsImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceJoddHttpImpl; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl; @@ -46,6 +47,9 @@ public WxMaService wxMaService(WxMaConfig wxMaConfig) { case HttpClient: wxMaService = new WxMaServiceHttpClientImpl(); break; + case HttpComponents: + wxMaService = new WxMaServiceHttpComponentsImpl(); + break; default: wxMaService = new WxMaServiceImpl(); break; diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java index 7e88db904..82f150094 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java @@ -88,7 +88,7 @@ public static class ConfigStorage { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.HttpClient; + private HttpClientType httpClientType = HttpClientType.HttpComponents; /** * http代理主机. diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java index 6f2c349f3..ccd4eafc7 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java @@ -8,7 +8,7 @@ * @author Zeyes */ @Slf4j -public class WxChannelServiceImpl extends WxChannelServiceHttpClientImpl { +public class WxChannelServiceImpl extends WxChannelServiceHttpComponentsImpl { public WxChannelServiceImpl() { } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceHttpComponentsImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceHttpComponentsImpl.java new file mode 100644 index 000000000..526e1ec4e --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceHttpComponentsImpl.java @@ -0,0 +1,101 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.bean.WxMaStableAccessTokenRequest; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.util.http.HttpClientType; +import me.chanjar.weixin.common.util.http.hc.BasicResponseHandler; +import me.chanjar.weixin.common.util.http.hc.DefaultHttpComponentsClientBuilder; +import me.chanjar.weixin.common.util.http.hc.HttpComponentsClientBuilder; +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.io.entity.StringEntity; + +import java.io.IOException; + +/** + * Apache Http client5 方式实现 + * + * @author zhangyl + */ +@Slf4j +public class WxMaServiceHttpComponentsImpl extends BaseWxMaServiceImpl { + private CloseableHttpClient httpClient; + private HttpHost httpProxy; + + @Override + public void initHttp() { + WxMaConfig configStorage = this.getWxMaConfig(); + HttpComponentsClientBuilder apacheHttpClientBuilder = DefaultHttpComponentsClientBuilder.get(); + + apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword() == null ? null : + configStorage.getHttpProxyPassword().toCharArray()); + + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); + } + + this.httpClient = apacheHttpClientBuilder.build(); + } + + @Override + public CloseableHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public HttpHost getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpClientType getRequestType() { + return HttpClientType.HTTP_COMPONENTS; + } + + @Override + protected String doGetAccessTokenRequest() throws IOException { + String url = StringUtils.isNotEmpty(this.getWxMaConfig().getAccessTokenUrl()) ? + this.getWxMaConfig().getAccessTokenUrl() : + GET_ACCESS_TOKEN_URL.replace(WxMaConfig.DEFAULT_API_HOST_URL, this.getWxMaConfig().getEffectiveApiHostUrl()); + + url = String.format(url, this.getWxMaConfig().getAppid(), this.getWxMaConfig().getSecret()); + + HttpGet httpGet = new HttpGet(url); + if (this.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build(); + httpGet.setConfig(config); + } + return getRequestHttpClient().execute(httpGet, BasicResponseHandler.INSTANCE); + } + + @Override + protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException { + String url = StringUtils.isNotEmpty(this.getWxMaConfig().getAccessTokenUrl()) ? + this.getWxMaConfig().getAccessTokenUrl() : + GET_STABLE_ACCESS_TOKEN.replace( + WxMaConfig.DEFAULT_API_HOST_URL, this.getWxMaConfig().getEffectiveApiHostUrl()); + + HttpPost httpPost = new HttpPost(url); + if (this.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + WxMaStableAccessTokenRequest wxMaAccessTokenRequest = new WxMaStableAccessTokenRequest(); + wxMaAccessTokenRequest.setAppid(this.getWxMaConfig().getAppid()); + wxMaAccessTokenRequest.setSecret(this.getWxMaConfig().getSecret()); + wxMaAccessTokenRequest.setGrantType("client_credential"); + wxMaAccessTokenRequest.setForceRefresh(forceRefresh); + + httpPost.setEntity(new StringEntity(wxMaAccessTokenRequest.toJson(), ContentType.APPLICATION_JSON)); + return getRequestHttpClient().execute(httpPost, BasicResponseHandler.INSTANCE); + } +} 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 16478f841..d0820a0c2 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 @@ -6,6 +6,6 @@ * @author Binary Wang */ @Slf4j -public class WxMaServiceImpl extends WxMaServiceHttpClientImpl { +public class WxMaServiceImpl extends WxMaServiceHttpComponentsImpl { } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java index 79c3fad26..7cef64e57 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java @@ -2,11 +2,11 @@ /** *
          - * 默认接口实现类,使用apache httpclient实现
          + * 默认接口实现类,使用apache httpClient 5实现
            * Created by Binary Wang on 2017-5-27.
            * 
          * * @author Binary Wang */ -public class WxMpServiceImpl extends WxMpServiceHttpClientImpl { +public class WxMpServiceImpl extends WxMpServiceHttpComponentsImpl { } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceHttpComponentsImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceHttpComponentsImpl.java new file mode 100644 index 000000000..913c1971c --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceHttpComponentsImpl.java @@ -0,0 +1,74 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadResult; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpClientType; +import me.chanjar.weixin.common.util.http.MinishopUploadRequestExecutor; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.http.hc.DefaultHttpComponentsClientBuilder; +import me.chanjar.weixin.common.util.http.hc.HttpComponentsClientBuilder; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.core5.http.HttpHost; + +import java.io.File; + +/** + * httpclient 5 实现 + * + * @author zhangyl + */ +public class WxOpenServiceHttpComponentsImpl extends WxOpenServiceAbstractImpl { + private CloseableHttpClient httpClient; + private HttpHost httpProxy; + + @Override + public void initHttp() { + WxOpenConfigStorage configStorage = this.getWxOpenConfigStorage(); + HttpComponentsClientBuilder apacheHttpClientBuilder = DefaultHttpComponentsClientBuilder.get(); + + apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword() == null ? null : + configStorage.getHttpProxyPassword().toCharArray()); + + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); + } + + this.httpClient = apacheHttpClientBuilder.build(); + + } + + @Override + public CloseableHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public HttpHost getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpClientType getRequestType() { + return HttpClientType.HTTP_COMPONENTS; + } + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } + + @Override + public WxMinishopImageUploadResult uploadMinishopMediaFile(String url, File file) throws WxErrorException { + return execute(MinishopUploadRequestExecutor.create(this), url, file); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java index c807ccdf9..83e831df7 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java @@ -3,6 +3,6 @@ /** * @author 007 */ -public class WxOpenServiceImpl extends WxOpenServiceApacheHttpClientImpl { +public class WxOpenServiceImpl extends WxOpenServiceHttpComponentsImpl { } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index 8e795966f..4316bafa4 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -2,11 +2,11 @@ /** *
          - * 微信支付接口请求实现类,默认使用Apache HttpClient实现
          + * 微信支付接口请求实现类,默认使用Apache HttpClient 5实现
            * Created by Binary Wang on 2017-7-8.
            * 
          * * @author Binary Wang */ -public class WxPayServiceImpl extends WxPayServiceApacheHttpImpl { +public class WxPayServiceImpl extends WxPayServiceHttpComponentsImpl { } diff --git a/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceImpl.java b/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceImpl.java index 45e87204c..2e1314b3b 100644 --- a/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceImpl.java +++ b/weixin-java-qidian/src/main/java/me/chanjar/weixin/qidian/api/impl/WxQidianServiceImpl.java @@ -2,11 +2,11 @@ /** *
          - * 默认接口实现类,使用apache httpclient实现
          + * 默认接口实现类,使用apache httpClient 5实现
            * Created by Binary Wang on 2017-5-27.
            * 
          * * @author Binary Wang */ -public class WxQidianServiceImpl extends WxQidianServiceHttpClientImpl { +public class WxQidianServiceImpl extends WxQidianServiceHttpComponentsImpl { } From 72fa3b3301967c29031fabdad1574951a19b1c48 Mon Sep 17 00:00:00 2001 From: buaazyl Date: Fri, 9 Jan 2026 14:16:06 +0800 Subject: [PATCH 09/33] =?UTF-8?q?:art:=20#3838=20=E3=80=90=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E3=80=91=E4=B8=BAstarter=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E9=80=80=E6=AC=BE=E7=BB=93=E6=9E=9C=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=20URL=20=E7=9A=84=E9=85=8D=E7=BD=AE=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=8C=E5=85=81=E8=AE=B8=E5=BC=80=E5=8F=91=E8=80=85=E5=9C=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=B8=AD=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=80=80=E6=AC=BE=E9=80=9A=E7=9F=A5=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++------- .../wxjava/pay/config/WxPayAutoConfiguration.java | 1 + .../wxjava/pay/properties/WxPayProperties.java | 5 +++++ .../wxjava/pay/config/WxPayAutoConfiguration.java | 1 + .../wxjava/pay/properties/WxPayProperties.java | 5 +++++ .../wxpay/bean/request/WxPayRefundRequest.java | 4 +++- .../github/binarywang/wxpay/config/WxPayConfig.java | 6 +++++- .../wxpay/service/impl/BaseWxPayServiceImpl.java | 6 ++++++ 8 files changed, 32 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 54af600be..080b831d1 100644 --- a/README.md +++ b/README.md @@ -133,10 +133,10 @@ **Spring Boot 配置示例:** ```properties -# 使用 HttpClient 5.x(推荐,MP/CP/Channel/QiDian 模块默认) +# 使用 HttpClient 5.x(推荐,MP/MiniApp/CP/Channel/QiDian 模块默认) wx.mp.config-storage.http-client-type=HttpComponents -# 使用 HttpClient 4.x(兼容模式,MiniApp 模块默认) +# 使用 HttpClient 4.x(兼容模式) wx.mp.config-storage.http-client-type=HttpClient # 使用 OkHttp @@ -153,11 +153,10 @@ wx.mp.config-storage.http-client-type=HTTP_COMPONENTS # 注意使用大写下 ``` **注意事项:** -1. **MiniApp 模块**已提供 `HttpComponents`(HttpClient 5.x)类型的配置选项,但当前默认仍为 HttpClient 4.x;如需启用 HttpClient 5.x,请确保所使用的集成模块(如 `wx-java-miniapp-spring-boot-starter`、`wx-java-miniapp-solon-plugin`)版本已支持该选项 -2. **MP、Channel、QiDian 模块**已完整支持 HttpClient 5.x,默认推荐使用 -3. **CP 模块**的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档 -4. 如需使用 OkHttp 或 Jodd-http,需在项目中添加对应的依赖(scope为provided) -5. HttpClient 4.x 和 HttpClient 5.x 可以共存,按需配置即可 +1. **MP、MiniApp、Channel、QiDian 模块**已完整支持 HttpClient 5.x,默认推荐使用 +2. **CP 模块**的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档 +3. 如需使用 OkHttp 或 Jodd-http,需在项目中添加对应的依赖(scope为provided) +4. HttpClient 4.x 和 HttpClient 5.x 可以共存,按需配置即可 --------------------------------- diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/config/WxPayAutoConfiguration.java b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/config/WxPayAutoConfiguration.java index 94112c7d9..3ef7456da 100644 --- a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/config/WxPayAutoConfiguration.java +++ b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/config/WxPayAutoConfiguration.java @@ -47,6 +47,7 @@ public WxPayService wxPayService() { payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv()); payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); + payConfig.setRefundNotifyUrl(StringUtils.trimToNull(this.properties.getRefundNotifyUrl())); //以下是apiv3以及支付分相关 payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId())); payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl())); diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java index 0b035e983..d394fefbd 100644 --- a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java +++ b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java @@ -87,6 +87,11 @@ public class WxPayProperties { */ private String notifyUrl; + /** + * 退款结果异步回调地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String refundNotifyUrl; + /** * 微信支付分授权回调地址 */ diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java b/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java index 5a794de7e..758fd929a 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java @@ -51,6 +51,7 @@ public WxPayService wxPayService() { payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv()); payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); + payConfig.setRefundNotifyUrl(StringUtils.trimToNull(this.properties.getRefundNotifyUrl())); //以下是apiv3以及支付分相关 payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId())); payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl())); diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java b/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java index 8212e3b01..25f7d7c02 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java @@ -64,6 +64,11 @@ public class WxPayProperties { */ private String notifyUrl; + /** + * 退款结果异步回调地址,通知url必须为直接可访问的url,不能携带参数 + */ + private String refundNotifyUrl; + /** * 微信支付分回调地址 */ 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 e145644d9..b0cbcf4e7 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 @@ -230,7 +230,9 @@ public void checkAndSign(WxPayConfig config) throws WxPayException { if (StringUtils.isBlank(this.getOpUserId())) { this.setOpUserId(config.getMchId()); } - + if (StringUtils.isBlank(this.getNotifyUrl())) { + this.setNotifyUrl(config.getRefundNotifyUrl()); + } super.checkAndSign(config); } 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 b42451a66..88e544e67 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 @@ -97,9 +97,13 @@ public class WxPayConfig { */ private String subMchId; /** - * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数. + * 微信支付异步回调地址,通知url必须为直接可访问的url,不能携带参数. */ private String notifyUrl; + /** + * 退款结果异步回调地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String refundNotifyUrl; /** * 交易类型. *
          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 2e896cda7..5347099a0 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
          @@ -263,6 +263,9 @@ public WxPayRefundResult refundV2(WxPayRefundRequest request) throws WxPayExcept
           
             @Override
             public WxPayRefundV3Result refundV3(WxPayRefundV3Request request) throws WxPayException {
          +    if (StringUtils.isBlank(request.getNotifyUrl())) {
          +      request.setNotifyUrl(this.getConfig().getRefundNotifyUrl());
          +    }
               String url = String.format("%s/v3/refund/domestic/refunds", this.getPayBaseUrl());
               String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
               return GSON.fromJson(response, WxPayRefundV3Result.class);
          @@ -270,6 +273,9 @@ public WxPayRefundV3Result refundV3(WxPayRefundV3Request request) throws WxPayEx
           
             @Override
             public WxPayRefundV3Result partnerRefundV3(WxPayPartnerRefundV3Request request) throws WxPayException {
          +    if (StringUtils.isBlank(request.getNotifyUrl())) {
          +      request.setNotifyUrl(this.getConfig().getRefundNotifyUrl());
          +    }
               if (StringUtils.isBlank(request.getSubMchid())) {
                 request.setSubMchid(this.getConfig().getSubMchId());
               }
          
          From e27325f58090db4e8801dfb433795668f1fe23bd Mon Sep 17 00:00:00 2001
          From: Noctis_nkt 
          Date: Fri, 9 Jan 2026 14:18:23 +0800
          Subject: [PATCH 10/33] =?UTF-8?q?=E3=80=90=E4=BC=81=E4=B8=9A=E5=BE=AE?=
           =?UTF-8?q?=E4=BF=A1=E3=80=91=E6=96=B0=E5=A2=9E=E7=AE=A1=E7=90=86=E8=A1=A8?=
           =?UTF-8?q?=E6=A0=BC=E5=86=85=E5=AE=B9=E7=9B=B8:new:=20#3837=20=E3=80=90?=
           =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E3=80=91=E5=BE=AE=E6=96=87?=
           =?UTF-8?q?=E6=A1=A3=EF=BC=88WeDoc=EF=BC=89=E6=9C=8D=E5=8A=A1=E6=96=B0?=
           =?UTF-8?q?=E5=A2=9E=E4=BA=86=E4=B8=89=E4=B8=AA=E7=AE=A1=E7=90=86=E8=A1=A8?=
           =?UTF-8?q?=E6=A0=BC=E5=86=85=E5=AE=B9=E7=9A=84=20API=20=E6=8E=A5=E5=8F=A3?=
           =?UTF-8?q?=EF=BC=8C=E5=8C=85=E6=8B=AC=E6=89=B9=E9=87=8F=E6=9B=B4=E6=96=B0?=
           =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=86=85=E5=AE=B9=E3=80=81=E8=8E=B7=E5=8F=96?=
           =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E8=A1=8C=E5=88=97=E4=BF=A1=E6=81=AF=E4=BB=A5?=
           =?UTF-8?q?=E5=8F=8A=E8=8E=B7=E5=8F=96=E6=8C=87=E5=AE=9A=E8=8C=83=E5=9B=B4?=
           =?UTF-8?q?=E7=9A=84=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE?=
          MIME-Version: 1.0
          Content-Type: text/plain; charset=UTF-8
          Content-Transfer-Encoding: 8bit
          
          ---
           .../weixin/cp/api/WxCpOaWeDocService.java     |  49 ++++
           .../cp/api/impl/WxCpOaWeDocServiceImpl.java   |  23 ++
           .../doc/WxCpDocSheetBatchUpdateRequest.java   | 199 ++++++++++++++
           .../doc/WxCpDocSheetBatchUpdateResponse.java  | 126 +++++++++
           .../cp/bean/oa/doc/WxCpDocSheetData.java      | 260 ++++++++++++++++++
           .../oa/doc/WxCpDocSheetGetDataRequest.java    |  64 +++++
           .../bean/oa/doc/WxCpDocSheetProperties.java   |  79 ++++++
           .../weixin/cp/constant/WxCpApiPathConsts.java |  15 +
           8 files changed, 815 insertions(+)
           create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java
           create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java
           create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java
           create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java
           create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java
          
          diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java
          index 1356c839b..d63d32694 100644
          --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java
          +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java
          @@ -78,4 +78,53 @@ public interface WxCpOaWeDocService {
              * @throws WxErrorException the wx error exception
              */
             WxCpDocShare docShare(@NonNull String docId) throws WxErrorException;
          +
          +  /**
          +   * 编辑表格内容
          +   * 该接口可以对一个在线表格批量执行多个更新操作
          +   * 

          + * 注意: + * 1.批量更新请求中的各个操作会逐个按顺序执行,直到全部执行完成则请求返回,或者其中一个操作报错则不再继续执行后续的操作 + * 2.每一个更新操作在执行之前都会做请求校验(包括权限校验、参数校验等等),如果校验未通过则该更新操作会报错并返回,不再执行后续操作 + * 3.单次批量更新请求的操作数量 <= 5 + *

          + * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/batch_update?access_token=ACCESS_TOKEN + * + * @param request 编辑表格内容请求参数 + * @return 编辑表格内容批量更新的响应结果 + * @throws WxErrorException the wx error exception + */ + WxCpDocSheetBatchUpdateResponse docBatchUpdate(@NonNull WxCpDocSheetBatchUpdateRequest request) throws WxErrorException; + + /** + * 获取表格行列信息 + * 该接口用于获取在线表格的工作表、行数、列数等。 + *

          + * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/get_sheet_properties?access_token=ACCESS_TOKEN + * + * @param docId 在线表格的docid + * @return 返回表格行列信息 + * @throws WxErrorException + */ + WxCpDocSheetProperties getSheetProperties(@NonNull String docId) throws WxErrorException; + + + /** + * 本接口用于获取指定范围内的在线表格信息,单次查询的范围大小需满足以下限制: + *

          + * 查询范围行数 <=1000 + * 查询范围列数 <=200 + * 范围内的总单元格数量 <=10000 + *

          + * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/get_sheet_range_data?access_token=ACCESS_TOKEN + * + * @param request 获取指定范围内的在线表格信息请求参数 + * @return 返回指定范围内的在线表格信息 + * @throws WxErrorException + */ + WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest request) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java index 81de32453..fc5379dc7 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java @@ -63,4 +63,27 @@ public WxCpDocShare docShare(@NonNull String docId) throws WxErrorException { String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); return WxCpDocShare.fromJson(responseContent); } + + @Override + public WxCpDocSheetBatchUpdateResponse docBatchUpdate(@NonNull WxCpDocSheetBatchUpdateRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_BATCH_UPDATE); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSheetBatchUpdateResponse.fromJson(responseContent); + } + + @Override + public WxCpDocSheetProperties getSheetProperties(@NonNull String docId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", docId); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpDocSheetProperties.fromJson(responseContent); + } + + @Override + public WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSheetData.fromJson(responseContent); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java new file mode 100644 index 000000000..37c42717e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java @@ -0,0 +1,199 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.bean.oa.doc.WxCpDocSheetData.GridData; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 编辑表格内容请求 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSheetBatchUpdateRequest implements Serializable { + private static final long serialVersionUID = 584565591133421347L; + + /** + * 文档的docid.必填 + */ + @SerializedName("docid") + private String docId; + + /** + * 更新操作列表.必填 + */ + @SerializedName("requests") + private List requests; + + /** + * From json wx cp doc sheet batch update request. + * + * @param json the json + * @return the wx cp doc sheet batch update request + */ + public static WxCpDocSheetBatchUpdateRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetBatchUpdateRequest.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 更新操作 + */ + @Getter + @Setter + public static class Request implements Serializable { + private static final long serialVersionUID = 253933038745894628L; + + /** + * 新增工作表 + */ + @SerializedName("add_sheet_request") + private AddSheetRequest addSheetRequest; + + /** + * 删除工作表请求 + */ + @SerializedName("delete_sheet_request") + private DeleteSheetRequest deleteSheetRequest; + + /** + * 更新范围内单元格内容 + */ + @SerializedName("update_range_request") + private UpdateRangeRequest updateRangeRequest; + + /** + * 删除表格连续的行或列 + */ + @SerializedName("delete_dimension_request") + private DeleteDimensionRequest deleteDimensionRequest; + + /** + * 新增工作表,新增需满足以下限制 + * 范围列数 <=200 + * 范围内的总单元格数量 <=10000 + */ + @Getter + @Setter + public static class AddSheetRequest implements Serializable { + private static final long serialVersionUID = 523704967699486288L; + + /** + * 工作表名称 + */ + @SerializedName("title") + private String title; + + /** + * 新增工作表的初始行数 + */ + @SerializedName("row_count") + private int rowCount; + + /** + * 新增工作表的初始列数 + */ + @SerializedName("column_count") + private int columnCount; + } + + /** + * 删除工作表请求 + */ + @Getter + @Setter + public static class DeleteSheetRequest implements Serializable { + private static final long serialVersionUID = 767974765396168274L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + } + + /** + * 更新范围内单元格内容 + */ + @Getter + @Setter + public static class UpdateRangeRequest implements Serializable { + private static final long serialVersionUID = 433859595039061888L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 表格数据 + */ + @SerializedName("grid_data") + private GridData gridData; + } + + /** + * 删除表格连续的行或列 + * 注意: + * 1.该操作会导致表格缩表 + * 2.删除的范围遵循 左闭右开 ———— [start_index,end_index) ,如果 end_index <= start_index + * 则该请求报错。 + */ + @Getter + @Setter + public static class DeleteDimensionRequest implements Serializable { + private static final long serialVersionUID = 107245521502978033L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 删除的维度类型. + * ROW:行 + * COLUMN:列 + */ + @SerializedName("dimension") + private String dimension; + + /** + * 删除行列的起始序号(从1开始) + */ + @SerializedName("start_index") + private int startIndex; + + /** + * 删除行列的终止序号(从1开始) + */ + @SerializedName("end_index") + private int endIndex; + } + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java new file mode 100644 index 000000000..8e31e9022 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java @@ -0,0 +1,126 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.oa.doc.WxCpDocSheetProperties.Properties; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 更新操作(UpdateRequest])对应的响应结构体类型 + * + * @author zhongying + * @since 2026-01-08 + */ +@Data +public class WxCpDocSheetBatchUpdateResponse implements Serializable { + private static final long serialVersionUID = 781694717017131015L; + + /** + * 新增工作表响应 + */ + @SerializedName("add_sheet_response") + private AddSheetResponse addSheetResponse; + + /** + * 删除工作表响应 + */ + @SerializedName("delete_sheet_response") + private DeleteSheetResponse deleteSheetResponse; + + /** + * 更新范围内单元格内容响应 + */ + @SerializedName("update_range_response") + private UpdateRangeResponse updateRangeResponse; + + /** + * 删除表格连续的行或列响应 + */ + @SerializedName("delete_dimension_response") + private DeleteDimensionResponse deleteDimensionResponse; + + /** + * 从 JSON 字符串反序列化为 WxCpDocSheetBatchUpdateResponse 对象。 + * + * @param json the json + * @return 反序列化得到的 WxCpDocSheetBatchUpdateResponse 对象 + */ + public static WxCpDocSheetBatchUpdateResponse fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetBatchUpdateResponse.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 新增工作表响应 + */ + @Getter + @Setter + public static class AddSheetResponse implements Serializable { + private static final long serialVersionUID = 618814209485621336L; + + /** + * 新增子表的属性 + */ + @SerializedName("properties") + private Properties properties; + } + + /** + * 删除工作表响应 + */ + @Getter + @Setter + public static class DeleteSheetResponse implements Serializable { + private static final long serialVersionUID = 625927337093938411L; + + /** + * 被删除的工作表的唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + } + + /** + * 更新范围内单元格内容响应 + */ + @Getter + @Setter + public static class UpdateRangeResponse implements Serializable { + private static final long serialVersionUID = 180842641209787414L; + + /** + * 数据更新的成功的单元格数量 + */ + @SerializedName("updated_cells") + private int updatedCells; + } + + /** + * 删除表格连续的行(或列),请求响应体结构 + */ + @Getter + @Setter + public static class DeleteDimensionResponse implements Serializable { + private static final long serialVersionUID = 107245521502978033L; + + /** + * 被删除的行数(或列数) + */ + @SerializedName("deleted") + private int deleted; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java new file mode 100644 index 000000000..15e76430b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java @@ -0,0 +1,260 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格数据 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +public class WxCpDocSheetData extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 498054945993671723L; + + /** + * 返回data + */ + @SerializedName("grid_data") + private GridData gridData; + + /** + * From json sheet data. + * + * @param json the json + * @return the sheet data + */ + public static WxCpDocSheetData fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetData.class); + } + + /** + * To json string. + * + * @return the string + */ + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 表格数据 + */ + @Getter + @Setter + public static class GridData implements Serializable { + private static final long serialVersionUID = 389887488098521821L; + + /** + * 起始行编号 (从0开始计算) + */ + @SerializedName("start_row") + private int startRow; + + /** + * 起始列编号 (从0开始计算) + */ + @SerializedName("start_column") + private int startColumn; + + /** + * 各行的数据 + */ + @SerializedName("rows") + private List rows; + + /** + * 行数据 + */ + @Getter + @Setter + public static class RowData implements Serializable { + private static final long serialVersionUID = 225648868492722337L; + + /** + * 各个单元格的数据内容 + */ + @SerializedName("values") + private List values; + + /** + * 单元格的信息 + */ + @Getter + @Setter + public static class CellData implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 单元格的数据内容 + */ + @SerializedName("cell_value") + private CellValue cellValue; + + /** + * 单元格的样式信息 + */ + @SerializedName("cell_format") + private CellFormat cellFormat; + + /** + * 单元格的数据内容,暂时只支持文本、链接,一个CellValue中只能选填一个字段 + */ + @Getter + @Setter + public static class CellValue implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 文本 + */ + @SerializedName("text") + private String text; + + /** + * 链接 + */ + @SerializedName("link") + private Link link; + + /** + * 链接 + */ + @Getter + @Setter + public static class Link implements Serializable { + private static final long serialVersionUID = 912896452879347178L; + + /** + * 链接url + */ + @SerializedName("url") + private String url; + + /** + * 链接标题 + */ + @SerializedName("text") + private String text; + } + } + + /** + * 单元格的样式信息 + */ + @Getter + @Setter + public static class CellFormat implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 文字样式 + */ + + @SerializedName("text_format") + private TextFormat textFormat; + + /** + * 文字样式 + */ + @Getter + @Setter + public static class TextFormat implements Serializable { + private static final long serialVersionUID = 184358104921122206L; + + /** + * 字体 + */ + @SerializedName("font") + private String font; + + /** + * 字体大小,最大72 + */ + @SerializedName("font_size") + private int fontSize; + + /** + * 字体加粗 + */ + @SerializedName("bold") + private boolean bold; + + /** + * 斜体 + */ + @SerializedName("italic") + private boolean italic; + + /** + * 字体删除线 + */ + @SerializedName("strikethrough") + private boolean strikethrough; + + /** + * 字体下划线 + */ + @SerializedName("underline") + private boolean underline; + + /** + * 字体颜色 + */ + @SerializedName("color") + private Color color; + + /** + * 字体颜色 + */ + @Getter + @Setter + public static class Color implements Serializable { + private static final long serialVersionUID = 140418085882147315L; + + /** + * 红色,取值范围:[0,255] + */ + @SerializedName("red") + private int red; + + /** + * 绿色,取值范围:[0,255] + */ + @SerializedName("green") + private int green; + + /** + * 蓝色,取值范围:[0,255] + */ + @SerializedName("blue") + private int blue; + + /** + * alpha通道,取值范围:[0,255],默认值为255完全不透明 + */ + @SerializedName("alpha") + private int alpha; + + } + + } + } + + } + + } + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java new file mode 100644 index 000000000..df2907aa3 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java @@ -0,0 +1,64 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格数据请求 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSheetGetDataRequest implements Serializable { + private static final long serialVersionUID = 827718590347822812L; + + /** + * 在线表格唯一标识.必填 + */ + @SerializedName("docid") + private String docId; + + /** + * 工作表ID,工作表的唯一标识.必填 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 查询的范围,格式为"A1:B2",表示获取A1到B2单元格的数据.必填 + */ + @SerializedName("range") + private String range; + + /** + * From json to {@link WxCpDocSheetGetDataRequest}. + * + * @param json the json string representing {@link WxCpDocSheetGetDataRequest} + * @return the {@link WxCpDocSheetGetDataRequest} object + */ + public static WxCpDocSheetGetDataRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetGetDataRequest.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java new file mode 100644 index 000000000..6e67965fe --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java @@ -0,0 +1,79 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格行列信息 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +public class WxCpDocSheetProperties extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 666707252457243065L; + + @SerializedName("properties") + private List properties; + + /** + * From json sheet properties. + * + * @param json the json + * @return the sheet properties + */ + public static WxCpDocSheetProperties fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetProperties.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 工作表属性 + */ + @Getter + @Setter + public static class Properties implements Serializable { + private static final long serialVersionUID = 640301090538839892L; + + /** + * 工作表ID,工作表的唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 工作表名称 + */ + @SerializedName("title") + private String title; + + /** + * 表格的总行数 + */ + @SerializedName("row_count") + private int rowCount; + + /** + * 表格的总列数 + */ + @SerializedName("column_count") + private int columnCount; + + } +} 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 ade813ef5..82bb811b3 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 @@ -575,6 +575,21 @@ interface Oa { */ String WEDOC_DOC_SHARE = "/cgi-bin/wedoc/doc_share"; + /** + * The constant WEDOC_SPREADSHEET_BATCH_UPDATE. + */ + String WEDOC_SPREADSHEET_BATCH_UPDATE = "/cgi-bin/wedoc/spreadsheet/batch_update"; + + /** + * The constant WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES. + */ + String WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES = "/cgi-bin/wedoc/spreadsheet/get_sheet_properties"; + + /** + * The constant WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA. + */ + String WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA = "/cgi-bin/wedoc/spreadsheet/get_sheet_range_data"; + /** * 邮件 * https://developer.work.weixin.qq.com/document/path/95486 From 397bbe04c4376ab6f73717acd10a2558c6728906 Mon Sep 17 00:00:00 2001 From: buaazyl Date: Sat, 10 Jan 2026 14:23:38 +0800 Subject: [PATCH 11/33] =?UTF-8?q?:art:=20#3844=20=E3=80=90=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=9E=B6=E6=9E=84=E3=80=91=E5=B0=86=20httpclient4=20?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E7=9A=84=20scope=20=E4=BB=8E=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E7=9A=84=20compile=20=E6=94=B9=E4=B8=BA=20provided?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BE=BF=E8=AE=A9=E4=BD=BF=E7=94=A8=E8=80=85?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=9B=B4=E7=81=B5=E6=B4=BB=E5=9C=B0=E9=80=89?= =?UTF-8?q?=E6=8B=A9=20HTTP=20=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HTTPCLIENT_UPGRADE_GUIDE.md | 10 +++++----- pom.xml | 2 +- weixin-java-channel/pom.xml | 10 ++++++++++ weixin-java-common/pom.xml | 2 ++ weixin-java-cp/pom.xml | 5 +++++ weixin-java-miniapp/pom.xml | 10 ++++++++++ weixin-java-mp/pom.xml | 10 ++++++++++ weixin-java-open/pom.xml | 10 ++++++++++ weixin-java-pay/pom.xml | 8 ++++++++ weixin-java-qidian/pom.xml | 5 +++++ 10 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/HTTPCLIENT_UPGRADE_GUIDE.md b/docs/HTTPCLIENT_UPGRADE_GUIDE.md index 945341966..5cabb1067 100644 --- a/docs/HTTPCLIENT_UPGRADE_GUIDE.md +++ b/docs/HTTPCLIENT_UPGRADE_GUIDE.md @@ -43,8 +43,8 @@ ### 对现有项目 - **向后兼容**:不需要修改任何代码 -- HttpClient 4.x 依然可用,项目同时包含两个版本的依赖 -- 如果希望继续使用 HttpClient 4.x,只需在配置中显式指定 +- 如果希望继续使用 HttpClient 4.x,只需在配置中显式指定,pay 模块会自动包含 httpclient4 依赖(因为某些接口必须使用 httpclient4) + 其他模块(mp、miniapp、cp、open、channel、qidian)如果需要使用 httpclient4,必须显式在项目中添加 httpclient4 依赖 ## 迁移步骤 @@ -94,10 +94,10 @@ WxMpService wxMpService = new WxMpServiceHttpClientImpl(); A: 不会。项目保持完全向后兼容,HttpClient 4.x 的所有实现都保持不变。 ### Q: 我需要修改代码吗? -A: 大多数情况下不需要。如果希望继续使用 HttpClient 4.x,只需在配置中指定 `http-client-type=HttpClient` 即可。 +A: 大多数情况下不需要。如果希望继续使用 HttpClient 4.x,只需在配置中指定 `http-client-type=HttpClient` ,并引入 HttpClient 4.x 依赖即可。 ### Q: 我可以在同一个项目中同时使用两个版本吗? -A: 可以。不同的模块可以配置使用不同的 HTTP 客户端。例如,MP 模块使用 HttpClient 5.x,MiniApp 模块默认使用 HttpClient 4.x,但也可以按需配置为 HttpClient 5.x。 +A: 可以。不同的模块可以配置使用不同的 HTTP 客户端。例如,MP 模块使用 HttpClient 5.x,pay 模块部分接口仍使用 HttpClient 4.x,但也可以按需配置为 HttpClient 5.x。 ### Q: 如何排除不需要的依赖? A: 如果只想使用一个版本,可以在 `pom.xml` 中排除另一个: @@ -196,4 +196,4 @@ weixin-java-common/ - ✅ **推荐使用 HttpClient 5.x**:性能更好,功能更强 - ✅ **向后兼容**:可以继续使用 HttpClient 4.x - ✅ **灵活配置**:支持多种 HTTP 客户端,按需选择 -- ✅ **平滑迁移**:无需修改代码,仅需配置即可 +- ✅ **平滑迁移**:无需修改代码,仅需配置,若不使用 HttpClient 5.x ,引入其他依赖即可 diff --git a/pom.xml b/pom.xml index 5740a2779..d58a677b2 100644 --- a/pom.xml +++ b/pom.xml @@ -136,7 +136,7 @@ UTF-8 4.5.13 - 5.5 + 5.5.2 9.4.57.v20241219 diff --git a/weixin-java-channel/pom.xml b/weixin-java-channel/pom.xml index 13dd26fa9..c15ea302e 100644 --- a/weixin-java-channel/pom.xml +++ b/weixin-java-channel/pom.xml @@ -29,6 +29,16 @@ jodd-http provided + + org.apache.httpcomponents + httpclient + provided + + + org.apache.httpcomponents + httpmime + provided + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 9032af97d..68826ca2d 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -34,6 +34,7 @@ org.apache.httpcomponents httpclient + provided commons-logging @@ -44,6 +45,7 @@ org.apache.httpcomponents httpmime + provided diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 6c47176af..6f8ab756a 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -30,6 +30,11 @@ okhttp provided + + org.apache.httpcomponents + httpclient + provided + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 340a15e58..4f5378727 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -31,6 +31,16 @@ okhttp provided + + org.apache.httpcomponents + httpclient + provided + + + org.apache.httpcomponents + httpmime + provided + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index c33aaeab8..755695d0c 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -31,6 +31,16 @@ okhttp provided + + org.apache.httpcomponents + httpclient + provided + + + org.apache.httpcomponents + httpmime + provided + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 4c34786da..6720cd2b3 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -48,6 +48,16 @@ okhttp provided + + org.apache.httpcomponents + httpclient + provided + + + org.apache.httpcomponents + httpmime + provided + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 9bf6d49a7..43851df85 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -34,6 +34,14 @@ jodd-util 6.1.0 + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpmime + org.apache.httpcomponents.client5 httpclient5 diff --git a/weixin-java-qidian/pom.xml b/weixin-java-qidian/pom.xml index 293a4655c..0752ce69d 100644 --- a/weixin-java-qidian/pom.xml +++ b/weixin-java-qidian/pom.xml @@ -31,6 +31,11 @@ okhttp provided + + org.apache.httpcomponents + httpclient + provided + org.apache.httpcomponents.client5 httpclient5 From 5947f2480585acdb5e735de10c4263534a732b36 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 20:08:02 +0800 Subject: [PATCH 12/33] =?UTF-8?q?:art:=20=E6=9B=B4=E6=AD=A3BusinessOperati?= =?UTF-8?q?onTransferRequest=E4=B8=ADtransferSceneId=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=A3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/transfer/BusinessOperationTransferRequest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java index 60b8edaf4..0129798ed 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/BusinessOperationTransferRequest.java @@ -40,7 +40,9 @@ public class BusinessOperationTransferRequest implements Serializable { /** * 转账场景ID - * 必须,该笔转账使用的转账场景,可前往“商户平台-产品中心-商家转账”中申请。如:1000(现金营销),1006(企业报销)等 + * 必须,该笔转账使用的转账场景,可前往"商户平台-产品中心-商家转账"中申请。 + * 运营工具场景ID如:2001(现金营销)、2002(佣金报酬)、2003(推广奖励)等 + * 可使用 {@link com.github.binarywang.wxpay.constant.WxPayConstants.OperationSceneId} 中定义的常量 */ @SerializedName("transfer_scene_id") private String transferSceneId; From 3b5ead664cc6e7ef71c1890e71b539aa684a818c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 14 Jan 2026 13:56:50 +0800 Subject: [PATCH 13/33] =?UTF-8?q?:new:=20#3850=20=E3=80=90=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E5=8F=B7=E3=80=91=E5=B0=8F=E5=BA=97=20SDK=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=B1=BB=E7=9B=AE=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=92=8C=E5=95=86=E5=93=81=20SPU=20=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=89=A9=E5=B1=95=EF=BC=88by=20cchengg=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../channel/api/WxChannelCategoryService.java | 18 +++++--- .../impl/WxChannelCategoryServiceImpl.java | 27 ++++++------ .../bean/category/CategoryDetailResult.java | 3 ++ .../bean/category/RelationCategoryItem.java | 41 +++++++++++++++++++ .../category/RelationCategoryRequest.java | 28 +++++++++++++ .../category/RelationCategoryResponse.java | 25 +++++++++++ .../channel/bean/product/SkuFastInfo.java | 8 ++++ .../weixin/channel/bean/product/SkuInfo.java | 4 ++ .../channel/bean/product/SpuFastInfo.java | 24 +++++++++++ .../weixin/channel/bean/product/SpuInfo.java | 4 ++ .../bean/product/TimingOnSaleInfo.java | 36 ++++++++++++++++ .../constant/WxChannelApiUrlConstants.java | 2 + .../WxChannelCategoryServiceImplTest.java | 10 +++++ 13 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java index 0b357a5d1..ad8669761 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java @@ -6,11 +6,7 @@ import me.chanjar.weixin.channel.bean.audit.AuditResponse; import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo; import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; -import me.chanjar.weixin.channel.bean.category.CategoryDetailResult; -import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse; -import me.chanjar.weixin.channel.bean.category.PassCategoryResponse; -import me.chanjar.weixin.channel.bean.category.ShopCategory; -import me.chanjar.weixin.channel.bean.category.ShopCategoryResponse; +import me.chanjar.weixin.channel.bean.category.*; import me.chanjar.weixin.common.error.WxErrorException; /** @@ -121,4 +117,16 @@ AuditApplyResponse addCategory(String level1, String level2, String level3, List * @throws WxErrorException 异常 */ PassCategoryResponse listPassCategory() throws WxErrorException; + + /** + * 获取店铺的类目权限列表 + * + * @param isFilterStatus 是否按状态筛选 + * @param status 类目状态(当 isFilterStatus 为 true 时有效) + * @return 类目权限列表 + * + * @throws WxErrorException 异常 + */ + RelationCategoryResponse listRelationCategory(Boolean isFilterStatus, Integer status) throws WxErrorException; + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java index 23cd83984..7070ab929 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java @@ -1,13 +1,5 @@ package me.chanjar.weixin.channel.api.impl; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.ADD_CATEGORY_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.AVAILABLE_CATEGORY_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.CANCEL_CATEGORY_AUDIT_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_AUDIT_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_DETAIL_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_ALL_CATEGORY_URL; -import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_PASS_CATEGORY_URL; - import java.util.Collections; import java.util.List; import lombok.extern.slf4j.Slf4j; @@ -17,17 +9,15 @@ import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo; import me.chanjar.weixin.channel.bean.audit.CategoryAuditRequest; import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; -import me.chanjar.weixin.channel.bean.category.CategoryDetailResult; -import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse; -import me.chanjar.weixin.channel.bean.category.PassCategoryResponse; -import me.chanjar.weixin.channel.bean.category.ShopCategory; -import me.chanjar.weixin.channel.bean.category.ShopCategoryResponse; +import me.chanjar.weixin.channel.bean.category.*; import me.chanjar.weixin.channel.util.JsonUtils; import me.chanjar.weixin.channel.util.ResponseUtils; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.*; + /** * 视频号小店 商品类目相关接口 * @@ -135,4 +125,15 @@ public PassCategoryResponse listPassCategory() throws WxErrorException { return ResponseUtils.decode(resJson, PassCategoryResponse.class); } + @Override + public RelationCategoryResponse listRelationCategory(Boolean isFilterStatus, Integer status) throws WxErrorException { + RelationCategoryRequest request = new RelationCategoryRequest( + isFilterStatus != null ? isFilterStatus : false, + status != null ? status : 0 + ); + String reqJson = JsonUtils.encode(request); + String resJson = shopService.post(LIST_RELATION_CATEGORY_URL, reqJson); + return ResponseUtils.decode(resJson, RelationCategoryResponse.class); + } + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java index 32313b7e3..3188bd382 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java @@ -22,6 +22,9 @@ public class CategoryDetailResult extends WxChannelBaseResponse { @JsonProperty("attr") private Attr attr; + @JsonProperty("product_qua_list") + private List productQuaList; + @Data @NoArgsConstructor diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java new file mode 100644 index 000000000..8e0bd1b0b --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java @@ -0,0 +1,41 @@ +package me.chanjar.weixin.channel.bean.category; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 店铺类目权限列表项 + * + * @author chucheng + */ +@Data +@NoArgsConstructor +public class RelationCategoryItem implements Serializable { + + /** 类目id */ + @JsonProperty("id") + private Long id; + + /** 类目状态, 1生效中,2已失效 */ + @JsonProperty("status") + private Integer status; + + /** 失效原因 */ + @JsonProperty("uneffective_reason") + private String uneffectiveReason; + + /** 生效时间 */ + @JsonProperty("effective_time") + private Long effectiveTime; + + /** 失效时间 */ + @JsonProperty("uneffective_time") + private Long uneffectiveTime; + + /** 类目资质id */ + @JsonProperty("qua_id") + private Long quaId; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java new file mode 100644 index 000000000..c514e7d9c --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java @@ -0,0 +1,28 @@ +package me.chanjar.weixin.channel.bean.category; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 类目权限列表请求参数 + * + * @author Zeyes + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RelationCategoryRequest implements Serializable { + + private static final long serialVersionUID = -8765432109876543210L; + + /** 是否按状态筛选 */ + @JsonProperty("is_filter_status") + private Boolean isFilterStatus; + + /** 类目状态(当 isFilterStatus 为 true 时有效) */ + @JsonProperty("status") + private Integer status; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java new file mode 100644 index 000000000..4bd1ea96d --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.channel.bean.category; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; + +/** + * 店铺的类目权限列表响应 + * + * @author chucheng + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class RelationCategoryResponse extends WxChannelBaseResponse { + + private static final long serialVersionUID = -8473920857463918245L; + + @JsonProperty("list") + private List list; + +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java index a461e6d95..b37dfe472 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java @@ -35,6 +35,14 @@ public class SkuFastInfo implements Serializable { @JsonProperty("is_delete") private Boolean delete; + /** 商品sku编码 */ + @JsonProperty("sku_code") + private String skuCode; + + /** 更新sku状态 0-默认值;5-上架;11-下架 */ + @JsonProperty("status") + private Integer status; + @Data @NoArgsConstructor diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java index 22e75d7af..956b188c2 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java @@ -56,6 +56,10 @@ public class SkuInfo implements Serializable { @JsonProperty("sku_id") private String skuId; + /** sku条形码 */ + @JsonProperty("bar_code") + private String barCode; + public SkuInfo() { } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java index 05e107779..23b1135ba 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java @@ -25,4 +25,28 @@ public class SpuFastInfo implements Serializable { @JsonProperty("skus") protected List skus; + /** 商品编码 */ + @JsonProperty("spu_code") + protected String spuCode; + + /** 限购信息 */ + @JsonProperty("limit_info") + protected LimitInfo limitInfo; + + /** 运费信息 */ + @JsonProperty("express_info") + protected ExpressInfo expressInfo; + + /** 额外服务 */ + @JsonProperty("extra_service") + protected ExtraServiceInfo extraService; + + /** 发货方式:0-快递发货;1-无需快递,手机号发货;3-无需快递,可选发货账号类型,默认为0,若为无需快递,则无需填写运费模版id */ + @JsonProperty("deliver_method") + private Integer deliverMethod; + + /** 商品待开售信息 */ + @JsonProperty("timing_onsale_info") + private TimingOnSaleInfo timingOnSaleInfo; + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java index 155148c17..9b2224db9 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java @@ -151,4 +151,8 @@ public class SpuInfo extends SpuSimpleInfo { /** 发布模式,0: 普通模式;1: 极简模式 */ @JsonProperty("release_mode") private Integer releaseMode; + + /** 商品待开售信息 */ + @JsonProperty("timing_onsale_info") + private TimingOnSaleInfo timingOnSaleInfo; } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java new file mode 100644 index 000000000..29270d426 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.channel.bean.product; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 商品待开售信息 + * + * @author chu + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TimingOnSaleInfo implements Serializable { + + /** 状态枚举 0-没有待开售;1-待开售 */ + @JsonProperty("status") + private Integer status; + + /** 开售时间,秒级时间戳,0为未配置时间 */ + @JsonProperty("onsale_time") + private Long onSaleTime; + + /** 是否隐藏价格 0-不隐藏;1-隐藏 */ + @JsonProperty("is_hide_price") + private Integer isHidePrice; + + /** 待开售任务ID,可用于请求立即开售 */ + @JsonProperty("task_id") + private Integer taskId; + +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java index 2d9aa84f8..4859b723f 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java @@ -53,6 +53,8 @@ public interface Category { String CANCEL_CATEGORY_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/category/audit/cancel"; /** 获取账号申请通过的类目和资质信息 */ String LIST_PASS_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/list/get"; + /** 获取店铺的类目权限列表 */ + String LIST_RELATION_CATEGORY_URL = "https://api.weixin.qq.com/shop/ec/category/get_category_relation_list"; } /** 主页管理相关接口 */ diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java index 125e061cd..06afde299 100644 --- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java +++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java @@ -158,4 +158,14 @@ public void testListPassCategory() throws WxErrorException { assertTrue(response.isSuccess()); System.out.println(response); } + + @Test + public void testListRelationCategory() throws WxErrorException { + WxChannelCategoryService categoryService = channelService.getCategoryService(); + me.chanjar.weixin.channel.bean.category.RelationCategoryResponse response = + categoryService.listRelationCategory(true, 1); + assertNotNull(response); + assertTrue(response.isSuccess()); + System.out.println(response); + } } From 16d5cf9afd8dd03ff89b6537c7c01b1d8e75306f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:05:39 +0800 Subject: [PATCH 14/33] =?UTF-8?q?:art:=20#3843=20=E3=80=90=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=9E=B6=E6=9E=84=E3=80=91=E4=BF=AE=E5=A4=8D=20Spring?= =?UTF-8?q?=20Boot=203=EF=BC=88Spring=20Data=20Redis=203.x=EF=BC=89?= =?UTF-8?q?=E4=B8=8B=20RedisTemplate.getExpire=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC=E8=AF=AD=E4=B9=89=E5=8F=98=E5=8C=96=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E8=BF=87=E6=9C=9F=E5=88=A4=E6=96=AD/=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=A4=B1=E6=95=88=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/common/redis/RedisTemplateWxRedisOps.java | 2 +- .../weixin/common/redis/CommonWxRedisOpsTest.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java index 19d4046c9..d531a2a30 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java @@ -29,7 +29,7 @@ public void setValue(String key, String value, int expire, TimeUnit timeUnit) { @Override public Long getExpire(String key) { - return redisTemplate.getExpire(key); + return redisTemplate.getExpire(key, TimeUnit.SECONDS); } @Override diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/redis/CommonWxRedisOpsTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/redis/CommonWxRedisOpsTest.java index 96ba20ba2..fb53c8c4b 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/redis/CommonWxRedisOpsTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/redis/CommonWxRedisOpsTest.java @@ -35,6 +35,17 @@ public void testGetExpire() { Assert.assertTrue(expireSeconds <= 4 && expireSeconds >= 0); } + @Test + public void testGetExpireForNonExistentKey() { + String nonExistentKey = "non_existent_key_" + System.currentTimeMillis(); + Long expire = wxRedisOps.getExpire(nonExistentKey); + // 对于不存在的 key,底层使用 getExpire(key, TimeUnit.SECONDS) 时应返回负值 + // Spring Data Redis 2.x 和 3.x 约定:-2 表示 key 不存在,-1 表示 key 没有过期时间 + // 因此这里不应返回 null,而应返回一个小于 0 的值 + Assert.assertNotNull(expire, "Non-existent key should not have null expiration"); + Assert.assertTrue(expire < 0, "Non-existent key should have negative expiration"); + } + @Test public void testExpire() { String key = "access_token", value = String.valueOf(System.currentTimeMillis()); From 777f4e518a75753e99aaf9bed3d8c5e86814d055 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 10:57:55 +0800 Subject: [PATCH 15/33] =?UTF-8?q?:art:=20#3841=20=E3=80=90=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E3=80=91=E4=BF=AE=E5=A4=8D=20RsaCry?= =?UTF-8?q?ptoUtil=20=E6=97=A0=E6=B3=95=E5=8A=A0=E5=AF=86=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E5=AD=97=E6=AE=B5=E5=92=8C=E5=B5=8C=E5=A5=97=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=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/v3/util/RsaCryptoUtil.java | 23 ++- .../wxpay/v3/util/RsaCryptoUtilTest.java | 179 ++++++++++++++++++ 2 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java index 8c3e2ace5..0143022ec 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java @@ -14,8 +14,11 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Base64; import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * 微信支付敏感信息加密 @@ -36,10 +39,26 @@ public static void encryptFields(Object encryptObject, X509Certificate certifica } } + /** + * 递归获取类的所有字段,包括父类中的字段 + * + * @param clazz 要获取字段的类 + * @return 所有字段的列表 + */ + private static List getAllFields(Class clazz) { + List fields = new ArrayList<>(); + while (clazz != null && clazz != Object.class) { + Field[] declaredFields = clazz.getDeclaredFields(); + Collections.addAll(fields, declaredFields); + clazz = clazz.getSuperclass(); + } + return fields; + } + private static void encryptField(Object encryptObject, X509Certificate certificate) throws IllegalAccessException, IllegalBlockSizeException { Class infoClass = encryptObject.getClass(); - Field[] infoFieldArray = infoClass.getDeclaredFields(); - for (Field field : infoFieldArray) { + List infoFieldList = getAllFields(infoClass); + for (Field field : infoFieldList) { if (field.isAnnotationPresent(SpecEncrypt.class)) { //字段使用了@SpecEncrypt进行标识 if (field.getType().getTypeName().equals(JAVA_LANG_STRING)) { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java new file mode 100644 index 000000000..18f46c687 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -0,0 +1,179 @@ +package com.github.binarywang.wxpay.v3.util; + +import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingReceiverV3Request; +import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.testng.annotations.Test; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import static org.testng.Assert.*; + +/** + * RsaCryptoUtil 测试类 + */ +public class RsaCryptoUtilTest { + + /** + * 测试反射能否找到嵌套类中的 @SpecEncrypt 注解字段 + */ + @Test + public void testFindAnnotatedFieldsInNestedClass() { + // 创建 Receiver 对象 + ProfitSharingV3Request.Receiver receiver = new ProfitSharingV3Request.Receiver(); + receiver.setName("测试姓名"); + + // 使用反射查找带有 @SpecEncrypt 注解的字段 + Class receiverClass = receiver.getClass(); + Field[] fields = receiverClass.getDeclaredFields(); + + boolean foundNameField = false; + boolean nameFieldHasAnnotation = false; + + for (Field field : fields) { + if (field.getName().equals("name")) { + foundNameField = true; + if (field.isAnnotationPresent(SpecEncrypt.class)) { + nameFieldHasAnnotation = true; + } + } + } + + // 验证能够找到 name 字段并且它有 @SpecEncrypt 注解 + assertTrue(foundNameField, "应该能找到 name 字段"); + assertTrue(nameFieldHasAnnotation, "name 字段应该有 @SpecEncrypt 注解"); + } + + /** + * 测试嵌套对象中的字段加密 + * 验证 List 中每个 Receiver 对象的 name 字段是否能被正确找到和处理 + */ + @Test + public void testEncryptFieldsWithNestedObjects() { + // 创建测试对象 + ProfitSharingV3Request request = ProfitSharingV3Request.newBuilder() + .appid("test-appid") + .subMchId("test-submchid") + .transactionId("test-transaction") + .outOrderNo("test-order-no") + .unfreezeUnsplit(true) + .build(); + + List receivers = new ArrayList<>(); + ProfitSharingV3Request.Receiver receiver = new ProfitSharingV3Request.Receiver(); + receiver.setName("张三"); // 设置需要加密的字段 + receiver.setAccount("test-account"); + receiver.setType("PERSONAL_OPENID"); + receiver.setAmount(100); + receiver.setRelationType("STORE"); + receiver.setDescription("测试分账"); + + receivers.add(receiver); + request.setReceivers(receivers); + + // 验证 receivers 字段有 @SpecEncrypt 注解 + try { + Field receiversField = ProfitSharingV3Request.class.getDeclaredField("receivers"); + boolean hasAnnotation = receiversField.isAnnotationPresent(SpecEncrypt.class); + assertTrue(hasAnnotation, "receivers 字段应该有 @SpecEncrypt 注解"); + } catch (NoSuchFieldException e) { + fail("应该能找到 receivers 字段"); + } + + // 验证name字段不为null + assertNotNull(receiver.getName()); + assertEquals(receiver.getName(), "张三"); + } + + /** + * 测试单个对象中的字段加密 + * 验证直接在对象上的 @SpecEncrypt 字段是否能被正确找到 + */ + @Test + public void testEncryptFieldsWithDirectField() { + // 创建测试对象 + ProfitSharingReceiverV3Request request = ProfitSharingReceiverV3Request.newBuilder() + .appid("test-appid") + .subMchId("test-submchid") + .type("PERSONAL_OPENID") + .account("test-account") + .name("李四") + .relationType("STORE") + .build(); + + // 验证 name 字段有 @SpecEncrypt 注解 + try { + Field nameField = ProfitSharingReceiverV3Request.class.getDeclaredField("name"); + boolean hasAnnotation = nameField.isAnnotationPresent(SpecEncrypt.class); + assertTrue(hasAnnotation, "name 字段应该有 @SpecEncrypt 注解"); + } catch (NoSuchFieldException e) { + fail("应该能找到 name 字段"); + } + + // 验证name字段不为null + assertNotNull(request.getName()); + assertEquals(request.getName(), "李四"); + } + + /** + * 测试类继承场景下的字段加密 + * 验证父类中带 @SpecEncrypt 注解的字段是否能被正确找到和加密 + */ + @Test + public void testEncryptFieldsWithInheritance() { + // 定义测试用的父类和子类 + @Data + class ParentRequest { + @SpecEncrypt + @SerializedName("parent_name") + private String parentName; + } + + @Data + @lombok.EqualsAndHashCode(callSuper = false) + class ChildRequest extends ParentRequest { + @SpecEncrypt + @SerializedName("child_name") + private String childName; + + @Override + protected boolean canEqual(final Object other) { + return other instanceof ChildRequest; + } + } + + // 创建子类实例 + ChildRequest request = new ChildRequest(); + request.setParentName("父类字段"); + request.setChildName("子类字段"); + + // 验证能够找到父类和子类的字段 + // 使用 getDeclaredFields 只能找到子类字段 + Field[] childFields = ChildRequest.class.getDeclaredFields(); + + // 使用反射调用 RsaCryptoUtil 的私有 getAllFields 方法 + int annotatedFieldCount = 0; + try { + java.lang.reflect.Method getAllFieldsMethod = RsaCryptoUtil.class.getDeclaredMethod("getAllFields", Class.class); + getAllFieldsMethod.setAccessible(true); + @SuppressWarnings("unchecked") + List allFields = (List) getAllFieldsMethod.invoke(null, ChildRequest.class); + + for (Field field : allFields) { + if (field.isAnnotationPresent(SpecEncrypt.class)) { + annotatedFieldCount++; + } + } + } catch (Exception e) { + fail("无法调用 getAllFields 方法: " + e.getMessage()); + } + + // 应该找到2个带注解的字段(parentName 和 childName) + assertTrue(annotatedFieldCount >= 2, "应该能找到至少2个带 @SpecEncrypt 注解的字段"); + } +} From 6a9852f7e3bfef2b1090abebae86865b3b449735 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:07:03 +0800 Subject: [PATCH 16/33] =?UTF-8?q?:new:=20#3847=20=E3=80=90=E5=BC=80?= =?UTF-8?q?=E6=94=BE=E5=B9=B3=E5=8F=B0=E3=80=91=E6=96=B0=E5=A2=9E=20wx-jav?= =?UTF-8?q?a-open-multi-spring-boot-starter=20=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E5=BC=80=E6=94=BE=E5=B9=B3=E5=8F=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-boot-starters/pom.xml | 1 + .../README.md | 98 +++++++++++ .../pom.xml | 62 +++++++ .../WxOpenMultiAutoConfiguration.java | 15 ++ .../WxOpenMultiServiceConfiguration.java | 26 +++ .../services/AbstractWxOpenConfiguration.java | 153 ++++++++++++++++++ .../services/WxOpenInJedisConfiguration.java | 78 +++++++++ .../services/WxOpenInMemoryConfiguration.java | 33 ++++ .../WxOpenInRedisTemplateConfiguration.java | 44 +++++ .../WxOpenInRedissonConfiguration.java | 68 ++++++++ .../properties/WxOpenMultiProperties.java | 125 ++++++++++++++ .../WxOpenMultiRedisProperties.java | 57 +++++++ .../properties/WxOpenSingleProperties.java | 49 ++++++ .../open/service/WxOpenMultiServices.java | 26 +++ .../open/service/WxOpenMultiServicesImpl.java | 35 ++++ .../main/resources/META-INF/spring.factories | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + 17 files changed, 873 insertions(+) create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/README.md create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/pom.xml create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/autoconfigure/WxOpenMultiAutoConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/WxOpenMultiServiceConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInJedisConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInMemoryConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedisTemplateConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedissonConfiguration.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiProperties.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 1f4881e9d..e145e5fd6 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -23,6 +23,7 @@ wx-java-mp-multi-spring-boot-starter wx-java-mp-spring-boot-starter wx-java-pay-spring-boot-starter + wx-java-open-multi-spring-boot-starter wx-java-open-spring-boot-starter wx-java-qidian-spring-boot-starter wx-java-cp-multi-spring-boot-starter diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/README.md b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/README.md new file mode 100644 index 000000000..ab5afa544 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/README.md @@ -0,0 +1,98 @@ +# wx-java-open-multi-spring-boot-starter + +## 快速开始 + +1. 引入依赖 + ```xml + + com.github.binarywang + wx-java-open-multi-spring-boot-starter + ${version} + + ``` +2. 添加配置(application.properties) + ```properties + # 开放平台配置 + ## 应用 1 配置(必填) + wx.open.apps.tenantId1.app-id=appId + wx.open.apps.tenantId1.secret=@secret + ## 选填 + wx.open.apps.tenantId1.token=@token + wx.open.apps.tenantId1.aes-key=@aesKey + wx.open.apps.tenantId1.api-host-url=@apiHostUrl + wx.open.apps.tenantId1.access-token-url=@accessTokenUrl + ## 应用 2 配置(必填) + wx.open.apps.tenantId2.app-id=@appId + wx.open.apps.tenantId2.secret=@secret + ## 选填 + wx.open.apps.tenantId2.token=@token + wx.open.apps.tenantId2.aes-key=@aesKey + wx.open.apps.tenantId2.api-host-url=@apiHostUrl + wx.open.apps.tenantId2.access-token-url=@accessTokenUrl + + # ConfigStorage 配置(选填) + ## 配置类型: memory(默认), jedis, redisson, redistemplate + wx.open.config-storage.type=memory + ## 相关redis前缀配置: wx:open:multi(默认) + wx.open.config-storage.key-prefix=wx:open:multi + wx.open.config-storage.redis.host=127.0.0.1 + wx.open.config-storage.redis.port=6379 + ## 注意:当前版本暂不支持 sentinel 配置,以下配置仅作为预留 + # wx.open.config-storage.redis.sentinel-ips=127.0.0.1:16379,127.0.0.1:26379 + # wx.open.config-storage.redis.sentinel-name=mymaster + + # http 客户端配置(选填) + wx.open.config-storage.http-proxy-host= + wx.open.config-storage.http-proxy-port= + wx.open.config-storage.http-proxy-username= + wx.open.config-storage.http-proxy-password= + ## 最大重试次数,默认:5 次,如果小于 0,则为 0 + wx.open.config-storage.max-retry-times=5 + ## 重试时间间隔步进,默认:1000 毫秒,如果小于 0,则为 1000 + wx.open.config-storage.retry-sleep-millis=1000 + ## 连接超时时间,单位毫秒,默认:5000 + wx.open.config-storage.connection-timeout=5000 + ## 读数据超时时间,即socketTimeout,单位毫秒,默认:5000 + wx.open.config-storage.so-timeout=5000 + ## 从连接池获取链接的超时时间,单位毫秒,默认:5000 + wx.open.config-storage.connection-request-timeout=5000 + ``` +3. 自动注入的类型:`WxOpenMultiServices` + +4. 使用样例 + +```java +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DemoService { + @Autowired + private WxOpenMultiServices wxOpenMultiServices; + + public void test() { + // 应用 1 的 WxOpenService + WxOpenService wxOpenService1 = wxOpenMultiServices.getWxOpenService("tenantId1"); + WxOpenComponentService componentService1 = wxOpenService1.getWxOpenComponentService(); + // todo ... + + // 应用 2 的 WxOpenService + WxOpenService wxOpenService2 = wxOpenMultiServices.getWxOpenService("tenantId2"); + WxOpenComponentService componentService2 = wxOpenService2.getWxOpenComponentService(); + // todo ... + + // 应用 3 的 WxOpenService + WxOpenService wxOpenService3 = wxOpenMultiServices.getWxOpenService("tenantId3"); + // 判断是否为空 + if (wxOpenService3 == null) { + // todo wxOpenService3 为空,请先配置 tenantId3 微信开放平台应用参数 + return; + } + WxOpenComponentService componentService3 = wxOpenService3.getWxOpenComponentService(); + // todo ... + } +} +``` diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/pom.xml new file mode 100644 index 000000000..1ad7a5e8e --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/pom.xml @@ -0,0 +1,62 @@ + + + + wx-java-spring-boot-starters + com.github.binarywang + 4.8.0 + + 4.0.0 + + wx-java-open-multi-spring-boot-starter + WxJava - Spring Boot Starter for WxOpen::支持多账号配置 + 微信开放平台开发的 Spring Boot Starter::支持多账号配置 + + + + com.github.binarywang + weixin-java-open + ${project.version} + + + redis.clients + jedis + provided + + + org.redisson + redisson + provided + + + org.springframework.data + spring-data-redis + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/autoconfigure/WxOpenMultiAutoConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/autoconfigure/WxOpenMultiAutoConfiguration.java new file mode 100644 index 000000000..749130f51 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/autoconfigure/WxOpenMultiAutoConfiguration.java @@ -0,0 +1,15 @@ +package com.binarywang.spring.starter.wxjava.open.autoconfigure; + +import com.binarywang.spring.starter.wxjava.open.configuration.WxOpenMultiServiceConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * 微信开放平台多账号自动配置 + * + * @author Binary Wang + */ +@Configuration +@Import(WxOpenMultiServiceConfiguration.class) +public class WxOpenMultiAutoConfiguration { +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/WxOpenMultiServiceConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/WxOpenMultiServiceConfiguration.java new file mode 100644 index 000000000..e858185e3 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/WxOpenMultiServiceConfiguration.java @@ -0,0 +1,26 @@ +package com.binarywang.spring.starter.wxjava.open.configuration; + +import com.binarywang.spring.starter.wxjava.open.configuration.services.WxOpenInJedisConfiguration; +import com.binarywang.spring.starter.wxjava.open.configuration.services.WxOpenInMemoryConfiguration; +import com.binarywang.spring.starter.wxjava.open.configuration.services.WxOpenInRedisTemplateConfiguration; +import com.binarywang.spring.starter.wxjava.open.configuration.services.WxOpenInRedissonConfiguration; +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * 微信开放平台相关服务自动注册 + * + * @author Binary Wang + */ +@Configuration +@EnableConfigurationProperties(WxOpenMultiProperties.class) +@Import({ + WxOpenInJedisConfiguration.class, + WxOpenInMemoryConfiguration.class, + WxOpenInRedissonConfiguration.class, + WxOpenInRedisTemplateConfiguration.class +}) +public class WxOpenMultiServiceConfiguration { +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java new file mode 100644 index 000000000..0c6387878 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java @@ -0,0 +1,153 @@ +package com.binarywang.spring.starter.wxjava.open.configuration.services; + +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenSingleProperties; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServicesImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; +import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * WxOpenConfigStorage 抽象配置类 + * + * @author Binary Wang + */ +@RequiredArgsConstructor +@Slf4j +public abstract class AbstractWxOpenConfiguration { + + protected WxOpenMultiServices wxOpenMultiServices(WxOpenMultiProperties wxOpenMultiProperties) { + Map appsMap = wxOpenMultiProperties.getApps(); + if (appsMap == null || appsMap.isEmpty()) { + log.warn("微信开放平台应用参数未配置,通过 WxOpenMultiServices#getWxOpenService(\"tenantId\")获取实例将返回空"); + return new WxOpenMultiServicesImpl(); + } + /** + * 校验 appId 是否唯一,避免使用 redis 缓存 token、ticket 时错乱。 + */ + Collection apps = appsMap.values(); + if (apps.size() > 1) { + // 校验 appId 是否唯一 + String nullAppIdPlaceholder = "__NULL_APP_ID__"; + boolean multi = apps.stream() + // 没有 appId,如果不判断是否为空,这里会报 NPE 异常 + .collect(Collectors.groupingBy(c -> c.getAppId() == null ? nullAppIdPlaceholder : c.getAppId(), Collectors.counting())) + .entrySet().stream().anyMatch(e -> e.getValue() > 1); + if (multi) { + throw new RuntimeException("请确保微信开放平台配置 appId 的唯一性"); + } + } + WxOpenMultiServicesImpl services = new WxOpenMultiServicesImpl(); + + Set> entries = appsMap.entrySet(); + for (Map.Entry entry : entries) { + String tenantId = entry.getKey(); + WxOpenSingleProperties wxOpenSingleProperties = entry.getValue(); + WxOpenInMemoryConfigStorage storage = this.wxOpenConfigStorage(wxOpenMultiProperties); + this.configApp(storage, wxOpenSingleProperties); + this.configHttp(storage, wxOpenMultiProperties.getConfigStorage()); + WxOpenService wxOpenService = this.wxOpenService(storage, wxOpenMultiProperties); + services.addWxOpenService(tenantId, wxOpenService); + } + return services; + } + + /** + * 配置 WxOpenInMemoryConfigStorage + * + * @param wxOpenMultiProperties 参数 + * @return WxOpenInMemoryConfigStorage + */ + protected abstract WxOpenInMemoryConfigStorage wxOpenConfigStorage(WxOpenMultiProperties wxOpenMultiProperties); + + public WxOpenService wxOpenService(WxOpenConfigStorage configStorage, WxOpenMultiProperties wxOpenMultiProperties) { + WxOpenService wxOpenService = new WxOpenServiceImpl(); + wxOpenService.setWxOpenConfigStorage(configStorage); + return wxOpenService; + } + + private void configApp(WxOpenInMemoryConfigStorage config, WxOpenSingleProperties appProperties) { + String appId = appProperties.getAppId(); + String secret = appProperties.getSecret(); + String token = appProperties.getToken(); + String aesKey = appProperties.getAesKey(); + String apiHostUrl = appProperties.getApiHostUrl(); + String accessTokenUrl = appProperties.getAccessTokenUrl(); + + // appId 和 secret 是必需的 + if (StringUtils.isBlank(appId)) { + throw new IllegalArgumentException("微信开放平台 appId 不能为空"); + } + if (StringUtils.isBlank(secret)) { + throw new IllegalArgumentException("微信开放平台 secret 不能为空"); + } + + config.setComponentAppId(appId); + config.setComponentAppSecret(secret); + if (StringUtils.isNotBlank(token)) { + config.setComponentToken(token); + } + if (StringUtils.isNotBlank(aesKey)) { + config.setComponentAesKey(aesKey); + } + // 设置URL配置 + config.setApiHostUrl(StringUtils.trimToNull(apiHostUrl)); + config.setAccessTokenUrl(StringUtils.trimToNull(accessTokenUrl)); + } + + private void configHttp(WxOpenInMemoryConfigStorage config, WxOpenMultiProperties.ConfigStorage storage) { + String httpProxyHost = storage.getHttpProxyHost(); + Integer httpProxyPort = storage.getHttpProxyPort(); + String httpProxyUsername = storage.getHttpProxyUsername(); + String httpProxyPassword = storage.getHttpProxyPassword(); + if (StringUtils.isNotBlank(httpProxyHost)) { + config.setHttpProxyHost(httpProxyHost); + if (httpProxyPort != null) { + config.setHttpProxyPort(httpProxyPort); + } + if (StringUtils.isNotBlank(httpProxyUsername)) { + config.setHttpProxyUsername(httpProxyUsername); + } + if (StringUtils.isNotBlank(httpProxyPassword)) { + config.setHttpProxyPassword(httpProxyPassword); + } + } + + // 设置重试配置 + int maxRetryTimes = storage.getMaxRetryTimes(); + if (maxRetryTimes < 0) { + maxRetryTimes = 0; + } + int retrySleepMillis = storage.getRetrySleepMillis(); + if (retrySleepMillis < 0) { + retrySleepMillis = 1000; + } + config.setRetrySleepMillis(retrySleepMillis); + config.setMaxRetryTimes(maxRetryTimes); + + // 设置自定义的HttpClient超时配置 + ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); + if (clientBuilder == null) { + clientBuilder = DefaultApacheHttpClientBuilder.get(); + } + if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { + DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; + defaultBuilder.setConnectionTimeout(storage.getConnectionTimeout()); + defaultBuilder.setSoTimeout(storage.getSoTimeout()); + defaultBuilder.setConnectionRequestTimeout(storage.getConnectionRequestTimeout()); + config.setApacheHttpClientBuilder(defaultBuilder); + } + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInJedisConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInJedisConfiguration.java new file mode 100644 index 000000000..bb9577b99 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInJedisConfiguration.java @@ -0,0 +1,78 @@ +package com.binarywang.spring.starter.wxjava.open.configuration.services; + +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiRedisProperties; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; +import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + + +/** + * 自动装配基于 jedis 策略配置 + * + * @author Binary Wang + */ +@Configuration +@ConditionalOnProperty( + prefix = WxOpenMultiProperties.PREFIX + ".config-storage", name = "type", havingValue = "JEDIS" +) +@ConditionalOnClass({JedisPool.class, JedisPoolConfig.class}) +@RequiredArgsConstructor +public class WxOpenInJedisConfiguration extends AbstractWxOpenConfiguration { + private final WxOpenMultiProperties wxOpenMultiProperties; + private final ApplicationContext applicationContext; + + @Bean + public WxOpenMultiServices wxOpenMultiServices() { + return this.wxOpenMultiServices(wxOpenMultiProperties); + } + + @Override + protected WxOpenInMemoryConfigStorage wxOpenConfigStorage(WxOpenMultiProperties wxOpenMultiProperties) { + return this.configJedis(wxOpenMultiProperties); + } + + private WxOpenInRedisConfigStorage configJedis(WxOpenMultiProperties wxOpenMultiProperties) { + WxOpenMultiRedisProperties redisProperties = wxOpenMultiProperties.getConfigStorage().getRedis(); + JedisPool jedisPool; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + jedisPool = getJedisPool(wxOpenMultiProperties); + } else { + jedisPool = applicationContext.getBean(JedisPool.class); + } + return new WxOpenInRedisConfigStorage(jedisPool, wxOpenMultiProperties.getConfigStorage().getKeyPrefix()); + } + + private JedisPool getJedisPool(WxOpenMultiProperties wxOpenMultiProperties) { + WxOpenMultiProperties.ConfigStorage storage = wxOpenMultiProperties.getConfigStorage(); + WxOpenMultiRedisProperties redis = storage.getRedis(); + + JedisPoolConfig config = new JedisPoolConfig(); + if (redis.getMaxActive() != null) { + config.setMaxTotal(redis.getMaxActive()); + } + if (redis.getMaxIdle() != null) { + config.setMaxIdle(redis.getMaxIdle()); + } + if (redis.getMaxWaitMillis() != null) { + config.setMaxWaitMillis(redis.getMaxWaitMillis()); + } + if (redis.getMinIdle() != null) { + config.setMinIdle(redis.getMinIdle()); + } + config.setTestOnBorrow(true); + config.setTestWhileIdle(true); + + return new JedisPool(config, redis.getHost(), redis.getPort(), + redis.getTimeout(), redis.getPassword(), redis.getDatabase()); + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInMemoryConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInMemoryConfiguration.java new file mode 100644 index 000000000..f7448a087 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInMemoryConfiguration.java @@ -0,0 +1,33 @@ +package com.binarywang.spring.starter.wxjava.open.configuration.services; + +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 自动装配基于内存策略配置 + * + * @author someone + */ +@Configuration +@ConditionalOnProperty( + prefix = WxOpenMultiProperties.PREFIX + ".config-storage", name = "type", havingValue = "MEMORY", matchIfMissing = true +) +@RequiredArgsConstructor +public class WxOpenInMemoryConfiguration extends AbstractWxOpenConfiguration { + private final WxOpenMultiProperties wxOpenMultiProperties; + + @Bean + public WxOpenMultiServices wxOpenMultiServices() { + return this.wxOpenMultiServices(wxOpenMultiProperties); + } + + @Override + protected WxOpenInMemoryConfigStorage wxOpenConfigStorage(WxOpenMultiProperties wxOpenMultiProperties) { + return new WxOpenInMemoryConfigStorage(); + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedisTemplateConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedisTemplateConfiguration.java new file mode 100644 index 000000000..6208c90fe --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedisTemplateConfiguration.java @@ -0,0 +1,44 @@ +package com.binarywang.spring.starter.wxjava.open.configuration.services; + +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; +import me.chanjar.weixin.open.api.impl.WxOpenInRedisTemplateConfigStorage; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.StringRedisTemplate; + +/** + * 自动装配基于 redis template 策略配置 + * + * @author Binary Wang + */ +@Configuration +@ConditionalOnProperty( + prefix = WxOpenMultiProperties.PREFIX + ".config-storage", name = "type", havingValue = "redistemplate" +) +@ConditionalOnClass(StringRedisTemplate.class) +@RequiredArgsConstructor +public class WxOpenInRedisTemplateConfiguration extends AbstractWxOpenConfiguration { + private final WxOpenMultiProperties wxOpenMultiProperties; + private final ApplicationContext applicationContext; + + @Bean + public WxOpenMultiServices wxOpenMultiServices() { + return this.wxOpenMultiServices(wxOpenMultiProperties); + } + + @Override + protected WxOpenInMemoryConfigStorage wxOpenConfigStorage(WxOpenMultiProperties wxOpenMultiProperties) { + return this.configRedisTemplate(); + } + + private WxOpenInRedisTemplateConfigStorage configRedisTemplate() { + StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class); + return new WxOpenInRedisTemplateConfigStorage(redisTemplate, wxOpenMultiProperties.getConfigStorage().getKeyPrefix()); + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedissonConfiguration.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedissonConfiguration.java new file mode 100644 index 000000000..97569f3ba --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/WxOpenInRedissonConfiguration.java @@ -0,0 +1,68 @@ +package com.binarywang.spring.starter.wxjava.open.configuration.services; + +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiProperties; +import com.binarywang.spring.starter.wxjava.open.properties.WxOpenMultiRedisProperties; +import com.binarywang.spring.starter.wxjava.open.service.WxOpenMultiServices; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; +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.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 自动装配基于 redisson 策略配置 + * + * @author Binary Wang + */ +@Configuration +@ConditionalOnProperty( + prefix = WxOpenMultiProperties.PREFIX + ".config-storage", name = "type", havingValue = "redisson" +) +@ConditionalOnClass({Redisson.class, RedissonClient.class}) +@RequiredArgsConstructor +public class WxOpenInRedissonConfiguration extends AbstractWxOpenConfiguration { + private final WxOpenMultiProperties wxOpenMultiProperties; + private final ApplicationContext applicationContext; + + @Bean + public WxOpenMultiServices wxOpenMultiServices() { + return this.wxOpenMultiServices(wxOpenMultiProperties); + } + + @Override + protected WxOpenInMemoryConfigStorage wxOpenConfigStorage(WxOpenMultiProperties wxOpenMultiProperties) { + return this.configRedisson(wxOpenMultiProperties); + } + + private WxOpenInRedissonConfigStorage configRedisson(WxOpenMultiProperties wxOpenMultiProperties) { + WxOpenMultiRedisProperties redisProperties = wxOpenMultiProperties.getConfigStorage().getRedis(); + RedissonClient redissonClient; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + redissonClient = getRedissonClient(wxOpenMultiProperties); + } else { + redissonClient = applicationContext.getBean(RedissonClient.class); + } + return new WxOpenInRedissonConfigStorage(redissonClient, wxOpenMultiProperties.getConfigStorage().getKeyPrefix()); + } + + private RedissonClient getRedissonClient(WxOpenMultiProperties wxOpenMultiProperties) { + WxOpenMultiProperties.ConfigStorage storage = wxOpenMultiProperties.getConfigStorage(); + WxOpenMultiRedisProperties redis = storage.getRedis(); + + Config config = new Config(); + config.useSingleServer() + .setAddress("redis://" + redis.getHost() + ":" + redis.getPort()) + .setDatabase(redis.getDatabase()) + .setPassword(redis.getPassword()); + config.setTransportMode(TransportMode.NIO); + return Redisson.create(config); + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiProperties.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiProperties.java new file mode 100644 index 000000000..95e5b6671 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiProperties.java @@ -0,0 +1,125 @@ +package com.binarywang.spring.starter.wxjava.open.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * 微信开放平台多账号配置属性. + * + * @author Binary Wang + */ +@Data +@NoArgsConstructor +@ConfigurationProperties(WxOpenMultiProperties.PREFIX) +public class WxOpenMultiProperties implements Serializable { + private static final long serialVersionUID = -5358245184407791011L; + public static final String PREFIX = "wx.open"; + + private Map apps = new HashMap<>(); + + /** + * 存储策略 + */ + private final ConfigStorage configStorage = new ConfigStorage(); + + @Data + @NoArgsConstructor + public static class ConfigStorage implements Serializable { + private static final long serialVersionUID = 4815731027000065434L; + + /** + * 存储类型. + */ + private StorageType type = StorageType.memory; + + /** + * 指定key前缀. + */ + private String keyPrefix = "wx:open:multi"; + + /** + * redis连接配置. + */ + @NestedConfigurationProperty + private final WxOpenMultiRedisProperties redis = new WxOpenMultiRedisProperties(); + + /** + * http代理主机. + */ + private String httpProxyHost; + + /** + * http代理端口. + */ + private Integer httpProxyPort; + + /** + * http代理用户名. + */ + private String httpProxyUsername; + + /** + * http代理密码. + */ + private String httpProxyPassword; + + /** + * http 请求最大重试次数 + *

          +     *   {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
          +     *   {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
          +     * 
          + */ + private int maxRetryTimes = 5; + + /** + * http 请求重试间隔 + *
          +     *   {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
          +     *   {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
          +     * 
          + */ + private int retrySleepMillis = 1000; + + /** + * 连接超时时间,单位毫秒 + */ + private int connectionTimeout = 5000; + + /** + * 读数据超时时间,即socketTimeout,单位毫秒 + */ + private int soTimeout = 5000; + + /** + * 从连接池获取链接的超时时间,单位毫秒 + */ + private int connectionRequestTimeout = 5000; + } + + public enum StorageType { + /** + * 内存 + */ + memory, + /** + * jedis + */ + jedis, + /** + * redisson + */ + redisson, + /** + * redisTemplate + */ + redistemplate + } + +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java new file mode 100644 index 000000000..ae6d5368d --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java @@ -0,0 +1,57 @@ +package com.binarywang.spring.starter.wxjava.open.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 微信开放平台多账号Redis配置. + * + * @author Binary Wang + */ +@Data +@NoArgsConstructor +public class WxOpenMultiRedisProperties implements Serializable { + private static final long serialVersionUID = -5924815351660074401L; + + /** + * 主机地址. + */ + private String host = "127.0.0.1"; + + /** + * 端口号. + */ + private int port = 6379; + + /** + * 密码. + */ + private String password; + + /** + * 超时. + */ + private int timeout = 2000; + + /** + * 数据库. + */ + private int database = 0; + + /** + * sentinel ips + */ + private String sentinelIps; + + /** + * sentinel name + */ + private String sentinelName; + + private Integer maxActive; + private Integer maxIdle; + private Integer maxWaitMillis; + private Integer minIdle; +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java new file mode 100644 index 000000000..116da323d --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java @@ -0,0 +1,49 @@ +package com.binarywang.spring.starter.wxjava.open.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 微信开放平台单个应用配置. + * + * @author Binary Wang + */ +@Data +@NoArgsConstructor +public class WxOpenSingleProperties implements Serializable { + private static final long serialVersionUID = 1980986361098922525L; + + /** + * 设置微信开放平台的appid. + */ + private String appId; + + /** + * 设置微信开放平台的app secret. + */ + private String secret; + + /** + * 设置微信开放平台的token. + */ + private String token; + + /** + * 设置微信开放平台的EncodingAESKey. + */ + private String aesKey; + + /** + * 自定义API主机地址,用于替换默认的 https://api.weixin.qq.com + * 例如:http://proxy.company.com:8080 + */ + private String apiHostUrl; + + /** + * 自定义获取AccessToken地址,用于向自定义统一服务获取AccessToken + * 例如:http://proxy.company.com:8080/oauth/token + */ + private String accessTokenUrl; +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java new file mode 100644 index 000000000..9228071a1 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java @@ -0,0 +1,26 @@ +package com.binarywang.spring.starter.wxjava.open.service; + + +import me.chanjar.weixin.open.api.WxOpenService; + +/** + * 微信开放平台 {@link WxOpenService} 所有实例存放类. + * + * @author binarywang + */ +public interface WxOpenMultiServices { + /** + * 通过租户 Id 获取 WxOpenService + * + * @param tenantId 租户 Id + * @return WxOpenService + */ + WxOpenService getWxOpenService(String tenantId); + + /** + * 根据租户 Id,从列表中移除一个 WxOpenService 实例 + * + * @param tenantId 租户 Id + */ + void removeWxOpenService(String tenantId); +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java new file mode 100644 index 000000000..76fb139e6 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java @@ -0,0 +1,35 @@ +package com.binarywang.spring.starter.wxjava.open.service; + +import me.chanjar.weixin.open.api.WxOpenService; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 微信开放平台 {@link WxOpenMultiServices} 默认实现 + * + * @author Binary Wang + */ +public class WxOpenMultiServicesImpl implements WxOpenMultiServices { + private final Map services = new ConcurrentHashMap<>(); + + @Override + public WxOpenService getWxOpenService(String tenantId) { + return this.services.get(tenantId); + } + + /** + * 根据租户 Id,添加一个 WxOpenService 到列表 + * + * @param tenantId 租户 Id + * @param wxOpenService WxOpenService 实例 + */ + public void addWxOpenService(String tenantId, WxOpenService wxOpenService) { + this.services.put(tenantId, wxOpenService); + } + + @Override + public void removeWxOpenService(String tenantId) { + this.services.remove(tenantId); + } +} diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..a61d0018d --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.binarywang.spring.starter.wxjava.open.autoconfigure.WxOpenMultiAutoConfiguration \ No newline at end of file diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000..ddc66af02 --- /dev/null +++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.binarywang.spring.starter.wxjava.open.autoconfigure.WxOpenMultiAutoConfiguration \ No newline at end of file From 0dfedb160a705c100cfd93b08094a7cad62385cc Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 15:01:46 +0800 Subject: [PATCH 17/33] =?UTF-8?q?:new:=20#3853=20=E3=80=90=E4=BC=81?= =?UTF-8?q?=E4=B8=9A=E5=BE=AE=E4=BF=A1=E3=80=91=E6=96=B0=E5=A2=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=95=86=E4=BB=A3=E5=BC=80=E5=8F=91=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cp/bean/WxCpTpCustomizedAppDetail.java | 221 ++++++++++++++++++ .../weixin/cp/bean/WxCpTpTemplateList.java | 83 +++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 9 + .../tp/service/WxCpTpCustomizedService.java | 41 ++++ .../weixin/cp/tp/service/WxCpTpService.java | 14 ++ .../service/impl/BaseWxCpTpServiceImpl.java | 11 + .../impl/WxCpTpCustomizedServiceImpl.java | 64 +++++ .../impl/WxCpTpCustomizedServiceImplTest.java | 178 ++++++++++++++ 8 files changed, 621 insertions(+) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCustomizedAppDetail.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTemplateList.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpCustomizedService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpCustomizedServiceImpl.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpCustomizedServiceImplTest.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCustomizedAppDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCustomizedAppDetail.java new file mode 100644 index 000000000..f9ca645b8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCustomizedAppDetail.java @@ -0,0 +1,221 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 代开发应用详情. + * + * @author Binary Wang + * created on 2026-01-14 + */ +@Data +public class WxCpTpCustomizedAppDetail extends WxCpBaseResp { + + /** + * 授权方企业id + */ + @SerializedName("auth_corpid") + private String authCorpId; + + /** + * 授权方企业名称 + */ + @SerializedName("auth_corp_name") + private String authCorpName; + + /** + * 授权方企业方形头像 + */ + @SerializedName("auth_corp_square_logo_url") + private String authCorpSquareLogoUrl; + + /** + * 授权方企业圆形头像 + */ + @SerializedName("auth_corp_round_logo_url") + private String authCorpRoundLogoUrl; + + /** + * 授权方企业类型,1. 企业; 2. 政府以及事业单位; 3. 其他组织, 4.团队小型企业(原企业微信认证版用户) + */ + @SerializedName("auth_corp_type") + private Integer authCorpType; + + /** + * 授权方企业在微工作台(原企业号)的二维码,可用于关注微工作台 + */ + @SerializedName("auth_corp_qrcode_url") + private String authCorpQrcodeUrl; + + /** + * 授权方企业用户规模 + */ + @SerializedName("auth_corp_user_limit") + private Integer authCorpUserLimit; + + /** + * 授权方企业的主体名称(仅认证或验证过的企业有),即企业全称 + */ + @SerializedName("auth_corp_full_name") + private String authCorpFullName; + + /** + * 企业类型,1. 已验证企业;2. 已认证企业 + */ + @SerializedName("auth_corp_verified_type") + private Integer authCorpVerifiedType; + + /** + * 授权方企业所属行业 + */ + @SerializedName("auth_corp_industry") + private String authCorpIndustry; + + /** + * 授权方企业所属子行业 + */ + @SerializedName("auth_corp_sub_industry") + private String authCorpSubIndustry; + + /** + * 授权方企业所在地址 + */ + @SerializedName("auth_corp_location") + private String authCorpLocation; + + /** + * 代开发自建应用详情 + */ + @SerializedName("customized_app_list") + private List customizedAppList; + + /** + * From json wx cp tp customized app detail. + * + * @param json the json + * @return the wx cp tp customized app detail + */ + public static WxCpTpCustomizedAppDetail fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTpCustomizedAppDetail.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 代开发自建应用信息 + */ + @Data + public static class CustomizedApp implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 代开发自建应用的agentid + */ + @SerializedName("agentid") + private Integer agentId; + + /** + * 代开发自建应用对应的模板id + */ + @SerializedName("template_id") + private String templateId; + + /** + * 代开发自建应用的name + */ + @SerializedName("name") + private String name; + + /** + * 代开发自建应用的description + */ + @SerializedName("description") + private String description; + + /** + * 代开发自建应用的logo url + */ + @SerializedName("logo_url") + private String logoUrl; + + /** + * 代开发自建应用的可见范围 + */ + @SerializedName("allow_userinfos") + private AllowUserInfos allowUserInfos; + + /** + * 代开发自建应用是否被禁用 + */ + @SerializedName("close") + private Integer close; + + /** + * 代开发自建应用主页url + */ + @SerializedName("home_url") + private String homeUrl; + + /** + * 代开发自建应用的模式,0 = 代开发自建应用;1 = 第三方应用代开发 + */ + @SerializedName("app_type") + private Integer appType; + } + + /** + * 应用可见范围 + */ + @Data + public static class AllowUserInfos implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 应用可见范围(成员) + */ + @SerializedName("user") + private List users; + + /** + * 应用可见范围(部门) + */ + @SerializedName("department") + private List departments; + } + + /** + * 成员信息 + */ + @Data + public static class User implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 成员userid + */ + @SerializedName("userid") + private String userId; + } + + /** + * 部门信息 + */ + @Data + public static class Department implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 部门id + */ + @SerializedName("id") + private Integer id; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTemplateList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTemplateList.java new file mode 100644 index 000000000..83abbb6e7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpTemplateList.java @@ -0,0 +1,83 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 应用模板列表. + * + * @author Binary Wang + * created on 2026-01-14 + */ +@Data +public class WxCpTpTemplateList extends WxCpBaseResp { + + /** + * 应用模板列表 + */ + @SerializedName("template_list") + private List