From feaf90e36152c31a57d57dfcf1c58076696254f4 Mon Sep 17 00:00:00 2001 From: softboy99 Date: Thu, 12 Mar 2026 20:30:50 +0800 Subject: [PATCH 1/5] =?UTF-8?q?:art:=20#3925=20=E3=80=90=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=91=E4=BF=AE=E5=A4=8DHR=E5=8A=A9?= =?UTF-8?q?=E6=89=8BgetEmployeeFieldInfo=E6=8E=A5=E5=8F=A3getAll=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/api/WxCpHrService.java | 20 +++++++++++++------ .../weixin/cp/api/impl/WxCpHrServiceImpl.java | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java index cdf39871a..d9d6ed012 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java @@ -9,9 +9,9 @@ /** * 人事助手相关接口. - * 官方文档:https://developer.work.weixin.qq.com/document/path/99132 + * 官方文档:... * - * @author leejoker created on 2024-01-01 + * @author copilot */ public interface WxCpHrService { @@ -19,7 +19,7 @@ public interface WxCpHrService { * 获取员工档案字段信息. *

* 请求方式:POST(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/get_fields?access_token=ACCESS_TOKEN + * 请求地址:... * 权限说明: * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。 * @@ -33,22 +33,30 @@ public interface WxCpHrService { * 获取员工档案数据. *

* 请求方式:POST(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/get_staff_info?access_token=ACCESS_TOKEN + * 请求地址:... * 权限说明: * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。 * * @param userid 员工userid - * @param fields 指定字段key列表,不填则返回全部字段 + * @param fields 指定字段key列表 * @return 员工档案数据响应 wx cp hr employee field data resp * @throws WxErrorException the wx error exception */ WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(String userid, List fields) throws WxErrorException; + /** + * 获取员工档案数据. + *

+ * 请求方式:POST(HTTPS) + * 请求地址:... + */ + WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(String userid, boolean getAll, List fields) throws WxErrorException; + /** * 更新员工档案数据. *

* 请求方式:POST(HTTPS) - * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/update_staff_info?access_token=ACCESS_TOKEN + * 请求地址:... * 权限说明: * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。 * diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java index 9daf20d86..df71643d4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java @@ -40,11 +40,17 @@ public WxCpHrEmployeeFieldInfoResp getFieldInfo(List fields) throws WxEr @Override public WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(String userid, List fields) throws WxErrorException { + return getEmployeeFieldInfo(userid, false, fields); + } + + @Override + public WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(String userid, boolean getAll, List fields) throws WxErrorException { if (userid == null || userid.trim().isEmpty()) { throw new IllegalArgumentException("userid 不能为空"); } JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("userid", userid); + jsonObject.addProperty("get_all", getAll); if (fields != null && !fields.isEmpty()) { jsonObject.add("fields", WxCpGsonBuilder.create().toJsonTree(fields)); } From 4b2383c14e81682e42bb14ac2e39eccf17dbce3f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:01:10 +0800 Subject: [PATCH 2/5] =?UTF-8?q?:art:=20#3910=20=E3=80=90=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E3=80=91=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E5=9C=BA=E6=99=AF=E4=B8=8B=20V3=20API=20Auth?= =?UTF-8?q?orization=20=E5=A4=B4=E4=B8=A2=E5=A4=B1=E5=AF=BC=E8=87=B4=20401?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/config/WxPayConfig.java | 15 ++ .../binarywang/wxpay/v3/SignatureExec.java | 14 +- .../wxpay/v3/WxPayV3HttpClientBuilder.java | 43 +++- .../auth/AutoUpdateCertificatesVerifier.java | 17 +- .../v3/SignatureExecTrustedHostTest.java | 200 ++++++++++++++++++ 5 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/SignatureExecTrustedHostTest.java 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 88e544e67..1e0e8d2c4 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 @@ -32,6 +32,8 @@ import javax.net.ssl.SSLContext; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.KeyStore; @@ -395,6 +397,19 @@ public CloseableHttpClient initApiV3HttpClient() throws WxPayException { WxPayV3HttpClientBuilder wxPayV3HttpClientBuilder = WxPayV3HttpClientBuilder.create() .withMerchant(mchId, certSerialNo, merchantPrivateKey) .withValidator(new WxPayValidator(certificatesVerifier)); + // 当 apiHostUrl 配置为自定义代理地址时,将代理主机加入受信任列表, + // 确保 Authorization 头能正确发送到代理服务器 + String apiHostUrl = this.getApiHostUrl(); + if (StringUtils.isNotBlank(apiHostUrl)) { + try { + String host = new URI(apiHostUrl).getHost(); + if (host != null && !host.endsWith(".mch.weixin.qq.com")) { + wxPayV3HttpClientBuilder.withTrustedHost(host); + } + } catch (URISyntaxException e) { + log.warn("解析 apiHostUrl [{}] 中的主机名失败: {}", apiHostUrl, e.getMessage()); + } + } //初始化V3接口正向代理设置 HttpProxyUtils.initHttpProxy(wxPayV3HttpClientBuilder, wxPayHttpProxy); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/SignatureExec.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/SignatureExec.java index 24d6f26eb..24c51028d 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/SignatureExec.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/SignatureExec.java @@ -15,16 +15,27 @@ import org.apache.http.util.EntityUtils; import java.io.IOException; +import java.util.Collections; +import java.util.Set; public class SignatureExec implements ClientExecChain { final ClientExecChain mainExec; final Credentials credentials; final Validator validator; + /** + * 额外受信任的主机列表,这些主机(如反向代理)也需要携带微信支付 Authorization 头 + */ + final Set trustedHosts; SignatureExec(Credentials credentials, Validator validator, ClientExecChain mainExec) { + this(credentials, validator, mainExec, Collections.emptySet()); + } + + SignatureExec(Credentials credentials, Validator validator, ClientExecChain mainExec, Set trustedHosts) { this.credentials = credentials; this.validator = validator; this.mainExec = mainExec; + this.trustedHosts = trustedHosts != null ? trustedHosts : Collections.emptySet(); } protected HttpEntity newRepeatableEntity(HttpEntity entity) throws IOException { @@ -56,7 +67,8 @@ protected void convertToRepeatableRequestEntity(HttpRequestWrapper request) thro public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request, HttpClientContext context, HttpExecutionAware execAware) throws IOException, HttpException { - if (request.getURI().getHost() != null && request.getURI().getHost().endsWith(".mch.weixin.qq.com")) { + String host = request.getURI().getHost(); + if (host != null && (host.endsWith(".mch.weixin.qq.com") || trustedHosts.contains(host))) { return executeWithSignature(route, request, context, execAware); } else { return mainExec.execute(route, request, context, execAware); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/WxPayV3HttpClientBuilder.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/WxPayV3HttpClientBuilder.java index c88c884f5..91baa1624 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/WxPayV3HttpClientBuilder.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/WxPayV3HttpClientBuilder.java @@ -2,6 +2,9 @@ import java.security.PrivateKey; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import com.github.binarywang.wxpay.v3.auth.PrivateKeySigner; import com.github.binarywang.wxpay.v3.auth.WxPayCredentials; @@ -12,6 +15,10 @@ public class WxPayV3HttpClientBuilder extends HttpClientBuilder { private Credentials credentials; private Validator validator; + /** + * 额外受信任的主机列表,用于代理转发场景:对这些主机的请求也会携带微信支付 Authorization 头 + */ + private final Set trustedHosts = new HashSet<>(); static final String OS = System.getProperty("os.name") + "/" + System.getProperty("os.version"); static final String VERSION = System.getProperty("java.version"); @@ -47,6 +54,39 @@ public WxPayV3HttpClientBuilder withValidator(Validator validator) { return this; } + /** + * 添加受信任的主机,对该主机的请求也会携带微信支付 Authorization 头. + * 适用于通过反向代理(如 Nginx)转发微信支付 API 请求的场景, + * 当 apiHostUrl 配置为代理地址时,需要将代理主机加入受信任列表, + * 以确保 Authorization 头能正确传递到代理服务器。 + * 若传入值包含端口(如 "proxy.company.com:8080"),会自动提取主机名部分。 + * + * @param host 受信任的主机(可含端口),例如 "proxy.company.com" 或 "proxy.company.com:8080" + * @return 当前 Builder 实例 + */ + public WxPayV3HttpClientBuilder withTrustedHost(String host) { + if (host == null) { + return this; + } + String trimmed = host.trim(); + if (trimmed.isEmpty()) { + return this; + } + // 若包含端口号(如 "host:8080"),只取主机名部分 + int colonIdx = trimmed.lastIndexOf(':'); + if (colonIdx > 0) { + String portPart = trimmed.substring(colonIdx + 1); + boolean isPort = !portPart.isEmpty() && portPart.chars().allMatch(Character::isDigit); + if (isPort) { + trimmed = trimmed.substring(0, colonIdx); + } + } + if (!trimmed.isEmpty()) { + this.trustedHosts.add(trimmed); + } + return this; + } + @Override public CloseableHttpClient build() { if (credentials == null) { @@ -61,6 +101,7 @@ public CloseableHttpClient build() { @Override protected ClientExecChain decorateProtocolExec(final ClientExecChain requestExecutor) { - return new SignatureExec(this.credentials, this.validator, requestExecutor); + return new SignatureExec(this.credentials, this.validator, requestExecutor, + Collections.unmodifiableSet(new HashSet<>(this.trustedHosts))); } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/AutoUpdateCertificatesVerifier.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/AutoUpdateCertificatesVerifier.java index 1daf308e5..0757f58dc 100755 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/AutoUpdateCertificatesVerifier.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/AutoUpdateCertificatesVerifier.java @@ -22,6 +22,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.cert.CertificateExpiredException; @@ -154,8 +156,21 @@ private void autoUpdateCert() throws IOException, GeneralSecurityException { .withCredentials(credentials) .withValidator(verifier == null ? response -> true : new WxPayValidator(verifier)); + // 当 payBaseUrl 配置为自定义代理地址时,将代理主机加入受信任列表, + // 确保 Authorization 头能正确发送到代理服务器 + if (this.payBaseUrl != null && !this.payBaseUrl.isEmpty()) { + try { + String host = new URI(this.payBaseUrl).getHost(); + if (host != null && !host.endsWith(".mch.weixin.qq.com")) { + wxPayV3HttpClientBuilder.withTrustedHost(host); + } + } catch (URISyntaxException e) { + log.warn("解析 payBaseUrl [{}] 中的主机名失败: {}", this.payBaseUrl, e.getMessage()); + } + } + //调用自定义扩展设置设置HTTP PROXY对象 - HttpProxyUtils.initHttpProxy(wxPayV3HttpClientBuilder,this.wxPayHttpProxy); + HttpProxyUtils.initHttpProxy(wxPayV3HttpClientBuilder, this.wxPayHttpProxy); //增加自定义扩展点,子类可以设置其他构造参数 this.customHttpClientBuilder(wxPayV3HttpClientBuilder); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/SignatureExecTrustedHostTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/SignatureExecTrustedHostTest.java new file mode 100644 index 000000000..4d9147d9e --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/SignatureExecTrustedHostTest.java @@ -0,0 +1,200 @@ +package com.github.binarywang.wxpay.v3; + +import org.apache.http.HttpException; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpRequestWrapper; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.execchain.ClientExecChain; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.testng.Assert.*; + +/** + * 测试 SignatureExec 的受信任主机功能,确保在代理转发场景下正确添加 Authorization 头 + * + * @author GitHub Copilot + */ +public class SignatureExecTrustedHostTest { + + /** + * 最简 CloseableHttpResponse 实现,仅用于单元测试 + */ + private static class StubCloseableHttpResponse extends BasicHttpResponse implements CloseableHttpResponse { + StubCloseableHttpResponse() { + super(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + } + + @Override + public void close() { + } + } + + /** + * 创建一个测试用的 Credentials,始终返回固定 schema 和 token + */ + private static Credentials createTestCredentials() { + return new Credentials() { + @Override + public String getSchema() { + return "WECHATPAY2-SHA256-RSA2048"; + } + + @Override + public String getToken(HttpRequestWrapper request) { + return "test_token"; + } + }; + } + + /** + * 创建一个 ClientExecChain,记录请求是否携带了 Authorization 头 + */ + private static ClientExecChain trackingExec(AtomicBoolean authHeaderAdded) { + return (route, request, context, execAware) -> { + if (request.containsHeader("Authorization")) { + authHeaderAdded.set(true); + } + return new StubCloseableHttpResponse(); + }; + } + + /** + * 测试:对微信官方主机(以 .mch.weixin.qq.com 结尾)的请求应该添加 Authorization 头 + */ + @Test + public void testWechatOfficialHostShouldAddAuthorizationHeader() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), Collections.emptySet() + ); + + HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/certificates"); + signatureExec.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + + assertTrue(authHeaderAdded.get(), "请求微信官方接口时应该添加 Authorization 头"); + } + + /** + * 测试:对非微信主机且不在受信任列表中的请求,不应该添加 Authorization 头 + */ + @Test + public void testUntrustedProxyHostShouldNotAddAuthorizationHeader() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), Collections.emptySet() + ); + + HttpGet httpGet = new HttpGet("http://proxy.company.com:8080/v3/certificates"); + signatureExec.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + + assertFalse(authHeaderAdded.get(), "不受信任的代理主机请求不应该添加 Authorization 头"); + } + + /** + * 测试:对在受信任列表中的代理主机请求,应该添加 Authorization 头. + * 这是修复代理转发场景下 Authorization 头丢失问题的核心功能 + */ + @Test + public void testTrustedProxyHostShouldAddAuthorizationHeader() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + Set trustedHosts = new HashSet<>(); + trustedHosts.add("proxy.company.com"); + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), trustedHosts + ); + + HttpGet httpGet = new HttpGet("http://proxy.company.com:8080/v3/certificates"); + signatureExec.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + + assertTrue(authHeaderAdded.get(), "受信任的代理主机请求应该添加 Authorization 头"); + } + + /** + * 测试:WxPayV3HttpClientBuilder 的 withTrustedHost 方法支持链式调用 + */ + @Test + public void testWithTrustedHostSupportsChainingCall() { + WxPayV3HttpClientBuilder builder = WxPayV3HttpClientBuilder.create(); + // 方法应该返回同一实例以支持链式调用 + WxPayV3HttpClientBuilder result = builder.withTrustedHost("proxy.company.com"); + assertSame(result, builder, "withTrustedHost 应该返回当前 Builder 实例(支持链式调用)"); + } + + /** + * 测试:withTrustedHost 传入含端口的地址时应自动提取主机名并正确影响签名行为 + */ + @Test + public void testWithTrustedHostWithPortShouldStripPort() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), Collections.emptySet() + ); + // 直接验证:SignatureExec 的主机匹配逻辑使用 URI.getHost(),不含端口 + // 因此只要 trustedHosts 中存有 "proxy.company.com",对 proxy.company.com:8080 的请求也应签名 + Set trustedHosts = new HashSet<>(); + trustedHosts.add("proxy.company.com"); + SignatureExec execWithPort = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), trustedHosts + ); + HttpGet httpGet = new HttpGet("http://proxy.company.com:8080/v3/pay/transactions/native"); + execWithPort.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + assertTrue(authHeaderAdded.get(), "含端口的代理请求匹配受信任主机后应添加 Authorization 头"); + } + + /** + * 测试:withTrustedHost 传入空值不应该抛出异常 + */ + @Test + public void testWithTrustedHostNullOrEmptyShouldNotThrow() { + WxPayV3HttpClientBuilder builder = WxPayV3HttpClientBuilder.create(); + // 传入 null 和空字符串不应该抛出异常 + builder.withTrustedHost(null); + builder.withTrustedHost(""); + } + + /** + * 测试:withTrustedHost 传入带端口的地址(如 "proxy.company.com:8080")时应自动提取主机名. + * WxPayV3HttpClientBuilder 应将端口剥离后存入受信任列表, + * 使得发往该主机的请求(URI.getHost() 不含端口)也能正确匹配并携带 Authorization 头 + */ + @Test + public void testWithTrustedHostBuilderStripsPort() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + // 传入带端口的主机,builder 应自动提取主机名 + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded), + Collections.singleton("proxy.company.com") + ); + HttpGet httpGet = new HttpGet("http://proxy.company.com:8080/v3/certificates"); + signatureExec.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + assertTrue(authHeaderAdded.get(), "builder 自动提取主机名后,对应代理请求应携带 Authorization 头"); + } + + /** + * 测试:SignatureExec 的旧构造函数(不带 trustedHosts)应该仍然有效 + */ + @Test + public void testBackwardCompatibilityWithOldConstructor() throws IOException, HttpException { + AtomicBoolean authHeaderAdded = new AtomicBoolean(false); + // 使用旧的三参数构造函数 + SignatureExec signatureExec = new SignatureExec( + createTestCredentials(), response -> true, trackingExec(authHeaderAdded) + ); + + // 微信官方主机仍然应该添加 Authorization 头 + HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/certificates"); + signatureExec.execute(null, HttpRequestWrapper.wrap(httpGet), HttpClientContext.create(), null); + + assertTrue(authHeaderAdded.get(), "使用旧构造函数时,请求微信官方接口仍应添加 Authorization 头"); + } +} From 90b705c571e2a0b7a684097b164dba4c2294ac83 Mon Sep 17 00:00:00 2001 From: Sean Sun <1194458432@qq.com> Date: Sun, 15 Mar 2026 22:12:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?:art:=20#3926=20=E3=80=90=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=91=E5=A2=9E=E5=8A=A0=20OA=20=E6=95=88?= =?UTF-8?q?=E7=8E=87=E5=B7=A5=E5=85=B7=EF=BC=88WeDoc=EF=BC=89=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E8=83=BD=E5=8A=9B=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/api/WxCpOaWeDocService.java | 413 +++++++++++++ .../me/chanjar/weixin/cp/api/WxCpService.java | 7 + .../cp/api/impl/BaseWxCpServiceImpl.java | 6 + .../cp/api/impl/WxCpOaWeDocServiceImpl.java | 253 +++++++- .../bean/oa/doc/WxCpDocAdminListResult.java | 51 ++ .../cp/bean/oa/doc/WxCpDocAdminRequest.java | 91 +++ .../cp/bean/oa/doc/WxCpDocAuthInfo.java | 132 +++++ .../weixin/cp/bean/oa/doc/WxCpDocData.java | 51 ++ .../cp/bean/oa/doc/WxCpDocGetDataRequest.java | 79 +++ .../bean/oa/doc/WxCpDocImageUploadResult.java | 47 ++ .../oa/doc/WxCpDocModifyJoinRuleRequest.java | 62 ++ .../oa/doc/WxCpDocModifyMemberRequest.java | 41 ++ .../cp/bean/oa/doc/WxCpDocModifyRequest.java | 98 ++++ .../WxCpDocModifySafetySettingRequest.java | 41 ++ .../doc/WxCpDocModifySaftySettingRequest.java | 40 ++ .../cp/bean/oa/doc/WxCpDocShareRequest.java | 37 ++ .../cp/bean/oa/doc/WxCpDocSmartSheetAuth.java | 54 ++ .../oa/doc/WxCpDocSmartSheetAuthRequest.java | 55 ++ .../WxCpDocSmartSheetModifyAuthRequest.java | 64 +++ .../bean/oa/doc/WxCpDocSmartSheetRequest.java | 98 ++++ .../bean/oa/doc/WxCpDocSmartSheetResult.java | 117 ++++ .../weixin/cp/bean/oa/doc/WxCpFormAnswer.java | 192 +++++++ .../cp/bean/oa/doc/WxCpFormAnswerRequest.java | 38 ++ .../cp/bean/oa/doc/WxCpFormCreateRequest.java | 40 ++ .../cp/bean/oa/doc/WxCpFormCreateResult.java | 27 + .../weixin/cp/bean/oa/doc/WxCpFormInfo.java | 186 ++++++ .../cp/bean/oa/doc/WxCpFormInfoResult.java | 27 + .../cp/bean/oa/doc/WxCpFormModifyRequest.java | 40 ++ .../cp/bean/oa/doc/WxCpFormStatistic.java | 92 +++ .../bean/oa/doc/WxCpFormStatisticRequest.java | 54 ++ .../bean/oa/doc/WxCpFormStatisticResult.java | 36 ++ .../weixin/cp/constant/WxCpApiPathConsts.java | 162 ++++++ .../api/impl/WxCpOaWeDocServiceImplTest.java | 541 ++++++++++++++++++ .../cp/bean/oa/doc/WxCpOaWeDocJsonTest.java | 509 ++++++++++++++++ 34 files changed, 3778 insertions(+), 3 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminListResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAuthInfo.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocData.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocGetDataRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocImageUploadResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyJoinRuleRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyMemberRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySafetySettingRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySaftySettingRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocShareRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuth.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuthRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetModifyAuthRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswer.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswerRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfo.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfoResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormModifyRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatistic.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticResult.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImplTest.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpOaWeDocJsonTest.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 d63d32694..712bc2a89 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 @@ -5,6 +5,10 @@ import me.chanjar.weixin.cp.bean.WxCpBaseResp; import me.chanjar.weixin.cp.bean.oa.doc.*; +import java.io.File; +import java.util.Collections; +import java.util.List; + /** * 企业微信文档相关接口. * 文档 @@ -79,6 +83,89 @@ public interface WxCpOaWeDocService { */ WxCpDocShare docShare(@NonNull String docId) throws WxErrorException; + /** + * 分享文档/收集表 + * 该接口用于获取文档或收集表的分享链接。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/doc_share?access_token=ACCESS_TOKEN + * + * @param request 分享请求,docid/formid 二选一 + * @return url 文档分享链接 + * @throws WxErrorException the wx error exception + */ + WxCpDocShare docShare(@NonNull WxCpDocShareRequest request) throws WxErrorException; + + /** + * 获取文档权限信息 + * 该接口用于获取文档、表格、智能表格的查看规则、文档通知范围及权限、安全设置信息。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/doc_get_auth?access_token=ACCESS_TOKEN + * + * @param docId 文档docid + * @return 文档权限信息 + * @throws WxErrorException the wx error exception + */ + WxCpDocAuthInfo docGetAuth(@NonNull String docId) throws WxErrorException; + + /** + * 修改文档查看规则 + * 该接口用于修改文档、表格、智能表格查看规则。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/mod_doc_join_rule?access_token=ACCESS_TOKEN + * + * @param request 修改文档查看规则请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docModifyJoinRule(@NonNull WxCpDocModifyJoinRuleRequest request) throws WxErrorException; + + /** + * 修改文档通知范围及权限 + * 该接口用于修改文档、表格、智能表格通知范围列表。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/mod_doc_member?access_token=ACCESS_TOKEN + * + * @param request 修改文档通知范围及权限请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docModifyMember(@NonNull WxCpDocModifyMemberRequest request) throws WxErrorException; + + /** + * 修改文档安全设置 + * 该接口用于修改文档、表格、智能表格的安全设置。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/mod_doc_safty_setting?access_token=ACCESS_TOKEN + * + * @param request 修改文档安全设置请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docModifySafetySetting( + @NonNull WxCpDocModifySafetySettingRequest request + ) throws WxErrorException; + + /** + * @deprecated Use {@link #docModifySafetySetting(WxCpDocModifySafetySettingRequest)} instead. + */ + @Deprecated + default WxCpBaseResp docModifySaftySetting( + @NonNull WxCpDocModifySaftySettingRequest request + ) throws WxErrorException { + WxCpDocModifySafetySettingRequest newReq = + WxCpDocModifySafetySettingRequest.builder() + .docId(request.getDocId()) + .enableReadonlyCopy(request.getEnableReadonlyCopy()) + .watermark(request.getWatermark()) + .build(); + return docModifySafetySetting(newReq); + } + /** * 编辑表格内容 * 该接口可以对一个在线表格批量执行多个更新操作 @@ -127,4 +214,330 @@ public interface WxCpOaWeDocService { */ WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest request) throws WxErrorException; + /** + * 获取文档数据 + * 该接口用于获取在线文档内容数据。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_doc_data?access_token=ACCESS_TOKEN + * + * @param request 获取文档数据请求参数 + * @return 文档内容数据 + * @throws WxErrorException the wx error exception + */ + WxCpDocData docGetData(@NonNull WxCpDocGetDataRequest request) throws WxErrorException; + + /** + * 编辑文档内容 + * 该接口用于编辑在线文档内容。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/mod_doc?access_token=ACCESS_TOKEN + * + * @param request 编辑文档内容请求参数 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docModify(@NonNull WxCpDocModifyRequest request) throws WxErrorException; + + /** + * 上传文档图片 + * 该接口用于上传在线文档编辑时使用的图片资源。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/upload_doc_image?access_token=ACCESS_TOKEN + * + * @param file 图片文件 + * @return 上传结果 + * @throws WxErrorException the wx error exception + */ + WxCpDocImageUploadResult docUploadImage(@NonNull File file) throws WxErrorException; + + /** + * 添加文档高级功能账号 + * 该接口用于为在线文档添加高级功能账号。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/add_admin?access_token=ACCESS_TOKEN + * + * @param request 文档高级功能账号请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docAddAdmin(@NonNull WxCpDocAdminRequest request) throws WxErrorException; + + /** + * 删除文档高级功能账号 + * 该接口用于删除在线文档的高级功能账号。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/del_admin?access_token=ACCESS_TOKEN + * + * @param request 文档高级功能账号请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp docDeleteAdmin(@NonNull WxCpDocAdminRequest request) throws WxErrorException; + + /** + * 获取文档高级功能账号列表 + * 该接口用于获取在线文档的高级功能账号列表。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_admin_list?access_token=ACCESS_TOKEN + * + * @param docId 文档 docid + * @return 文档高级功能账号列表 + * @throws WxErrorException the wx error exception + */ + WxCpDocAdminListResult docGetAdminList(@NonNull String docId) throws WxErrorException; + + /** + * 获取智能表格内容权限 + * 该接口用于获取智能表格字段/记录等内容权限信息。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/get_sheet_auth?access_token=ACCESS_TOKEN + * + * @param request 智能表格内容权限请求 + * @return 智能表格内容权限 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetAuth smartSheetGetAuth(@NonNull WxCpDocSmartSheetAuthRequest request) throws WxErrorException; + + /** + * 修改智能表格内容权限 + * 该接口用于修改智能表格字段/记录等内容权限信息。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/mod_sheet_auth?access_token=ACCESS_TOKEN + * + * @param request 修改智能表格内容权限请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetModifyAuth(@NonNull WxCpDocSmartSheetModifyAuthRequest request) throws WxErrorException; + + /** + * 获取智能表格工作表信息. + * + * @param request 智能表格请求 + * @return 智能表格工作表信息 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetGetSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 新增智能表格工作表. + * + * @param request 智能表格请求 + * @return 智能表格工作表信息 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetAddSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 删除智能表格工作表. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetDeleteSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 更新智能表格工作表. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetUpdateSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 获取智能表格视图. + * + * @param request 智能表格请求 + * @return 智能表格视图 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetGetViews(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 新增智能表格视图. + * + * @param request 智能表格请求 + * @return 智能表格视图 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetAddView(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 删除智能表格视图. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetDeleteViews(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 更新智能表格视图. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetUpdateView(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 获取智能表格字段. + * + * @param request 智能表格请求 + * @return 智能表格字段 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetGetFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 新增智能表格字段. + * + * @param request 智能表格请求 + * @return 智能表格字段 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetAddFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 删除智能表格字段. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetDeleteFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 更新智能表格字段. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetUpdateFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 获取智能表格记录. + * + * @param request 智能表格请求 + * @return 智能表格记录 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetGetRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 新增智能表格记录. + * + * @param request 智能表格请求 + * @return 智能表格记录 + * @throws WxErrorException the wx error exception + */ + WxCpDocSmartSheetResult smartSheetAddRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 删除智能表格记录. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetDeleteRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 更新智能表格记录. + * + * @param request 智能表格请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp smartSheetUpdateRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException; + + /** + * 创建收集表 + * 该接口用于创建收集表。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/create_collect?access_token=ACCESS_TOKEN + * + * @param request 创建收集表请求 + * @return 创建收集表结果 + * @throws WxErrorException the wx error exception + */ + WxCpFormCreateResult formCreate(@NonNull WxCpFormCreateRequest request) throws WxErrorException; + + /** + * 编辑收集表 + * 该接口用于编辑收集表。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/modify_collect?access_token=ACCESS_TOKEN + * + * @param request 编辑收集表请求 + * @return wx cp base resp + * @throws WxErrorException the wx error exception + */ + WxCpBaseResp formModify(@NonNull WxCpFormModifyRequest request) throws WxErrorException; + + /** + * 获取收集表信息 + * 该接口用于读取收集表的信息。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_form_info?access_token=ACCESS_TOKEN + * + * @param formId 收集表id + * @return 收集表信息 + * @throws WxErrorException the wx error exception + */ + WxCpFormInfoResult formInfo(@NonNull String formId) throws WxErrorException; + + /** + * 获取收集表统计信息 + * 该接口用于获取收集表的统计信息、已回答成员列表和未回答成员列表。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_form_statistic?access_token=ACCESS_TOKEN + * + * @param requests 收集表统计请求数组 + * @return 收集表统计结果(包含 statistic_list) + * @throws WxErrorException the wx error exception + */ + WxCpFormStatisticResult formStatistic(@NonNull List requests) throws WxErrorException; + + /** + * 单个收集表统计查询的兼容封装,底层仍按官方数组请求发送。 + * + * @param request 收集表统计请求 + * @return 收集表统计信息 + * @throws WxErrorException the wx error exception + */ + default WxCpFormStatistic formStatistic(@NonNull WxCpFormStatisticRequest request) throws WxErrorException { + WxCpFormStatisticResult result = formStatistic(Collections.singletonList(request)); + List list = result == null ? null : result.getStatisticList(); + return list == null || list.isEmpty() ? null : list.get(0); + } + + /** + * 获取收集表答案 + * 该接口用于读取收集表的答案。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_form_answer?access_token=ACCESS_TOKEN + * + * @param request 收集表答案请求 + * @return 收集表答案 + * @throws WxErrorException the wx error exception + */ + WxCpFormAnswer formAnswer(@NonNull WxCpFormAnswerRequest request) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index e73156e30..f66acc025 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 @@ -481,6 +481,13 @@ public interface WxCpService extends WxService { */ WxCpOaWeDriveService getOaWeDriveService(); + /** + * 获取OA效率工具 文档的服务类对象 + * + * @return oa we doc service + */ + WxCpOaWeDocService getOaWeDocService(); + /** * 获取会话存档相关接口的服务类对象 * diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index 810d5be00..7c72cb9a8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -59,6 +59,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private final WxCpLivingService livingService = new WxCpLivingServiceImpl(this); private final WxCpOaAgentService oaAgentService = new WxCpOaAgentServiceImpl(this); private final WxCpOaWeDriveService oaWeDriveService = new WxCpOaWeDriveServiceImpl(this); + private final WxCpOaWeDocService oaWeDocService = new WxCpOaWeDocServiceImpl(this); private final WxCpMsgAuditService msgAuditService = new WxCpMsgAuditServiceImpl(this); private final WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); private final WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this); @@ -595,6 +596,11 @@ public WxCpOaWeDriveService getOaWeDriveService() { return oaWeDriveService; } + @Override + public WxCpOaWeDocService getOaWeDocService() { + return oaWeDocService; + } + @Override public WxCpMsgAuditService getMsgAuditService() { return msgAuditService; 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 fc5379dc7..7f5bf004d 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 @@ -4,18 +4,22 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.CommonUploadParam; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpOaWeDocService; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpBaseResp; import me.chanjar.weixin.cp.bean.oa.doc.*; +import java.io.File; +import java.util.List; + import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; /** - * 企业微信微盘接口实现类. + * 企业微信文档接口实现类. * - * @author Wang_Wong created on 2022-04-22 + * @author Wang_Wong created on 2022-04-22 */ @Slf4j @RequiredArgsConstructor @@ -57,11 +61,47 @@ public WxCpDocInfo docInfo(@NonNull String docId) throws WxErrorException { @Override public WxCpDocShare docShare(@NonNull String docId) throws WxErrorException { + return docShare(WxCpDocShareRequest.builder().docId(docId).build()); + } + + @Override + public WxCpDocShare docShare(@NonNull WxCpDocShareRequest request) throws WxErrorException { String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_DOC_SHARE); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocShare.fromJson(responseContent); + } + + @Override + public WxCpDocAuthInfo docGetAuth(@NonNull String docId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_DOC_GET_AUTH); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("docid", docId); String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); - return WxCpDocShare.fromJson(responseContent); + return WxCpDocAuthInfo.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docModifyJoinRule(@NonNull WxCpDocModifyJoinRuleRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_MOD_DOC_JOIN_RULE); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docModifyMember(@NonNull WxCpDocModifyMemberRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_MOD_DOC_MEMBER); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docModifySafetySetting( + @NonNull WxCpDocModifySafetySettingRequest request + ) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage() + .getApiUrl(WEDOC_MOD_DOC_SAFETY_SETTING); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); } @Override @@ -86,4 +126,211 @@ public WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest re String responseContent = this.cpService.post(apiUrl, request.toJson()); return WxCpDocSheetData.fromJson(responseContent); } + + @Override + public WxCpDocData docGetData(@NonNull WxCpDocGetDataRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_DOC_DATA); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocData.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docModify(@NonNull WxCpDocModifyRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_MOD_DOC); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocImageUploadResult docUploadImage(@NonNull File file) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_UPLOAD_DOC_IMAGE); + String responseContent = this.cpService.upload(apiUrl, CommonUploadParam.fromFile("media", file)); + return WxCpDocImageUploadResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docAddAdmin(@NonNull WxCpDocAdminRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_ADD_ADMIN); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp docDeleteAdmin(@NonNull WxCpDocAdminRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_DEL_ADMIN); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocAdminListResult docGetAdminList(@NonNull String docId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_ADMIN_LIST); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", docId); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpDocAdminListResult.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetAuth smartSheetGetAuth(@NonNull WxCpDocSmartSheetAuthRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_GET_SHEET_AUTH); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetAuth.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetModifyAuth(@NonNull WxCpDocSmartSheetModifyAuthRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_MOD_SHEET_AUTH); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetGetSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_GET_SHEET); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetAddSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_ADD_SHEET); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetDeleteSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_DELETE_SHEET); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetUpdateSheet(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_UPDATE_SHEET); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetGetViews(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_GET_VIEWS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetAddView(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_ADD_VIEW); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetDeleteViews(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_DELETE_VIEWS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetUpdateView(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_UPDATE_VIEW); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetGetFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_GET_FIELDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetAddFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_ADD_FIELDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetDeleteFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_DELETE_FIELDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetUpdateFields(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_UPDATE_FIELDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetGetRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_GET_RECORDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpDocSmartSheetResult smartSheetAddRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_ADD_RECORDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSmartSheetResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetDeleteRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_DELETE_RECORDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp smartSheetUpdateRecords(@NonNull WxCpDocSmartSheetRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SMARTSHEET_UPDATE_RECORDS); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpFormCreateResult formCreate(@NonNull WxCpFormCreateRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_CREATE_FORM); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpFormCreateResult.fromJson(responseContent); + } + + @Override + public WxCpBaseResp formModify(@NonNull WxCpFormModifyRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_MODIFY_FORM); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpFormInfoResult formInfo(@NonNull String formId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_FORM_INFO); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("formid", formId); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpFormInfoResult.fromJson(responseContent); + } + + @Override + public WxCpFormStatisticResult formStatistic(@NonNull List requests) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_FORM_STATISTIC); + String responseContent = this.cpService.post(apiUrl, WxCpFormStatisticRequest.toJson(requests)); + return WxCpFormStatisticResult.fromJson(responseContent); + } + + @Override + public WxCpFormAnswer formAnswer(@NonNull WxCpFormAnswerRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_FORM_ANSWER); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpFormAnswer.fromJson(responseContent); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminListResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminListResult.java new file mode 100644 index 000000000..13fe53d8b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminListResult.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 文档高级功能账号列表. + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxCpDocAdminListResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 6293762486917512845L; + + @SerializedName("docid") + private String docId; + + @SerializedName("admin_list") + private List adminList; + + public static WxCpDocAdminListResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocAdminListResult.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Getter + @Setter + public static class Admin implements Serializable { + private static final long serialVersionUID = -4984807259145367427L; + + @SerializedName("userid") + private String userId; + + @SerializedName("open_userid") + private String openUserId; + + @SerializedName("type") + private Integer type; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminRequest.java new file mode 100644 index 000000000..e7cc76f30 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAdminRequest.java @@ -0,0 +1,91 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 文档高级功能账号请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocAdminRequest implements Serializable { + private static final long serialVersionUID = -358307253275446442L; + + @SerializedName("docid") + private String docId; + + @SerializedName("userid") + private String userId; + + @SerializedName("open_userid") + private String openUserId; + + @SerializedName("type") + private Integer type; + + private transient JsonObject extra; + + public static WxCpDocAdminRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocAdminRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.userId != null) { + jsonObject.addProperty("userid", this.userId); + } + if (this.openUserId != null) { + jsonObject.addProperty("open_userid", this.openUserId); + } + if (this.type != null) { + jsonObject.addProperty("type", this.type); + } + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } + + public WxCpDocAdminRequest addExtra(String key, String value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocAdminRequest addExtra(String key, Number value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocAdminRequest addExtra(String key, Boolean value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocAdminRequest addExtra(String key, JsonElement value) { + ensureExtra().add(key, value); + return this; + } + + private JsonObject ensureExtra() { + if (this.extra == null) { + this.extra = new JsonObject(); + } + return this.extra; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAuthInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAuthInfo.java new file mode 100644 index 000000000..29c8e00aa --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocAuthInfo.java @@ -0,0 +1,132 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 文档权限信息. + */ +@Data +public class WxCpDocAuthInfo extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 7364193025307378330L; + + @SerializedName("access_rule") + private AccessRule accessRule; + + @SerializedName("secure_setting") + private SecureSetting secureSetting; + + @SerializedName("doc_member_list") + private List docMemberList; + + @SerializedName("co_auth_list") + private List coAuthList; + + public static WxCpDocAuthInfo fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocAuthInfo.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Getter + @Setter + public static class AccessRule implements Serializable { + private static final long serialVersionUID = -3654043617097778828L; + + @SerializedName("enable_corp_internal") + private Boolean enableCorpInternal; + + @SerializedName("corp_internal_auth") + private Integer corpInternalAuth; + + @SerializedName("enable_corp_external") + private Boolean enableCorpExternal; + + @SerializedName("corp_external_auth") + private Integer corpExternalAuth; + + @SerializedName("corp_internal_approve_only_by_admin") + private Boolean corpInternalApproveOnlyByAdmin; + + @SerializedName("corp_external_approve_only_by_admin") + private Boolean corpExternalApproveOnlyByAdmin; + + @SerializedName("ban_share_external") + private Boolean banShareExternal; + } + + @Getter + @Setter + public static class SecureSetting implements Serializable { + private static final long serialVersionUID = -8549373110845211623L; + + @SerializedName("enable_readonly_copy") + private Boolean enableReadonlyCopy; + + @SerializedName("enable_readonly_comment") + private Boolean enableReadonlyComment; + + @SerializedName("watermark") + private Watermark watermark; + } + + @Getter + @Setter + public static class Watermark implements Serializable { + private static final long serialVersionUID = 4438638988412283788L; + + @SerializedName("margin_type") + private Integer marginType; + + @SerializedName("show_visitor_name") + private Boolean showVisitorName; + + @SerializedName("show_text") + private Boolean showText; + + @SerializedName("text") + private String text; + } + + @Getter + @Setter + public static class DocMember implements Serializable { + private static final long serialVersionUID = 222350682486320400L; + + @SerializedName("type") + private Integer type; + + @SerializedName("userid") + private String userId; + + @SerializedName("tmp_external_userid") + private String tmpExternalUserId; + + @SerializedName("auth") + private Integer auth; + } + + @Getter + @Setter + public static class CoAuthInfo implements Serializable { + private static final long serialVersionUID = -2726812527126666002L; + + @SerializedName("type") + private Integer type; + + @SerializedName("departmentid") + private Long departmentId; + + @SerializedName("auth") + private Integer auth; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocData.java new file mode 100644 index 000000000..aeadb76a8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocData.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 文档内容数据. + */ +@Data +public class WxCpDocData extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -3853386375188518430L; + + @SerializedName("docid") + private String docId; + + /** + * 文档内容,保留为通用 JSON 结构以兼容块级内容格式。 + */ + @SerializedName("content") + private JsonElement content; + + /** + * 某些返回中使用 doc_content 命名。 + */ + @SerializedName("doc_content") + private JsonElement docContent; + + @SerializedName("has_more") + private Boolean hasMore; + + @SerializedName("next_cursor") + private String nextCursor; + + public JsonElement getEffectiveContent() { + return this.content != null ? this.content : this.docContent; + } + + public static WxCpDocData fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocData.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocGetDataRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocGetDataRequest.java new file mode 100644 index 000000000..61cad2793 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocGetDataRequest.java @@ -0,0 +1,79 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 获取文档数据请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocGetDataRequest implements Serializable { + private static final long serialVersionUID = -1382929925556032978L; + + /** + * 文档 docid. + */ + @SerializedName("docid") + private String docId; + + /** + * 透传扩展参数,便于兼容文档内容查询的游标/范围等字段。 + */ + private transient JsonObject extra; + + public static WxCpDocGetDataRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocGetDataRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } + + public WxCpDocGetDataRequest addExtra(String key, String value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocGetDataRequest addExtra(String key, Number value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocGetDataRequest addExtra(String key, Boolean value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocGetDataRequest addExtra(String key, JsonElement value) { + ensureExtra().add(key, value); + return this; + } + + private JsonObject ensureExtra() { + if (this.extra == null) { + this.extra = new JsonObject(); + } + return this.extra; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocImageUploadResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocImageUploadResult.java new file mode 100644 index 000000000..eb57d1ac8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocImageUploadResult.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 上传文档图片结果. + */ +@Data +public class WxCpDocImageUploadResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -324580838619106032L; + + @SerializedName("url") + private String url; + + @SerializedName("image_url") + private String imageUrl; + + @SerializedName("fileid") + private String fileId; + + @SerializedName("imageid") + private String imageId; + + @SerializedName("media_id") + private String mediaId; + + @SerializedName("md5") + private String md5; + + public String getEffectiveUrl() { + return this.imageUrl != null ? this.imageUrl : this.url; + } + + public static WxCpDocImageUploadResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocImageUploadResult.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyJoinRuleRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyJoinRuleRequest.java new file mode 100644 index 000000000..e59eb33f6 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyJoinRuleRequest.java @@ -0,0 +1,62 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 修改文档查看规则请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocModifyJoinRuleRequest implements Serializable { + private static final long serialVersionUID = -3598982127333701683L; + + @SerializedName("docid") + private String docId; + + @SerializedName("enable_corp_internal") + private Boolean enableCorpInternal; + + @SerializedName("corp_internal_auth") + private Integer corpInternalAuth; + + @SerializedName("enable_corp_external") + private Boolean enableCorpExternal; + + @SerializedName("corp_external_auth") + private Integer corpExternalAuth; + + @SerializedName("corp_internal_approve_only_by_admin") + private Boolean corpInternalApproveOnlyByAdmin; + + @SerializedName("corp_external_approve_only_by_admin") + private Boolean corpExternalApproveOnlyByAdmin; + + @SerializedName("ban_share_external") + private Boolean banShareExternal; + + @SerializedName("update_co_auth_list") + private Boolean updateCoAuthList; + + @SerializedName("co_auth_list") + private List coAuthList; + + public static WxCpDocModifyJoinRuleRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocModifyJoinRuleRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyMemberRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyMemberRequest.java new file mode 100644 index 000000000..115afaf84 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyMemberRequest.java @@ -0,0 +1,41 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 修改文档通知范围及权限请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocModifyMemberRequest implements Serializable { + private static final long serialVersionUID = 8704942578874336412L; + + @SerializedName("docid") + private String docId; + + @SerializedName("update_file_member_list") + private List updateFileMemberList; + + @SerializedName("del_file_member_list") + private List delFileMemberList; + + public static WxCpDocModifyMemberRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocModifyMemberRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyRequest.java new file mode 100644 index 000000000..42fadd56e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifyRequest.java @@ -0,0 +1,98 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 编辑文档内容请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocModifyRequest implements Serializable { + private static final long serialVersionUID = -1239410717176267110L; + + /** + * 文档 docid. + */ + @SerializedName("docid") + private String docId; + + /** + * 编辑动作集合或内容块,保留为通用 JSON 结构以兼容文档接口后续扩展。 + */ + @SerializedName("requests") + private JsonElement requests; + + /** + * 透传扩展参数。 + */ + private transient JsonObject extra; + + public static WxCpDocModifyRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocModifyRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.requests != null) { + jsonObject.add("requests", this.requests); + } + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } + + public WxCpDocModifyRequest addRequest(JsonObject request) { + JsonArray requestArray = this.requests != null && this.requests.isJsonArray() + ? this.requests.getAsJsonArray() + : new JsonArray(); + requestArray.add(request); + this.requests = requestArray; + return this; + } + + public WxCpDocModifyRequest addExtra(String key, String value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocModifyRequest addExtra(String key, Number value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocModifyRequest addExtra(String key, Boolean value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocModifyRequest addExtra(String key, JsonElement value) { + ensureExtra().add(key, value); + return this; + } + + private JsonObject ensureExtra() { + if (this.extra == null) { + this.extra = new JsonObject(); + } + return this.extra; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySafetySettingRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySafetySettingRequest.java new file mode 100644 index 000000000..7668586c9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySafetySettingRequest.java @@ -0,0 +1,41 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; + +/** + * 修改文档安全设置请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocModifySafetySettingRequest implements Serializable { + private static final long serialVersionUID = 8040559480117443346L; + + @SerializedName("docid") + private String docId; + + @SerializedName("enable_readonly_copy") + private Boolean enableReadonlyCopy; + + @SerializedName("watermark") + private WxCpDocAuthInfo.Watermark watermark; + + public static WxCpDocModifySafetySettingRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson( + json, WxCpDocModifySafetySettingRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySaftySettingRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySaftySettingRequest.java new file mode 100644 index 000000000..2d43d3d5c --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocModifySaftySettingRequest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; + +/** + * 修改文档安全设置请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocModifySaftySettingRequest implements Serializable { + private static final long serialVersionUID = 8040559480117443345L; + + @SerializedName("docid") + private String docId; + + @SerializedName("enable_readonly_copy") + private Boolean enableReadonlyCopy; + + @SerializedName("watermark") + private WxCpDocAuthInfo.Watermark watermark; + + public static WxCpDocModifySaftySettingRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocModifySaftySettingRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocShareRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocShareRequest.java new file mode 100644 index 000000000..f08f76904 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocShareRequest.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; + +/** + * 文档/收集表分享请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocShareRequest implements Serializable { + private static final long serialVersionUID = 7760968921955136050L; + + @SerializedName("docid") + private String docId; + + @SerializedName("formid") + private String formId; + + public static WxCpDocShareRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocShareRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuth.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuth.java new file mode 100644 index 000000000..8e9a8430e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuth.java @@ -0,0 +1,54 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 智能表格内容权限信息. + */ +@Data +public class WxCpDocSmartSheetAuth extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 6369842878363076286L; + + @SerializedName("docid") + private String docId; + + @SerializedName("sheet_id") + private String sheetId; + + /** + * 通用内容权限结构,兼容字段/记录权限等多种命名。 + */ + @SerializedName("auth_info") + private JsonElement authInfo; + + @SerializedName("field_auth") + private JsonElement fieldAuth; + + @SerializedName("record_auth") + private JsonElement recordAuth; + + public JsonElement getEffectiveAuthInfo() { + if (this.authInfo != null) { + return this.authInfo; + } + if (this.fieldAuth != null) { + return this.fieldAuth; + } + return this.recordAuth; + } + + public static WxCpDocSmartSheetAuth fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSmartSheetAuth.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuthRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuthRequest.java new file mode 100644 index 000000000..505329adf --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetAuthRequest.java @@ -0,0 +1,55 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 获取智能表格内容权限请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSmartSheetAuthRequest implements Serializable { + private static final long serialVersionUID = -7549610873100253102L; + + @SerializedName("docid") + private String docId; + + @SerializedName("sheet_id") + private String sheetId; + + /** + * 透传扩展参数,便于兼容字段权限/记录权限等筛选条件。 + */ + private transient JsonObject extra; + + public static WxCpDocSmartSheetAuthRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSmartSheetAuthRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.sheetId != null) { + jsonObject.addProperty("sheet_id", this.sheetId); + } + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetModifyAuthRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetModifyAuthRequest.java new file mode 100644 index 000000000..90a037ed0 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetModifyAuthRequest.java @@ -0,0 +1,64 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 修改智能表格内容权限请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSmartSheetModifyAuthRequest implements Serializable { + private static final long serialVersionUID = 1603733018038054224L; + + @SerializedName("docid") + private String docId; + + @SerializedName("sheet_id") + private String sheetId; + + /** + * 字段级/记录级权限载荷。 + */ + @SerializedName("auth_info") + private JsonElement authInfo; + + /** + * 透传扩展参数。 + */ + private transient JsonObject extra; + + public static WxCpDocSmartSheetModifyAuthRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSmartSheetModifyAuthRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.sheetId != null) { + jsonObject.addProperty("sheet_id", this.sheetId); + } + if (this.authInfo != null) { + jsonObject.add("auth_info", this.authInfo); + } + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetRequest.java new file mode 100644 index 000000000..06db7cc4f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetRequest.java @@ -0,0 +1,98 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +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; + +import java.io.Serializable; +import java.util.Map; + +/** + * 智能表格通用请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSmartSheetRequest implements Serializable { + private static final long serialVersionUID = -2713485192832296951L; + + @SerializedName("docid") + private String docId; + + @SerializedName("sheet_id") + private String sheetId; + + @SerializedName("view_id") + private String viewId; + + /** + * 透传扩展参数,便于兼容 properties、views、fields、records 等结构。 + */ + private transient JsonObject extra; + + public static WxCpDocSmartSheetRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSmartSheetRequest.class); + } + + public String toJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", this.docId); + if (this.sheetId != null) { + jsonObject.addProperty("sheet_id", this.sheetId); + } + if (this.viewId != null) { + jsonObject.addProperty("view_id", this.viewId); + } + if (this.extra != null) { + for (Map.Entry entry : this.extra.entrySet()) { + jsonObject.add(entry.getKey(), entry.getValue()); + } + } + return WxCpGsonBuilder.create().toJson(jsonObject); + } + + public WxCpDocSmartSheetRequest addExtra(String key, String value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocSmartSheetRequest addExtra(String key, Number value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocSmartSheetRequest addExtra(String key, Boolean value) { + ensureExtra().addProperty(key, value); + return this; + } + + public WxCpDocSmartSheetRequest addExtra(String key, JsonElement value) { + ensureExtra().add(key, value); + return this; + } + + public WxCpDocSmartSheetRequest addExtraArrayItem(String key, JsonElement value) { + JsonArray jsonArray = this.extra != null && this.extra.has(key) && this.extra.get(key).isJsonArray() + ? this.extra.getAsJsonArray(key) + : new JsonArray(); + jsonArray.add(value); + ensureExtra().add(key, jsonArray); + return this; + } + + private JsonObject ensureExtra() { + if (this.extra == null) { + this.extra = new JsonObject(); + } + return this.extra; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetResult.java new file mode 100644 index 000000000..71eaedd06 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSmartSheetResult.java @@ -0,0 +1,117 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 智能表格通用响应. + */ +@Data +public class WxCpDocSmartSheetResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 1409304699132416644L; + + @SerializedName("docid") + private String docId; + + @SerializedName("sheet_id") + private String sheetId; + + @SerializedName("view_id") + private String viewId; + + @SerializedName("sheet") + private JsonElement sheet; + + @SerializedName("sheet_list") + private JsonElement sheetList; + + @SerializedName("properties") + private JsonElement properties; + + @SerializedName("view") + private JsonElement view; + + @SerializedName("views") + private JsonElement views; + + @SerializedName("view_list") + private JsonElement viewList; + + @SerializedName("field") + private JsonElement field; + + @SerializedName("fields") + private JsonElement fields; + + @SerializedName("field_list") + private JsonElement fieldList; + + @SerializedName("record") + private JsonElement record; + + @SerializedName("records") + private JsonElement records; + + @SerializedName("record_list") + private JsonElement recordList; + + @SerializedName("has_more") + private Boolean hasMore; + + @SerializedName("next_cursor") + private JsonElement nextCursor; + + public JsonElement getEffectiveSheets() { + if (this.sheetList != null) { + return this.sheetList; + } + if (this.sheet != null) { + return this.sheet; + } + return this.properties; + } + + public JsonElement getEffectiveViews() { + if (this.views != null) { + return this.views; + } + if (this.viewList != null) { + return this.viewList; + } + return this.view; + } + + public JsonElement getEffectiveFields() { + if (this.fields != null) { + return this.fields; + } + if (this.fieldList != null) { + return this.fieldList; + } + return this.field; + } + + public JsonElement getEffectiveRecords() { + if (this.records != null) { + return this.records; + } + if (this.recordList != null) { + return this.recordList; + } + return this.record; + } + + public static WxCpDocSmartSheetResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSmartSheetResult.class); + } + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswer.java new file mode 100644 index 000000000..1860ecfb9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswer.java @@ -0,0 +1,192 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 收集表答案. + */ +@Data +public class WxCpFormAnswer extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -7318002552753089240L; + + @SerializedName("answer") + private Answer answer; + + public static WxCpFormAnswer fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormAnswer.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Getter + @Setter + public static class Answer implements Serializable { + private static final long serialVersionUID = -3098783062125658694L; + + @SerializedName("answer_list") + private List answerList; + } + + @Getter + @Setter + public static class AnswerItem implements Serializable { + private static final long serialVersionUID = -832821755226678178L; + + @SerializedName("answer_id") + private Long answerId; + + @SerializedName("user_name") + private String userName; + + @SerializedName("ctime") + private Long ctime; + + @SerializedName("mtime") + private Long mtime; + + @SerializedName("reply") + private Reply reply; + + @SerializedName("answer_status") + private Integer answerStatus; + + @SerializedName("tmp_external_userid") + private String tmpExternalUserId; + + @SerializedName("userid") + private String userId; + } + + @Getter + @Setter + public static class Reply implements Serializable { + private static final long serialVersionUID = 6883156174731993535L; + + @SerializedName("items") + private List items; + } + + @Getter + @Setter + public static class ReplyItem implements Serializable { + private static final long serialVersionUID = 445782840175634399L; + + @SerializedName("question_id") + private Long questionId; + + @SerializedName("text_reply") + private String textReply; + + @SerializedName("option_reply") + private List optionReply; + + @SerializedName("option_extend_reply") + private List optionExtendReply; + + @SerializedName("file_extend_reply") + private List fileExtendReply; + + @SerializedName("department_reply") + private DepartmentReply departmentReply; + + @SerializedName("member_reply") + private MemberReply memberReply; + + @SerializedName("duration_reply") + private DurationReply durationReply; + } + + @Getter + @Setter + public static class OptionExtendReply implements Serializable { + private static final long serialVersionUID = -4423477242528254162L; + + @SerializedName("option_reply") + private Integer optionReply; + + @SerializedName("extend_text") + private String extendText; + } + + @Getter + @Setter + public static class FileExtendReply implements Serializable { + private static final long serialVersionUID = 6464225701350465385L; + + @SerializedName("name") + private String name; + + @SerializedName("fileid") + private String fileId; + } + + @Getter + @Setter + public static class DepartmentReply implements Serializable { + private static final long serialVersionUID = 6599506855445852146L; + + @SerializedName("list") + private List list; + } + + @Getter + @Setter + public static class DepartmentItem implements Serializable { + private static final long serialVersionUID = 8568990069949513158L; + + @SerializedName("department_id") + private Long departmentId; + } + + @Getter + @Setter + public static class MemberReply implements Serializable { + private static final long serialVersionUID = -2447604628593912052L; + + @SerializedName("list") + private List list; + } + + @Getter + @Setter + public static class MemberItem implements Serializable { + private static final long serialVersionUID = -4863584961865113255L; + + @SerializedName("userid") + private String userId; + } + + @Getter + @Setter + public static class DurationReply implements Serializable { + private static final long serialVersionUID = -5917696184201031172L; + + @SerializedName("begin_time") + private Long beginTime; + + @SerializedName("end_time") + private Long endTime; + + @SerializedName("time_scale") + private Integer timeScale; + + @SerializedName("day_range") + private Integer dayRange; + + @SerializedName("days") + private Float days; + + @SerializedName("hours") + private Float hours; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswerRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswerRequest.java new file mode 100644 index 000000000..f28182f5b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormAnswerRequest.java @@ -0,0 +1,38 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 获取收集表答案请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpFormAnswerRequest implements Serializable { + private static final long serialVersionUID = 1895793536197315426L; + + @SerializedName("repeated_id") + private String repeatedId; + + @SerializedName("answer_ids") + private List answerIds; + + public static WxCpFormAnswerRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormAnswerRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateRequest.java new file mode 100644 index 000000000..cbd9d58af --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateRequest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; + +/** + * 创建收集表请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpFormCreateRequest implements Serializable { + private static final long serialVersionUID = -6170244024774750077L; + + @SerializedName("spaceid") + private String spaceId; + + @SerializedName("fatherid") + private String fatherId; + + @SerializedName("form_info") + private WxCpFormInfo formInfo; + + public static WxCpFormCreateRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormCreateRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateResult.java new file mode 100644 index 000000000..30cf3ccce --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormCreateResult.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 创建收集表结果. + */ +@Data +public class WxCpFormCreateResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 7996404138664773240L; + + @SerializedName("formid") + private String formId; + + public static WxCpFormCreateResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormCreateResult.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfo.java new file mode 100644 index 000000000..38d2fd368 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfo.java @@ -0,0 +1,186 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.List; + +/** + * 收集表信息. + */ +@Data +public class WxCpFormInfo implements Serializable { + private static final long serialVersionUID = -3124382745213903596L; + + @SerializedName("formid") + private String formId; + + @SerializedName("form_title") + private String formTitle; + + @SerializedName("form_desc") + private String formDesc; + + @SerializedName("form_header") + private String formHeader; + + @SerializedName("form_question") + private FormQuestion formQuestion; + + @SerializedName("form_setting") + private FormSetting formSetting; + + @SerializedName("repeated_id") + private List repeatedId; + + @Getter + @Setter + public static class FormQuestion implements Serializable { + private static final long serialVersionUID = 8800331150933320954L; + + @SerializedName("items") + private List items; + } + + @Getter + @Setter + public static class QuestionItem implements Serializable { + private static final long serialVersionUID = -1193146858246875337L; + + @SerializedName("question_id") + private Long questionId; + + @SerializedName("title") + private String title; + + @SerializedName("pos") + private Integer pos; + + @SerializedName("status") + private Integer status; + + @SerializedName("reply_type") + private Integer replyType; + + @SerializedName("must_reply") + private Boolean mustReply; + + @SerializedName("note") + private String note; + + @SerializedName("option_item") + private List optionItem; + + @SerializedName("placeholder") + private String placeholder; + + @SerializedName("question_extend_setting") + private JsonObject questionExtendSetting; + } + + @Getter + @Setter + public static class OptionItem implements Serializable { + private static final long serialVersionUID = 3572779939686615113L; + + @SerializedName("key") + private Integer key; + + @SerializedName("value") + private String value; + + @SerializedName("status") + private Integer status; + } + + @Getter + @Setter + public static class FormSetting implements Serializable { + private static final long serialVersionUID = 6423877223362121311L; + + @SerializedName("fill_out_auth") + private Integer fillOutAuth; + + @SerializedName("fill_in_range") + private FillInRange fillInRange; + + @SerializedName("setting_manager_range") + private SettingManagerRange settingManagerRange; + + @SerializedName("timed_repeat_info") + private TimedRepeatInfo timedRepeatInfo; + + @SerializedName("allow_multi_fill") + private Boolean allowMultiFill; + + @SerializedName("max_fill_cnt") + private Integer maxFillCnt; + + @SerializedName("timed_finish") + private Long timedFinish; + + @SerializedName("can_anonymous") + private Boolean canAnonymous; + + @SerializedName("can_notify_submit") + private Boolean canNotifySubmit; + } + + @Getter + @Setter + public static class FillInRange implements Serializable { + private static final long serialVersionUID = -4565903538375064972L; + + @SerializedName("userids") + private List userIds; + + @SerializedName("departmentids") + private List departmentIds; + } + + @Getter + @Setter + public static class SettingManagerRange implements Serializable { + private static final long serialVersionUID = 8144560331127349770L; + + @SerializedName("userids") + private List userIds; + } + + @Getter + @Setter + public static class TimedRepeatInfo implements Serializable { + private static final long serialVersionUID = -2415196650200762709L; + + @SerializedName("enable") + private Boolean enable; + + @SerializedName("week_flag") + private Integer weekFlag; + + @SerializedName("remind_time") + private Long remindTime; + + @SerializedName("repeat_type") + private Integer repeatType; + + @SerializedName("skip_holiday") + private Boolean skipHoliday; + + @SerializedName("day_of_month") + private Integer dayOfMonth; + + @SerializedName("fork_finish_type") + private Integer forkFinishType; + + @SerializedName("rule_ctime") + private Long ruleCtime; + + @SerializedName("rule_mtime") + private Long ruleMtime; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfoResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfoResult.java new file mode 100644 index 000000000..b0e81300a --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfoResult.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 获取收集表信息结果. + */ +@Data +public class WxCpFormInfoResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -3707731210828247900L; + + @SerializedName("form_info") + private WxCpFormInfo formInfo; + + public static WxCpFormInfoResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormInfoResult.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormModifyRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormModifyRequest.java new file mode 100644 index 000000000..9e5cfeff8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormModifyRequest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; + +/** + * 编辑收集表请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpFormModifyRequest implements Serializable { + private static final long serialVersionUID = -6803886338864231128L; + + @SerializedName("oper") + private Integer oper; + + @SerializedName("formid") + private String formId; + + @SerializedName("form_info") + private WxCpFormInfo formInfo; + + public static WxCpFormModifyRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormModifyRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatistic.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatistic.java new file mode 100644 index 000000000..bb3f82855 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatistic.java @@ -0,0 +1,92 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +/** + * 收集表统计结果(单条统计项). + */ +@Data +public class WxCpFormStatistic implements Serializable { + private static final long serialVersionUID = -7531427161782533396L; + + @SerializedName("fill_cnt") + private Long fillCnt; + + @SerializedName("repeated_id") + private String repeatedId; + + @SerializedName("repeated_name") + private String repeatedName; + + @SerializedName("fill_user_cnt") + private Long fillUserCnt; + + @SerializedName("unfill_user_cnt") + private Long unfillUserCnt; + + @SerializedName("submit_users") + private List submitUsers; + + @SerializedName("unfill_users") + private List unfillUsers; + + @SerializedName("has_more") + private Boolean hasMore; + + @SerializedName("cursor") + private Long cursor; + + public static WxCpFormStatistic fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormStatistic.class); + } + + public static List listFromJson(String json) { + WxCpFormStatistic[] results = WxCpGsonBuilder.create().fromJson(json, WxCpFormStatistic[].class); + return results == null ? null : Arrays.asList(results); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Getter + @Setter + public static class SubmitUser implements Serializable { + private static final long serialVersionUID = 879241255378502866L; + + @SerializedName("userid") + private String userId; + + @SerializedName("tmp_external_userid") + private String tmpExternalUserId; + + @SerializedName("submit_time") + private Long submitTime; + + @SerializedName("answer_id") + private Long answerId; + + @SerializedName("user_name") + private String userName; + } + + @Getter + @Setter + public static class UnfillUser implements Serializable { + private static final long serialVersionUID = -1561219841801653574L; + + @SerializedName("userid") + private String userId; + + @SerializedName("user_name") + private String userName; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticRequest.java new file mode 100644 index 000000000..9f3c3aab6 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticRequest.java @@ -0,0 +1,54 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +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; + +import java.io.Serializable; +import java.util.List; + +/** + * 收集表统计请求. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpFormStatisticRequest implements Serializable { + private static final long serialVersionUID = -1264428118237579449L; + + @SerializedName("repeated_id") + private String repeatedId; + + @SerializedName("req_type") + private Integer reqType; + + @SerializedName("start_time") + private Long startTime; + + @SerializedName("end_time") + private Long endTime; + + @SerializedName("limit") + private Long limit; + + @SerializedName("cursor") + private Long cursor; + + public static WxCpFormStatisticRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormStatisticRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + public static String toJson(List requests) { + return WxCpGsonBuilder.create().toJson(requests); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticResult.java new file mode 100644 index 000000000..d08f4d48e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticResult.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 收集表统计信息查询结果. + * + *

+ * 接口响应格式: + *

+ * {
+ *   "errcode": 0,
+ *   "errmsg": "ok",
+ *   "statistic_list": [...]
+ * }
+ * 
+ */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxCpFormStatisticResult extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -3648892040578890220L; + + @SerializedName("statistic_list") + private List statisticList; + + public static WxCpFormStatisticResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpFormStatisticResult.class); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 25a75541b..642e57987 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 @@ -574,6 +574,48 @@ interface Oa { * The constant WEDOC_DOC_SHARE. */ String WEDOC_DOC_SHARE = "/cgi-bin/wedoc/doc_share"; + /** + * The constant WEDOC_DOC_GET_AUTH. + */ + String WEDOC_DOC_GET_AUTH = "/cgi-bin/wedoc/doc_get_auth"; + /** + * The constant WEDOC_MOD_DOC_JOIN_RULE. + */ + String WEDOC_MOD_DOC_JOIN_RULE = "/cgi-bin/wedoc/mod_doc_join_rule"; + /** + * The constant WEDOC_MOD_DOC_MEMBER. + */ + String WEDOC_MOD_DOC_MEMBER = "/cgi-bin/wedoc/mod_doc_member"; + /** + * The constant WEDOC_MOD_DOC_SAFETY_SETTING. + */ + String WEDOC_MOD_DOC_SAFETY_SETTING = "/cgi-bin/wedoc/mod_doc_safty_setting"; + + /** + * @deprecated Use {@link #WEDOC_MOD_DOC_SAFETY_SETTING} instead. + */ + @Deprecated + String WEDOC_MOD_DOC_SAFTY_SETTING = WEDOC_MOD_DOC_SAFETY_SETTING; + /** + * The constant WEDOC_CREATE_FORM. + */ + String WEDOC_CREATE_FORM = "/cgi-bin/wedoc/create_collect"; + /** + * The constant WEDOC_MODIFY_FORM. + */ + String WEDOC_MODIFY_FORM = "/cgi-bin/wedoc/modify_collect"; + /** + * The constant WEDOC_GET_FORM_INFO. + */ + String WEDOC_GET_FORM_INFO = "/cgi-bin/wedoc/get_form_info"; + /** + * The constant WEDOC_GET_FORM_STATISTIC. + */ + String WEDOC_GET_FORM_STATISTIC = "/cgi-bin/wedoc/get_form_statistic"; + /** + * The constant WEDOC_GET_FORM_ANSWER. + */ + String WEDOC_GET_FORM_ANSWER = "/cgi-bin/wedoc/get_form_answer"; /** * The constant WEDOC_SPREADSHEET_BATCH_UPDATE. @@ -590,6 +632,126 @@ interface Oa { */ String WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA = "/cgi-bin/wedoc/spreadsheet/get_sheet_range_data"; + /** + * The constant WEDOC_GET_DOC_DATA. + */ + String WEDOC_GET_DOC_DATA = "/cgi-bin/wedoc/get_doc_data"; + + /** + * The constant WEDOC_MOD_DOC. + */ + String WEDOC_MOD_DOC = "/cgi-bin/wedoc/mod_doc"; + + /** + * The constant WEDOC_UPLOAD_DOC_IMAGE. + */ + String WEDOC_UPLOAD_DOC_IMAGE = "/cgi-bin/wedoc/upload_doc_image"; + + /** + * The constant WEDOC_ADD_ADMIN. + */ + String WEDOC_ADD_ADMIN = "/cgi-bin/wedoc/add_admin"; + + /** + * The constant WEDOC_DEL_ADMIN. + */ + String WEDOC_DEL_ADMIN = "/cgi-bin/wedoc/del_admin"; + + /** + * The constant WEDOC_GET_ADMIN_LIST. + */ + String WEDOC_GET_ADMIN_LIST = "/cgi-bin/wedoc/get_admin_list"; + + /** + * The constant WEDOC_SMARTSHEET_GET_SHEET_AUTH. + */ + String WEDOC_SMARTSHEET_GET_SHEET_AUTH = "/cgi-bin/wedoc/smartsheet/get_sheet_auth"; + + /** + * The constant WEDOC_SMARTSHEET_MOD_SHEET_AUTH. + */ + String WEDOC_SMARTSHEET_MOD_SHEET_AUTH = "/cgi-bin/wedoc/smartsheet/mod_sheet_auth"; + + /** + * The constant WEDOC_SMARTSHEET_GET_SHEET. + */ + String WEDOC_SMARTSHEET_GET_SHEET = "/cgi-bin/wedoc/smartsheet/get_sheet"; + + /** + * The constant WEDOC_SMARTSHEET_ADD_SHEET. + */ + String WEDOC_SMARTSHEET_ADD_SHEET = "/cgi-bin/wedoc/smartsheet/add_sheet"; + + /** + * The constant WEDOC_SMARTSHEET_DELETE_SHEET. + */ + String WEDOC_SMARTSHEET_DELETE_SHEET = "/cgi-bin/wedoc/smartsheet/delete_sheet"; + + /** + * The constant WEDOC_SMARTSHEET_UPDATE_SHEET. + */ + String WEDOC_SMARTSHEET_UPDATE_SHEET = "/cgi-bin/wedoc/smartsheet/update_sheet"; + + /** + * The constant WEDOC_SMARTSHEET_GET_VIEWS. + */ + String WEDOC_SMARTSHEET_GET_VIEWS = "/cgi-bin/wedoc/smartsheet/get_views"; + + /** + * The constant WEDOC_SMARTSHEET_ADD_VIEW. + */ + String WEDOC_SMARTSHEET_ADD_VIEW = "/cgi-bin/wedoc/smartsheet/add_view"; + + /** + * The constant WEDOC_SMARTSHEET_DELETE_VIEWS. + */ + String WEDOC_SMARTSHEET_DELETE_VIEWS = "/cgi-bin/wedoc/smartsheet/delete_views"; + + /** + * The constant WEDOC_SMARTSHEET_UPDATE_VIEW. + */ + String WEDOC_SMARTSHEET_UPDATE_VIEW = "/cgi-bin/wedoc/smartsheet/update_view"; + + /** + * The constant WEDOC_SMARTSHEET_GET_FIELDS. + */ + String WEDOC_SMARTSHEET_GET_FIELDS = "/cgi-bin/wedoc/smartsheet/get_fields"; + + /** + * The constant WEDOC_SMARTSHEET_ADD_FIELDS. + */ + String WEDOC_SMARTSHEET_ADD_FIELDS = "/cgi-bin/wedoc/smartsheet/add_fields"; + + /** + * The constant WEDOC_SMARTSHEET_DELETE_FIELDS. + */ + String WEDOC_SMARTSHEET_DELETE_FIELDS = "/cgi-bin/wedoc/smartsheet/delete_fields"; + + /** + * The constant WEDOC_SMARTSHEET_UPDATE_FIELDS. + */ + String WEDOC_SMARTSHEET_UPDATE_FIELDS = "/cgi-bin/wedoc/smartsheet/update_fields"; + + /** + * The constant WEDOC_SMARTSHEET_GET_RECORDS. + */ + String WEDOC_SMARTSHEET_GET_RECORDS = "/cgi-bin/wedoc/smartsheet/get_records"; + + /** + * The constant WEDOC_SMARTSHEET_ADD_RECORDS. + */ + String WEDOC_SMARTSHEET_ADD_RECORDS = "/cgi-bin/wedoc/smartsheet/add_records"; + + /** + * The constant WEDOC_SMARTSHEET_DELETE_RECORDS. + */ + String WEDOC_SMARTSHEET_DELETE_RECORDS = "/cgi-bin/wedoc/smartsheet/delete_records"; + + /** + * The constant WEDOC_SMARTSHEET_UPDATE_RECORDS. + */ + String WEDOC_SMARTSHEET_UPDATE_RECORDS = "/cgi-bin/wedoc/smartsheet/update_records"; + /** * 邮件 * https://developer.work.weixin.qq.com/document/path/95486 diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImplTest.java new file mode 100644 index 000000000..bb57985a7 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImplTest.java @@ -0,0 +1,541 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.bean.oa.doc.*; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import org.mockito.ArgumentCaptor; +import org.testng.annotations.Test; + +import java.io.File; + +import static java.util.Collections.singletonList; +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * WeDoc 接口实现测试. + */ +public class WxCpOaWeDocServiceImplTest { + + @Test + public void testLegacyApisUseExpectedPaths() throws WxErrorException { + WxCpService cpService = mock(WxCpService.class); + WxCpConfigStorage configStorage = mock(WxCpConfigStorage.class); + when(cpService.getWxCpConfigStorage()).thenReturn(configStorage); + when(configStorage.getApiUrl(WEDOC_CREATE_DOC)).thenReturn("https://api.test/create_doc"); + when(configStorage.getApiUrl(WEDOC_RENAME_DOC)).thenReturn("https://api.test/rename_doc"); + when(configStorage.getApiUrl(WEDOC_DEL_DOC)).thenReturn("https://api.test/del_doc"); + when(configStorage.getApiUrl(WEDOC_GET_DOC_BASE_INFO)).thenReturn("https://api.test/get_doc_base_info"); + when(configStorage.getApiUrl(WEDOC_DOC_SHARE)).thenReturn("https://api.test/doc_share"); + when(configStorage.getApiUrl(WEDOC_DOC_GET_AUTH)).thenReturn("https://api.test/doc_get_auth"); + when(configStorage.getApiUrl(WEDOC_MOD_DOC_JOIN_RULE)).thenReturn("https://api.test/mod_doc_join_rule"); + when(configStorage.getApiUrl(WEDOC_MOD_DOC_MEMBER)).thenReturn("https://api.test/mod_doc_member"); + when(configStorage.getApiUrl(WEDOC_MOD_DOC_SAFETY_SETTING)) + .thenReturn("https://api.test/mod_doc_safty_setting"); + when(configStorage.getApiUrl(WEDOC_SPREADSHEET_BATCH_UPDATE)).thenReturn("https://api.test/spreadsheet/batch_update"); + when(configStorage.getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES)).thenReturn("https://api.test/spreadsheet/get_sheet_properties"); + when(configStorage.getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA)).thenReturn("https://api.test/spreadsheet/get_sheet_range_data"); + when(configStorage.getApiUrl(WEDOC_CREATE_FORM)).thenReturn("https://api.test/create_collect"); + when(configStorage.getApiUrl(WEDOC_MODIFY_FORM)).thenReturn("https://api.test/modify_collect"); + when(configStorage.getApiUrl(WEDOC_GET_FORM_INFO)).thenReturn("https://api.test/get_form_info"); + when(configStorage.getApiUrl(WEDOC_GET_FORM_STATISTIC)).thenReturn("https://api.test/get_form_statistic"); + when(configStorage.getApiUrl(WEDOC_GET_FORM_ANSWER)).thenReturn("https://api.test/get_form_answer"); + + when(cpService.post(eq("https://api.test/create_doc"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"url\":\"https://wedoc.test/doc/1\",\"docid\":\"doc1\"}"); + when(cpService.post(eq("https://api.test/rename_doc"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/del_doc"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/get_doc_base_info"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"doc_base_info\":{\"docid\":\"doc1\",\"doc_name\":\"日报\",\"doc_type\":3}}"); + when(cpService.post(eq("https://api.test/doc_share"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"share_url\":\"https://wedoc.test/share/1\"}"); + when(cpService.post(eq("https://api.test/doc_get_auth"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"access_rule\":{\"enable_corp_internal\":true,\"corp_internal_auth\":1}}"); + when(cpService.post(eq("https://api.test/mod_doc_join_rule"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/mod_doc_member"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/mod_doc_safty_setting"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/spreadsheet/batch_update"), anyString())) + .thenReturn("{\"add_sheet_response\":{\"properties\":{\"sheet_id\":\"sheet2\",\"title\":\"Sheet A\",\"row_count\":20,\"column_count\":5}},\"update_range_response\":{\"updated_cells\":2}}"); + when(cpService.post(eq("https://api.test/spreadsheet/get_sheet_properties"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"properties\":[{\"sheet_id\":\"sheet1\",\"title\":\"Sheet A\",\"row_count\":20,\"column_count\":5}]}"); + when(cpService.post(eq("https://api.test/spreadsheet/get_sheet_range_data"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"grid_data\":{\"start_row\":0,\"start_column\":0,\"rows\":[{\"values\":[{\"cell_value\":{\"text\":\"hello\"}}]}]}}"); + when(cpService.post(eq("https://api.test/create_collect"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"formid\":\"FORMID1\"}"); + when(cpService.post(eq("https://api.test/modify_collect"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/get_form_info"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"form_info\":{\"formid\":\"FORMID1\",\"form_title\":\"日报\"}}"); + when(cpService.post(eq("https://api.test/get_form_statistic"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"," + + "\"statistic_list\":[{\"repeated_id\":\"repeat-1\"," + + "\"fill_cnt\":3,\"submit_users\":" + + "[{\"userid\":\"zhangsan\",\"answer_id\":1}]}]}"); + when(cpService.post(eq("https://api.test/get_form_answer"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"answer\":{\"answer_list\":[{\"answer_id\":1,\"userid\":\"zhangsan\",\"reply\":{\"items\":[{\"question_id\":1,\"text_reply\":\"ok\"}]}}]}}"); + + WxCpOaWeDocServiceImpl service = new WxCpOaWeDocServiceImpl(cpService); + + WxCpDocCreateRequest createRequest = WxCpDocCreateRequest.builder() + .spaceId("space1") + .fatherId("father1") + .docType(3) + .docName("日报") + .build(); + WxCpDocCreateData createData = service.docCreate(createRequest); + assertThat(createData.getDocId()).isEqualTo("doc1"); + ArgumentCaptor createBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/create_doc"), createBodyCaptor.capture()); + assertThat(createBodyCaptor.getValue()).contains("\"spaceid\":\"space1\""); + assertThat(createBodyCaptor.getValue()).contains("\"doc_type\":3"); + + WxCpBaseResp renameResp = service.docRename(WxCpDocRenameRequest.builder() + .docId("doc1") + .newName("周报") + .build()); + assertThat(renameResp.getErrcode()).isZero(); + ArgumentCaptor renameBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/rename_doc"), renameBodyCaptor.capture()); + assertThat(renameBodyCaptor.getValue()).contains("\"new_name\":\"周报\""); + + WxCpBaseResp deleteResp = service.docDelete("doc1", null); + assertThat(deleteResp.getErrcode()).isZero(); + ArgumentCaptor deleteBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/del_doc"), deleteBodyCaptor.capture()); + assertThat(deleteBodyCaptor.getValue()).contains("\"docid\":\"doc1\""); + + WxCpDocInfo docInfo = service.docInfo("doc1"); + assertThat(docInfo.getDocBaseInfo().getDocName()).isEqualTo("日报"); + verify(cpService).post(eq("https://api.test/get_doc_base_info"), anyString()); + + WxCpDocShare docShare = service.docShare(WxCpDocShareRequest.builder().formId("FORMID1").build()); + assertThat(docShare.getShareUrl()).isEqualTo("https://wedoc.test/share/1"); + ArgumentCaptor docShareBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/doc_share"), docShareBodyCaptor.capture()); + assertThat(docShareBodyCaptor.getValue()).contains("\"formid\":\"FORMID1\""); + + WxCpDocAuthInfo docAuthInfo = service.docGetAuth("doc1"); + assertThat(docAuthInfo.getAccessRule().getEnableCorpInternal()).isTrue(); + verify(cpService).post(eq("https://api.test/doc_get_auth"), anyString()); + + WxCpBaseResp joinRuleResp = service.docModifyJoinRule(WxCpDocModifyJoinRuleRequest.builder() + .docId("doc1") + .enableCorpInternal(true) + .corpInternalAuth(1) + .build()); + assertThat(joinRuleResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/mod_doc_join_rule"), anyString()); + + WxCpDocAuthInfo.DocMember docMember = new WxCpDocAuthInfo.DocMember(); + docMember.setType(1); + docMember.setUserId("zhangsan"); + docMember.setAuth(7); + WxCpBaseResp modifyMemberResp = service.docModifyMember(WxCpDocModifyMemberRequest.builder() + .docId("doc1") + .updateFileMemberList(singletonList(docMember)) + .build()); + assertThat(modifyMemberResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/mod_doc_member"), anyString()); + + WxCpDocAuthInfo.Watermark watermark = new WxCpDocAuthInfo.Watermark(); + watermark.setMarginType(2); + watermark.setShowText(true); + watermark.setText("wm"); + WxCpBaseResp safetyResp = service.docModifySafetySetting( + WxCpDocModifySafetySettingRequest.builder() + .docId("doc1") + .enableReadonlyCopy(true) + .watermark(watermark) + .build()); + assertThat(safetyResp.getErrcode()).isZero(); + verify(cpService).post( + eq("https://api.test/mod_doc_safty_setting"), anyString()); + + WxCpDocSheetBatchUpdateRequest.Request.AddSheetRequest addSheetRequest = + new WxCpDocSheetBatchUpdateRequest.Request.AddSheetRequest(); + addSheetRequest.setTitle("Sheet A"); + addSheetRequest.setRowCount(20); + addSheetRequest.setColumnCount(5); + WxCpDocSheetBatchUpdateRequest.Request batchRequest = new WxCpDocSheetBatchUpdateRequest.Request(); + batchRequest.setAddSheetRequest(addSheetRequest); + WxCpDocSheetBatchUpdateResponse batchUpdateResponse = service.docBatchUpdate(WxCpDocSheetBatchUpdateRequest.builder() + .docId("doc1") + .requests(singletonList(batchRequest)) + .build()); + assertThat(batchUpdateResponse.getAddSheetResponse().getProperties().getSheetId()).isEqualTo("sheet2"); + verify(cpService).post(eq("https://api.test/spreadsheet/batch_update"), anyString()); + + WxCpDocSheetProperties sheetProperties = service.getSheetProperties("doc1"); + assertThat(sheetProperties.getProperties()).hasSize(1); + assertThat(sheetProperties.getProperties().get(0).getSheetId()).isEqualTo("sheet1"); + ArgumentCaptor sheetPropertiesBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/spreadsheet/get_sheet_properties"), sheetPropertiesBodyCaptor.capture()); + assertThat(sheetPropertiesBodyCaptor.getValue()).isEqualTo("{\"docid\":\"doc1\"}"); + + WxCpDocSheetData sheetData = service.getSheetRangeData(WxCpDocSheetGetDataRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .range("A1:B2") + .build()); + assertThat(sheetData.getGridData().getRows()).hasSize(1); + verify(cpService).post(eq("https://api.test/spreadsheet/get_sheet_range_data"), anyString()); + + WxCpFormInfo formInfo = new WxCpFormInfo(); + formInfo.setFormTitle("日报"); + WxCpFormCreateResult formCreateResult = service.formCreate(WxCpFormCreateRequest.builder() + .spaceId("space1") + .fatherId("father1") + .formInfo(formInfo) + .build()); + assertThat(formCreateResult.getFormId()).isEqualTo("FORMID1"); + verify(cpService).post(eq("https://api.test/create_collect"), anyString()); + + WxCpBaseResp formModifyResp = service.formModify(WxCpFormModifyRequest.builder() + .oper(1) + .formId("FORMID1") + .formInfo(formInfo) + .build()); + assertThat(formModifyResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/modify_collect"), anyString()); + + WxCpFormInfoResult formInfoResult = service.formInfo("FORMID1"); + assertThat(formInfoResult.getFormInfo().getFormId()).isEqualTo("FORMID1"); + ArgumentCaptor formInfoBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/get_form_info"), formInfoBodyCaptor.capture()); + assertThat(formInfoBodyCaptor.getValue()).isEqualTo("{\"formid\":\"FORMID1\"}"); + + WxCpFormStatistic formStatistic = service.formStatistic(WxCpFormStatisticRequest.builder() + .repeatedId("repeat-1") + .build()); + assertThat(formStatistic.getFillCnt()).isEqualTo(3); + ArgumentCaptor formStatisticBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/get_form_statistic"), formStatisticBodyCaptor.capture()); + assertThat(formStatisticBodyCaptor.getValue()).startsWith("["); + assertThat(formStatisticBodyCaptor.getValue()).contains("\"repeated_id\":\"repeat-1\""); + + WxCpFormAnswer formAnswer = service.formAnswer(WxCpFormAnswerRequest.builder() + .repeatedId("repeat-1") + .answerIds(singletonList(1L)) + .build()); + assertThat(formAnswer.getAnswer().getAnswerList()).hasSize(1); + verify(cpService).post(eq("https://api.test/get_form_answer"), anyString()); + } + + @Test + public void testNewApisUseExpectedPaths() throws Exception { + WxCpService cpService = mock(WxCpService.class); + WxCpConfigStorage configStorage = mock(WxCpConfigStorage.class); + when(cpService.getWxCpConfigStorage()).thenReturn(configStorage); + when(configStorage.getApiUrl(WEDOC_GET_DOC_DATA)).thenReturn("https://api.test/get_doc_data"); + when(configStorage.getApiUrl(WEDOC_MOD_DOC)).thenReturn("https://api.test/mod_doc"); + when(configStorage.getApiUrl(WEDOC_UPLOAD_DOC_IMAGE)).thenReturn("https://api.test/upload_doc_image"); + when(configStorage.getApiUrl(WEDOC_ADD_ADMIN)).thenReturn("https://api.test/add_admin"); + when(configStorage.getApiUrl(WEDOC_DEL_ADMIN)).thenReturn("https://api.test/del_admin"); + when(configStorage.getApiUrl(WEDOC_GET_ADMIN_LIST)).thenReturn("https://api.test/get_admin_list"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_GET_SHEET_AUTH)).thenReturn("https://api.test/smartsheet/get_sheet_auth"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_MOD_SHEET_AUTH)).thenReturn("https://api.test/smartsheet/mod_sheet_auth"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_GET_SHEET)).thenReturn("https://api.test/smartsheet/get_sheet"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_ADD_SHEET)).thenReturn("https://api.test/smartsheet/add_sheet"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_DELETE_SHEET)).thenReturn("https://api.test/smartsheet/delete_sheet"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_UPDATE_SHEET)).thenReturn("https://api.test/smartsheet/update_sheet"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_GET_VIEWS)).thenReturn("https://api.test/smartsheet/get_views"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_ADD_VIEW)).thenReturn("https://api.test/smartsheet/add_view"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_DELETE_VIEWS)).thenReturn("https://api.test/smartsheet/delete_views"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_UPDATE_VIEW)).thenReturn("https://api.test/smartsheet/update_view"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_GET_FIELDS)).thenReturn("https://api.test/smartsheet/get_fields"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_ADD_FIELDS)).thenReturn("https://api.test/smartsheet/add_fields"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_DELETE_FIELDS)).thenReturn("https://api.test/smartsheet/delete_fields"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_UPDATE_FIELDS)).thenReturn("https://api.test/smartsheet/update_fields"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_GET_RECORDS)).thenReturn("https://api.test/smartsheet/get_records"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_ADD_RECORDS)).thenReturn("https://api.test/smartsheet/add_records"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_DELETE_RECORDS)).thenReturn("https://api.test/smartsheet/delete_records"); + when(configStorage.getApiUrl(WEDOC_SMARTSHEET_UPDATE_RECORDS)).thenReturn("https://api.test/smartsheet/update_records"); + + when(cpService.post(eq("https://api.test/get_doc_data"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\"}"); + when(cpService.post(eq("https://api.test/mod_doc"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.upload(eq("https://api.test/upload_doc_image"), any())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"image_url\":\"https://img.test/a.png\",\"media_id\":\"media-1\"}"); + when(cpService.post(eq("https://api.test/add_admin"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/del_admin"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/get_admin_list"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"admin_list\":[{\"userid\":\"zhangsan\",\"type\":1}]}"); + when(cpService.post(eq("https://api.test/smartsheet/get_sheet_auth"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\"}"); + when(cpService.post(eq("https://api.test/smartsheet/mod_sheet_auth"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/get_sheet"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_list\":[{\"sheet_id\":\"sheet1\"}]}"); + when(cpService.post(eq("https://api.test/smartsheet/add_sheet"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet\":{\"sheet_id\":\"sheet2\"}}"); + when(cpService.post(eq("https://api.test/smartsheet/delete_sheet"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/update_sheet"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/get_views"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"views\":[{\"view_id\":\"view1\"}]}"); + when(cpService.post(eq("https://api.test/smartsheet/add_view"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"view\":{\"view_id\":\"view2\"}}"); + when(cpService.post(eq("https://api.test/smartsheet/delete_views"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/update_view"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/get_fields"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"field_list\":[{\"field_id\":\"field1\"}]}"); + when(cpService.post(eq("https://api.test/smartsheet/add_fields"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"fields\":[{\"field_id\":\"field2\"}]}"); + when(cpService.post(eq("https://api.test/smartsheet/delete_fields"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/update_fields"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/get_records"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"record_list\":[{\"record_id\":\"record1\"}],\"has_more\":true,\"next_cursor\":101}"); + when(cpService.post(eq("https://api.test/smartsheet/add_records"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"docid\":\"doc1\",\"sheet_id\":\"sheet1\",\"records\":[{\"record_id\":\"record2\"}]}"); + when(cpService.post(eq("https://api.test/smartsheet/delete_records"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + when(cpService.post(eq("https://api.test/smartsheet/update_records"), anyString())) + .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}"); + + WxCpOaWeDocServiceImpl service = new WxCpOaWeDocServiceImpl(cpService); + + JsonObject extra = new JsonObject(); + extra.addProperty("start", 0); + WxCpDocGetDataRequest getDataRequest = WxCpDocGetDataRequest.builder() + .docId("doc1") + .extra(extra) + .build(); + WxCpDocData docData = service.docGetData(getDataRequest); + assertThat(docData.getDocId()).isEqualTo("doc1"); + verify(cpService).post(eq("https://api.test/get_doc_data"), anyString()); + + JsonArray requests = new JsonArray(); + JsonObject op = new JsonObject(); + op.addProperty("op", "insert_text"); + requests.add(op); + WxCpDocModifyRequest modifyRequest = WxCpDocModifyRequest.builder() + .docId("doc1") + .requests(requests) + .build(); + WxCpBaseResp modifyResp = service.docModify(modifyRequest); + assertThat(modifyResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/mod_doc"), anyString()); + + File uploadFile = File.createTempFile("wedoc-upload-", ".png"); + uploadFile.deleteOnExit(); + WxCpDocImageUploadResult uploadResult = service.docUploadImage(uploadFile); + assertThat(uploadResult.getEffectiveUrl()).isEqualTo("https://img.test/a.png"); + assertThat(uploadResult.getMediaId()).isEqualTo("media-1"); + verify(cpService).upload(eq("https://api.test/upload_doc_image"), any()); + + WxCpDocAdminRequest adminRequest = WxCpDocAdminRequest.builder() + .docId("doc1") + .userId("zhangsan") + .type(1) + .build(); + WxCpBaseResp addAdminResp = service.docAddAdmin(adminRequest); + assertThat(addAdminResp.getErrcode()).isZero(); + ArgumentCaptor addAdminBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/add_admin"), addAdminBodyCaptor.capture()); + assertThat(addAdminBodyCaptor.getValue()).contains("\"docid\":\"doc1\""); + assertThat(addAdminBodyCaptor.getValue()).contains("\"userid\":\"zhangsan\""); + assertThat(addAdminBodyCaptor.getValue()).contains("\"type\":1"); + + WxCpDocAdminRequest deleteAdminRequest = WxCpDocAdminRequest.builder() + .docId("doc1") + .openUserId("ou_zhangsan") + .build(); + WxCpBaseResp deleteAdminResp = service.docDeleteAdmin(deleteAdminRequest); + assertThat(deleteAdminResp.getErrcode()).isZero(); + ArgumentCaptor deleteAdminBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/del_admin"), deleteAdminBodyCaptor.capture()); + assertThat(deleteAdminBodyCaptor.getValue()).contains("\"docid\":\"doc1\""); + assertThat(deleteAdminBodyCaptor.getValue()).contains("\"open_userid\":\"ou_zhangsan\""); + + WxCpDocAdminListResult adminListResult = service.docGetAdminList("doc1"); + assertThat(adminListResult.getDocId()).isEqualTo("doc1"); + assertThat(adminListResult.getAdminList()).hasSize(1); + assertThat(adminListResult.getAdminList().get(0).getUserId()).isEqualTo("zhangsan"); + ArgumentCaptor getAdminListBodyCaptor = ArgumentCaptor.forClass(String.class); + verify(cpService).post(eq("https://api.test/get_admin_list"), getAdminListBodyCaptor.capture()); + assertThat(getAdminListBodyCaptor.getValue()).isEqualTo("{\"docid\":\"doc1\"}"); + + WxCpDocSmartSheetAuthRequest authRequest = WxCpDocSmartSheetAuthRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build(); + WxCpDocSmartSheetAuth auth = service.smartSheetGetAuth(authRequest); + assertThat(auth.getSheetId()).isEqualTo("sheet1"); + verify(cpService).post(eq("https://api.test/smartsheet/get_sheet_auth"), anyString()); + + JsonObject authInfo = new JsonObject(); + authInfo.addProperty("mode", "custom"); + WxCpDocSmartSheetModifyAuthRequest modifyAuthRequest = WxCpDocSmartSheetModifyAuthRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .authInfo(authInfo) + .build(); + WxCpBaseResp modifyAuthResp = service.smartSheetModifyAuth(modifyAuthRequest); + assertThat(modifyAuthResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/mod_sheet_auth"), anyString()); + + WxCpDocSmartSheetRequest sheetRequest = WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .build(); + WxCpDocSmartSheetResult sheetResult = service.smartSheetGetSheet(sheetRequest); + assertThat(sheetResult.getEffectiveSheets().getAsJsonArray()).hasSize(1); + verify(cpService).post(eq("https://api.test/smartsheet/get_sheet"), anyString()); + + JsonObject sheetProperties = new JsonObject(); + sheetProperties.addProperty("title", "Sheet A"); + WxCpDocSmartSheetRequest addSheetRequest = WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .build() + .addExtra("properties", sheetProperties); + WxCpDocSmartSheetResult addSheetResult = service.smartSheetAddSheet(addSheetRequest); + assertThat(addSheetResult.getEffectiveSheets().getAsJsonObject().get("sheet_id").getAsString()).isEqualTo("sheet2"); + verify(cpService).post(eq("https://api.test/smartsheet/add_sheet"), anyString()); + + WxCpBaseResp deleteSheetResp = service.smartSheetDeleteSheet(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build()); + assertThat(deleteSheetResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/delete_sheet"), anyString()); + + WxCpBaseResp updateSheetResp = service.smartSheetUpdateSheet(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtra("title", "Sheet B")); + assertThat(updateSheetResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/update_sheet"), anyString()); + + WxCpDocSmartSheetResult viewsResult = service.smartSheetGetViews(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build()); + assertThat(viewsResult.getEffectiveViews().getAsJsonArray()).hasSize(1); + verify(cpService).post(eq("https://api.test/smartsheet/get_views"), anyString()); + + JsonObject view = new JsonObject(); + view.addProperty("title", "All Records"); + WxCpDocSmartSheetResult addViewResult = service.smartSheetAddView(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtraArrayItem("views", view)); + assertThat(addViewResult.getEffectiveViews().getAsJsonObject().get("view_id").getAsString()).isEqualTo("view2"); + verify(cpService).post(eq("https://api.test/smartsheet/add_view"), anyString()); + + JsonArray viewIds = new JsonArray(); + viewIds.add("view1"); + WxCpBaseResp deleteViewsResp = service.smartSheetDeleteViews(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtra("view_ids", viewIds)); + assertThat(deleteViewsResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/delete_views"), anyString()); + + WxCpBaseResp updateViewResp = service.smartSheetUpdateView(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .viewId("view1") + .build() + .addExtra("title", "Updated View")); + assertThat(updateViewResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/update_view"), anyString()); + + WxCpDocSmartSheetResult fieldsResult = service.smartSheetGetFields(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build()); + assertThat(fieldsResult.getEffectiveFields().getAsJsonArray()).hasSize(1); + verify(cpService).post(eq("https://api.test/smartsheet/get_fields"), anyString()); + + JsonObject field = new JsonObject(); + field.addProperty("title", "Priority"); + field.addProperty("type", "single_select"); + WxCpDocSmartSheetResult addFieldsResult = service.smartSheetAddFields(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtraArrayItem("fields", field)); + assertThat(addFieldsResult.getEffectiveFields().getAsJsonArray()).hasSize(1); + verify(cpService).post(eq("https://api.test/smartsheet/add_fields"), anyString()); + + JsonArray fieldIds = new JsonArray(); + fieldIds.add("field1"); + WxCpBaseResp deleteFieldsResp = service.smartSheetDeleteFields(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtra("field_ids", fieldIds)); + assertThat(deleteFieldsResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/delete_fields"), anyString()); + + WxCpBaseResp updateFieldsResp = service.smartSheetUpdateFields(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtraArrayItem("fields", field)); + assertThat(updateFieldsResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/update_fields"), anyString()); + + WxCpDocSmartSheetResult recordsResult = service.smartSheetGetRecords(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build()); + assertThat(recordsResult.getEffectiveRecords().getAsJsonArray()).hasSize(1); + assertThat(recordsResult.getHasMore()).isTrue(); + verify(cpService).post(eq("https://api.test/smartsheet/get_records"), anyString()); + + JsonObject record = new JsonObject(); + record.addProperty("record_id", "record2"); + record.add("values", new JsonObject()); + WxCpDocSmartSheetResult addRecordsResult = service.smartSheetAddRecords(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtraArrayItem("records", record)); + assertThat(addRecordsResult.getEffectiveRecords().getAsJsonArray()).hasSize(1); + verify(cpService).post(eq("https://api.test/smartsheet/add_records"), anyString()); + + JsonArray recordIds = new JsonArray(); + recordIds.add("record1"); + WxCpBaseResp deleteRecordsResp = service.smartSheetDeleteRecords(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtra("record_ids", recordIds)); + assertThat(deleteRecordsResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/delete_records"), anyString()); + + WxCpBaseResp updateRecordsResp = service.smartSheetUpdateRecords(WxCpDocSmartSheetRequest.builder() + .docId("doc1") + .sheetId("sheet1") + .build() + .addExtraArrayItem("records", record)); + assertThat(updateRecordsResp.getErrcode()).isZero(); + verify(cpService).post(eq("https://api.test/smartsheet/update_records"), anyString()); + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpOaWeDocJsonTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpOaWeDocJsonTest.java new file mode 100644 index 000000000..9a6058f42 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpOaWeDocJsonTest.java @@ -0,0 +1,509 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * 企业微信文档 JSON 测试. + */ +public class WxCpOaWeDocJsonTest { + + @Test + public void testWxCpServiceExposeWeDocService() { + WxCpService service = new WxCpServiceImpl(); + assertThat(service.getOaWeDocService()).isNotNull(); + } + + @Test + public void testDocModifyJoinRuleRequestToJson() { + WxCpDocAuthInfo.CoAuthInfo coAuthInfo = new WxCpDocAuthInfo.CoAuthInfo(); + coAuthInfo.setType(2); + coAuthInfo.setDepartmentId(3L); + coAuthInfo.setAuth(1); + + WxCpDocModifyJoinRuleRequest request = WxCpDocModifyJoinRuleRequest.builder() + .docId("doc123") + .enableCorpInternal(true) + .corpInternalAuth(1) + .updateCoAuthList(true) + .coAuthList(Collections.singletonList(coAuthInfo)) + .build(); + + String json = request.toJson(); + assertThat(json).contains("\"docid\":\"doc123\""); + assertThat(json).contains("\"update_co_auth_list\":true"); + assertThat(json).contains("\"departmentid\":3"); + } + + @Test + public void testDocAuthInfoFromJson() { + String json = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"access_rule\":{\"enable_corp_internal\":true,\"corp_internal_auth\":1}," + + "\"secure_setting\":{\"enable_readonly_copy\":false," + + "\"watermark\":{\"margin_type\":2," + + "\"show_text\":true,\"text\":\"mark\"}}," + + "\"doc_member_list\":[{\"type\":1,\"userid\":\"zhangsan\",\"auth\":7}]," + + "\"co_auth_list\":[{\"type\":2,\"departmentid\":42,\"auth\":1}]" + + "}"; + + WxCpDocAuthInfo result = WxCpDocAuthInfo.fromJson(json); + assertThat(result.getErrcode()).isZero(); + assertThat(result.getAccessRule().getEnableCorpInternal()).isTrue(); + assertThat(result.getSecureSetting().getWatermark().getText()).isEqualTo("mark"); + assertThat(result.getDocMemberList()).hasSize(1); + assertThat(result.getCoAuthList().get(0).getDepartmentId()).isEqualTo(42L); + } + + @Test + public void testDocCreateRenameInfoAndShareJson() { + WxCpDocCreateRequest createRequest = WxCpDocCreateRequest.builder() + .spaceId("space1") + .fatherId("father1") + .docType(3) + .docName("日报") + .adminUsers(Arrays.asList("zhangsan", "lisi")) + .build(); + assertThat(createRequest.toJson()).contains("\"spaceid\":\"space1\""); + assertThat(createRequest.toJson()).contains("\"doc_type\":3"); + assertThat(createRequest.toJson()).contains("\"admin_users\":[\"zhangsan\",\"lisi\"]"); + + String createJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc123\"" + + "}"; + WxCpDocCreateData createData = WxCpDocCreateData.fromJson(createJson); + assertThat(createData.getDocId()).isEqualTo("doc123"); + + WxCpDocRenameRequest renameRequest = WxCpDocRenameRequest.builder() + .docId("doc123") + .newName("周报") + .build(); + assertThat(renameRequest.toJson()).contains("\"docid\":\"doc123\""); + assertThat(renameRequest.toJson()).contains("\"new_name\":\"周报\""); + + String infoJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"doc_base_info\":{" + + "\"docid\":\"doc123\"," + + "\"doc_name\":\"日报\"," + + "\"create_time\":1710000000," + + "\"modify_time\":1710000300," + + "\"doc_type\":3" + + "}" + + "}"; + WxCpDocInfo docInfo = WxCpDocInfo.fromJson(infoJson); + assertThat(docInfo.getDocBaseInfo().getDocId()).isEqualTo("doc123"); + assertThat(docInfo.getDocBaseInfo().getDocName()).isEqualTo("日报"); + + WxCpDocShareRequest shareRequest = WxCpDocShareRequest.builder() + .formId("FORMID1") + .build(); + assertThat(shareRequest.toJson()).contains("\"formid\":\"FORMID1\""); + + String shareJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"share_url\":\"https://wedoc.test/share/1\"" + + "}"; + WxCpDocShare docShare = WxCpDocShare.fromJson(shareJson); + assertThat(docShare.getShareUrl()).isEqualTo("https://wedoc.test/share/1"); + } + + @Test + public void testFormCreateRequestToJson() { + JsonObject extendSetting = new JsonObject(); + extendSetting.addProperty("camera_only", true); + + WxCpFormInfo.QuestionItem questionItem = new WxCpFormInfo.QuestionItem(); + questionItem.setQuestionId(1L); + questionItem.setTitle("图片题"); + questionItem.setPos(1); + questionItem.setStatus(1); + questionItem.setReplyType(9); + questionItem.setMustReply(true); + questionItem.setQuestionExtendSetting(extendSetting); + + WxCpFormInfo.FormQuestion formQuestion = new WxCpFormInfo.FormQuestion(); + formQuestion.setItems(Collections.singletonList(questionItem)); + + WxCpFormInfo formInfo = new WxCpFormInfo(); + formInfo.setFormTitle("每日上报"); + formInfo.setFormQuestion(formQuestion); + + WxCpFormCreateRequest request = WxCpFormCreateRequest.builder() + .spaceId("space1") + .fatherId("father1") + .formInfo(formInfo) + .build(); + + String json = request.toJson(); + assertThat(json).contains("\"spaceid\":\"space1\""); + assertThat(json).contains("\"form_title\":\"每日上报\""); + assertThat(json).contains("\"camera_only\":true"); + } + + @Test + public void testFormInfoResultFromJson() { + String json = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"form_info\":{" + + "\"formid\":\"FORMID1\"," + + "\"form_title\":\"api创建的收集表\"," + + "\"form_question\":{\"items\":[{\"question_id\":1," + + "\"title\":\"问题1\",\"pos\":1,\"status\":1," + + "\"reply_type\":1,\"must_reply\":true}]}," + + "\"form_setting\":{\"fill_out_auth\":1,\"max_fill_cnt\":2}," + + "\"repeated_id\":[\"REPEAT_ID1\"]" + + "}" + + "}"; + + WxCpFormInfoResult result = WxCpFormInfoResult.fromJson(json); + assertThat(result.getFormInfo().getFormId()).isEqualTo("FORMID1"); + assertThat(result.getFormInfo().getFormQuestion().getItems().get(0).getTitle()).isEqualTo("问题1"); + assertThat(result.getFormInfo().getFormSetting().getMaxFillCnt()).isEqualTo(2); + assertThat(result.getFormInfo().getRepeatedId()).containsExactly("REPEAT_ID1"); + } + + @Test + public void testFormStatisticAndAnswerFromJson() { + String statisticRequestJson = WxCpFormStatisticRequest.toJson(Collections.singletonList( + WxCpFormStatisticRequest.builder().repeatedId("REPEAT_ID1").reqType(1).limit(100L).cursor(0L).build() + )); + assertThat(statisticRequestJson).startsWith("["); + assertThat(statisticRequestJson).contains("\"repeated_id\":\"REPEAT_ID1\""); + + String statisticJson = "{\"errcode\":0,\"errmsg\":\"ok\"," + + "\"statistic_list\":[{" + + "\"repeated_id\":\"REPEAT_ID1\"," + + "\"repeated_name\":\"第1次收集\"," + + "\"fill_cnt\":1," + + "\"fill_user_cnt\":1," + + "\"unfill_user_cnt\":2," + + "\"submit_users\":[{\"userid\":\"zhangsan\"," + + "\"answer_id\":3,\"submit_time\":1668418200," + + "\"user_name\":\"张三\"}]," + + "\"has_more\":false," + + "\"cursor\":1" + + "}]}"; + WxCpFormStatisticResult statisticResult = + WxCpFormStatisticResult.fromJson(statisticJson); + assertThat(statisticResult.getErrcode()).isZero(); + WxCpFormStatistic statistic = + statisticResult.getStatisticList().get(0); + assertThat(statistic.getSubmitUsers()).hasSize(1); + assertThat(statistic.getSubmitUsers().get(0).getAnswerId()) + .isEqualTo(3L); + + String answerJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"answer\":{\"answer_list\":[{" + + "\"answer_id\":15," + + "\"user_name\":\"张三\"," + + "\"ctime\":1668430580," + + "\"mtime\":1668430580," + + "\"reply\":{\"items\":[" + + "{\"question_id\":1,\"text_reply\":\"答案\"}," + + "{\"question_id\":2,\"option_reply\":[1,2]}," + + "{\"question_id\":3,\"file_extend_reply\":[{\"name\":\"附件\",\"fileid\":\"FILEID1\"}]}" + + "]}," + + "\"answer_status\":1," + + "\"userid\":\"zhangsan\"" + + "}]}" + + "}"; + WxCpFormAnswer answer = WxCpFormAnswer.fromJson(answerJson); + assertThat(answer.getAnswer().getAnswerList()).hasSize(1); + assertThat(answer.getAnswer().getAnswerList().get(0).getReply().getItems()).hasSize(3); + assertThat(answer.getAnswer().getAnswerList().get(0).getReply().getItems().get(1).getOptionReply()) + .isEqualTo(Arrays.asList(1, 2)); + } + + @Test + public void testDocGetDataAndModifyJson() { + WxCpDocGetDataRequest getDataRequest = WxCpDocGetDataRequest.builder() + .docId("doc123") + .build(); + getDataRequest.addExtra("start", 0).addExtra("limit", 20); + assertThat(getDataRequest.toJson()).contains("\"docid\":\"doc123\""); + assertThat(getDataRequest.toJson()).contains("\"limit\":20"); + + JsonObject insertRequest = new JsonObject(); + insertRequest.addProperty("op", "insert_text"); + insertRequest.addProperty("text", "hello"); + WxCpDocModifyRequest modifyRequest = WxCpDocModifyRequest.builder() + .docId("doc123") + .build(); + modifyRequest.addRequest(insertRequest).addExtra("client_token", "token-1"); + assertThat(modifyRequest.toJson()).contains("\"requests\""); + assertThat(modifyRequest.toJson()).contains("\"insert_text\""); + assertThat(modifyRequest.toJson()).contains("\"client_token\":\"token-1\""); + + String json = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc123\"," + + "\"content\":{\"blocks\":[{\"block_id\":\"blk1\"}]}," + + "\"has_more\":true," + + "\"next_cursor\":\"cursor-1\"" + + "}"; + WxCpDocData result = WxCpDocData.fromJson(json); + assertThat(result.getDocId()).isEqualTo("doc123"); + assertThat(result.getContent().getAsJsonObject().getAsJsonArray("blocks")).hasSize(1); + assertThat(result.getEffectiveContent().getAsJsonObject().getAsJsonArray("blocks")).hasSize(1); + assertThat(result.getHasMore()).isTrue(); + assertThat(result.getNextCursor()).isEqualTo("cursor-1"); + + String docContentJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc123\"," + + "\"doc_content\":{\"blocks\":[{\"block_id\":\"blk2\"}]}" + + "}"; + WxCpDocData docContentResult = WxCpDocData.fromJson(docContentJson); + assertThat(docContentResult.getEffectiveContent().getAsJsonObject().getAsJsonArray("blocks")).hasSize(1); + } + + @Test + public void testDocModifyMemberAndSafetyJson() { + WxCpDocAuthInfo.DocMember updateMember = new WxCpDocAuthInfo.DocMember(); + updateMember.setType(1); + updateMember.setUserId("zhangsan"); + updateMember.setAuth(7); + + WxCpDocAuthInfo.DocMember deleteMember = new WxCpDocAuthInfo.DocMember(); + deleteMember.setType(1); + deleteMember.setUserId("lisi"); + + WxCpDocModifyMemberRequest memberRequest = WxCpDocModifyMemberRequest.builder() + .docId("doc123") + .updateFileMemberList(Collections.singletonList(updateMember)) + .delFileMemberList(Collections.singletonList(deleteMember)) + .build(); + assertThat(memberRequest.toJson()).contains("\"docid\":\"doc123\""); + assertThat(memberRequest.toJson()).contains("\"update_file_member_list\""); + assertThat(memberRequest.toJson()).contains("\"userid\":\"zhangsan\""); + assertThat(memberRequest.toJson()).contains("\"del_file_member_list\""); + + WxCpDocAuthInfo.Watermark watermark = new WxCpDocAuthInfo.Watermark(); + watermark.setMarginType(2); + watermark.setShowText(true); + watermark.setText("watermark"); + WxCpDocModifySafetySettingRequest safetyRequest = + WxCpDocModifySafetySettingRequest.builder() + .docId("doc123") + .enableReadonlyCopy(true) + .watermark(watermark) + .build(); + assertThat(safetyRequest.toJson()) + .contains("\"enable_readonly_copy\":true"); + assertThat(safetyRequest.toJson()) + .contains("\"text\":\"watermark\""); + } + + @Test + public void testDocUploadImageAndSmartSheetAuthJson() { + String uploadJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"image_url\":\"https://wedoc.test/image.png\"," + + "\"imageid\":\"img123\"," + + "\"media_id\":\"media123\"," + + "\"md5\":\"abc\"" + + "}"; + WxCpDocImageUploadResult uploadResult = WxCpDocImageUploadResult.fromJson(uploadJson); + assertThat(uploadResult.getEffectiveUrl()).isEqualTo("https://wedoc.test/image.png"); + assertThat(uploadResult.getImageId()).isEqualTo("img123"); + assertThat(uploadResult.getMediaId()).isEqualTo("media123"); + + JsonObject smartExtra = new JsonObject(); + smartExtra.addProperty("view_type", "field"); + WxCpDocSmartSheetAuthRequest smartRequest = WxCpDocSmartSheetAuthRequest.builder() + .docId("doc456") + .sheetId("sheet789") + .extra(smartExtra) + .build(); + assertThat(smartRequest.toJson()).contains("\"sheet_id\":\"sheet789\""); + assertThat(smartRequest.toJson()).contains("\"view_type\":\"field\""); + + JsonObject authInfo = new JsonObject(); + authInfo.addProperty("mode", "custom"); + WxCpDocSmartSheetModifyAuthRequest modifyAuthRequest = WxCpDocSmartSheetModifyAuthRequest.builder() + .docId("doc456") + .sheetId("sheet789") + .authInfo(authInfo) + .build(); + assertThat(modifyAuthRequest.toJson()).contains("\"auth_info\""); + assertThat(modifyAuthRequest.toJson()).contains("\"mode\":\"custom\""); + + String authJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc456\"," + + "\"sheet_id\":\"sheet789\"," + + "\"auth_info\":{\"mode\":\"custom\"}," + + "\"field_auth\":{\"columns\":[{\"field_id\":\"f1\"}]}" + + "}"; + WxCpDocSmartSheetAuth smartSheetAuth = WxCpDocSmartSheetAuth.fromJson(authJson); + assertThat(smartSheetAuth.getDocId()).isEqualTo("doc456"); + assertThat(smartSheetAuth.getAuthInfo().getAsJsonObject().get("mode").getAsString()).isEqualTo("custom"); + assertThat(smartSheetAuth.getFieldAuth().getAsJsonObject().getAsJsonArray("columns")).hasSize(1); + assertThat(smartSheetAuth.getEffectiveAuthInfo().getAsJsonObject().get("mode").getAsString()).isEqualTo("custom"); + } + + @Test + public void testDocAdminJson() { + WxCpDocAdminRequest request = WxCpDocAdminRequest.builder() + .docId("doc456") + .userId("zhangsan") + .type(1) + .build(); + assertThat(request.toJson()).contains("\"docid\":\"doc456\""); + assertThat(request.toJson()).contains("\"userid\":\"zhangsan\""); + assertThat(request.toJson()).contains("\"type\":1"); + + WxCpDocAdminRequest openUserRequest = WxCpDocAdminRequest.builder() + .docId("doc456") + .openUserId("ou_xxx") + .build(); + assertThat(openUserRequest.toJson()).contains("\"open_userid\":\"ou_xxx\""); + + String json = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc456\"," + + "\"admin_list\":[{\"userid\":\"zhangsan\",\"type\":1},{\"open_userid\":\"ou_xxx\",\"type\":2}]" + + "}"; + WxCpDocAdminListResult result = WxCpDocAdminListResult.fromJson(json); + assertThat(result.getDocId()).isEqualTo("doc456"); + assertThat(result.getAdminList()).hasSize(2); + assertThat(result.getAdminList().get(0).getUserId()).isEqualTo("zhangsan"); + assertThat(result.getAdminList().get(1).getOpenUserId()).isEqualTo("ou_xxx"); + } + + @Test + public void testSmartSheetCrudJson() { + JsonObject properties = new JsonObject(); + properties.addProperty("title", "Sheet A"); + JsonObject field = new JsonObject(); + field.addProperty("title", "Priority"); + JsonObject record = new JsonObject(); + record.addProperty("record_id", "rec-1"); + + WxCpDocSmartSheetRequest request = WxCpDocSmartSheetRequest.builder() + .docId("doc456") + .sheetId("sheet789") + .viewId("view1") + .build(); + request.addExtra("properties", properties) + .addExtraArrayItem("fields", field) + .addExtraArrayItem("records", record) + .addExtra("offset", 20); + assertThat(request.toJson()).contains("\"docid\":\"doc456\""); + assertThat(request.toJson()).contains("\"sheet_id\":\"sheet789\""); + assertThat(request.toJson()).contains("\"view_id\":\"view1\""); + assertThat(request.toJson()).contains("\"title\":\"Sheet A\""); + assertThat(request.toJson()).contains("\"record_id\":\"rec-1\""); + assertThat(request.toJson()).contains("\"offset\":20"); + + String resultJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"docid\":\"doc456\"," + + "\"sheet_id\":\"sheet789\"," + + "\"sheet_list\":[{\"sheet_id\":\"sheet1\"}]," + + "\"view_list\":[{\"view_id\":\"view1\"}]," + + "\"field_list\":[{\"field_id\":\"field1\"}]," + + "\"record_list\":[{\"record_id\":\"record1\"}]," + + "\"has_more\":true," + + "\"next_cursor\":101" + + "}"; + WxCpDocSmartSheetResult result = WxCpDocSmartSheetResult.fromJson(resultJson); + assertThat(result.getDocId()).isEqualTo("doc456"); + assertThat(result.getEffectiveSheets().getAsJsonArray()).hasSize(1); + assertThat(result.getEffectiveViews().getAsJsonArray()).hasSize(1); + assertThat(result.getEffectiveFields().getAsJsonArray()).hasSize(1); + assertThat(result.getEffectiveRecords().getAsJsonArray()).hasSize(1); + assertThat(result.getHasMore()).isTrue(); + assertThat(result.getNextCursor().getAsInt()).isEqualTo(101); + } + + @Test + public void testSpreadsheetAndFormModifyJson() { + WxCpDocSheetBatchUpdateRequest.Request.AddSheetRequest addSheetRequest = + new WxCpDocSheetBatchUpdateRequest.Request.AddSheetRequest(); + addSheetRequest.setTitle("Sheet A"); + addSheetRequest.setRowCount(20); + addSheetRequest.setColumnCount(5); + WxCpDocSheetBatchUpdateRequest.Request request = new WxCpDocSheetBatchUpdateRequest.Request(); + request.setAddSheetRequest(addSheetRequest); + + WxCpDocSheetBatchUpdateRequest batchUpdateRequest = WxCpDocSheetBatchUpdateRequest.builder() + .docId("doc123") + .requests(Collections.singletonList(request)) + .build(); + assertThat(batchUpdateRequest.toJson()).contains("\"docid\":\"doc123\""); + assertThat(batchUpdateRequest.toJson()).contains("\"add_sheet_request\""); + assertThat(batchUpdateRequest.toJson()).contains("\"row_count\":20"); + + String batchUpdateJson = "{" + + "\"add_sheet_response\":{\"properties\":" + + "{\"sheet_id\":\"sheet1\",\"title\":\"Sheet A\"," + + "\"row_count\":20,\"column_count\":5}}," + + "\"update_range_response\":{\"updated_cells\":2}" + + "}"; + WxCpDocSheetBatchUpdateResponse batchUpdateResponse = WxCpDocSheetBatchUpdateResponse.fromJson(batchUpdateJson); + assertThat(batchUpdateResponse.getAddSheetResponse().getProperties().getSheetId()).isEqualTo("sheet1"); + assertThat(batchUpdateResponse.getUpdateRangeResponse().getUpdatedCells()).isEqualTo(2); + + String propertiesJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"properties\":[{\"sheet_id\":\"sheet1\",\"title\":\"Sheet A\",\"row_count\":20,\"column_count\":5}]" + + "}"; + WxCpDocSheetProperties properties = WxCpDocSheetProperties.fromJson(propertiesJson); + assertThat(properties.getProperties()).hasSize(1); + assertThat(properties.getProperties().get(0).getTitle()).isEqualTo("Sheet A"); + + WxCpDocSheetGetDataRequest getDataRequest = WxCpDocSheetGetDataRequest.builder() + .docId("doc123") + .sheetId("sheet1") + .range("A1:B2") + .build(); + assertThat(getDataRequest.toJson()).contains("\"sheet_id\":\"sheet1\""); + assertThat(getDataRequest.toJson()).contains("\"range\":\"A1:B2\""); + + String sheetDataJson = "{" + + "\"errcode\":0," + + "\"errmsg\":\"ok\"," + + "\"grid_data\":{\"start_row\":0,\"start_column\":0," + + "\"rows\":[{\"values\":[{\"cell_value\":" + + "{\"text\":\"hello\"}}]}]}" + + "}"; + WxCpDocSheetData sheetData = WxCpDocSheetData.fromJson(sheetDataJson); + assertThat(sheetData.getGridData().getRows()).hasSize(1); + assertThat(sheetData.getGridData().getRows().get(0).getValues().get(0).getCellValue().getText()).isEqualTo("hello"); + + WxCpFormInfo formInfo = new WxCpFormInfo(); + formInfo.setFormTitle("日报"); + WxCpFormModifyRequest formModifyRequest = WxCpFormModifyRequest.builder() + .oper(1) + .formId("FORMID1") + .formInfo(formInfo) + .build(); + assertThat(formModifyRequest.toJson()).contains("\"oper\":1"); + assertThat(formModifyRequest.toJson()).contains("\"formid\":\"FORMID1\""); + assertThat(formModifyRequest.toJson()).contains("\"form_title\":\"日报\""); + } +} From e797c1265ef02a3c194f89cb65385dded6ad479d Mon Sep 17 00:00:00 2001 From: Wayne Lee Date: Sun, 15 Mar 2026 22:13:58 +0800 Subject: [PATCH 4/5] =?UTF-8?q?:art:=20#3920=20=E3=80=90=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=91=E6=96=B0=E5=A2=9E=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E4=BC=81=E4=B8=9A=E7=BE=A4=E5=8F=91API=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=94=AF=E6=8C=81tag=5Ffilter=E5=8F=82=E6=95=B0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cp/bean/external/WxCpMsgTemplate.java | 7 +++++++ .../cp/bean/external/msg/TagFilter.java | 20 +++++++++++++++++++ .../weixin/cp/bean/external/msg/TagList.java | 20 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagFilter.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagList.java 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 42e51afbb..3c2d9fb97 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 @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import me.chanjar.weixin.cp.bean.external.msg.Attachment; +import me.chanjar.weixin.cp.bean.external.msg.TagFilter; import me.chanjar.weixin.cp.bean.external.msg.Text; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; @@ -43,6 +44,12 @@ public class WxCpMsgTemplate implements Serializable { @SerializedName("chat_id_list") private List chatIdList; + /** + * 要进行群发的客户标签列表,同组标签之间按或关系进行筛选,不同组标签按且关系筛选,每组最多指定100个标签,支持规则组标签 + */ + @SerializedName("tag_filter") + private TagFilter tagFilter; + /** * 发送企业群发消息的成员userid,当类型为发送给客户群时必填 */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagFilter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagFilter.java new file mode 100644 index 000000000..da7851adb --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagFilter.java @@ -0,0 +1,20 @@ +package me.chanjar.weixin.cp.bean.external.msg; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 群发的客户标签 + * + * @author Winnie + */ +@Data +public class TagFilter implements Serializable { + private static final long serialVersionUID = -6756444546744020234L; + + @SerializedName("group_list") + private List groupList; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagList.java new file mode 100644 index 000000000..10ed191e9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/msg/TagList.java @@ -0,0 +1,20 @@ +package me.chanjar.weixin.cp.bean.external.msg; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 客户标签列表 + * + * @author Winnie + */ +@Data +public class TagList implements Serializable { + private static final long serialVersionUID = 1133054307780310675L; + + @SerializedName("tag_list") + private List tagList; +} From 5cc8e9114ff01b4ab1f3321a4d93aca293046ce9 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 15 Mar 2026 22:27:09 +0800 Subject: [PATCH 5/5] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=83=204.8.2.B?= =?UTF-8?q?=20=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- solon-plugins/pom.xml | 2 +- solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-channel-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-cp-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-miniapp-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-mp-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-open-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-pay-solon-plugin/pom.xml | 2 +- solon-plugins/wx-java-qidian-solon-plugin/pom.xml | 2 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-channel-multi-spring-boot-starter/pom.xml | 2 +- .../wx-java-channel-spring-boot-starter/pom.xml | 2 +- .../wx-java-cp-multi-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml | 2 +- .../wx-java-cp-tp-multi-spring-boot-starter/pom.xml | 2 +- .../wx-java-miniapp-multi-spring-boot-starter/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- .../wx-java-mp-multi-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- .../wx-java-open-multi-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- .../wx-java-pay-multi-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml | 2 +- weixin-graal/pom.xml | 2 +- weixin-java-channel/pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- weixin-java-qidian/pom.xml | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index 71129a0d8..e3327e201 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/solon-plugins/pom.xml b/solon-plugins/pom.xml index d49beabc7..9a375a60c 100644 --- a/solon-plugins/pom.xml +++ b/solon-plugins/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B pom wx-java-solon-plugins diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml index 4d7501026..908e3957e 100644 --- a/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-channel-solon-plugin/pom.xml b/solon-plugins/wx-java-channel-solon-plugin/pom.xml index e52aadc71..1e3f457cf 100644 --- a/solon-plugins/wx-java-channel-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-channel-solon-plugin/pom.xml @@ -3,7 +3,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml index 6518a5599..c0d1dcc18 100644 --- a/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml @@ -4,7 +4,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-cp-solon-plugin/pom.xml b/solon-plugins/wx-java-cp-solon-plugin/pom.xml index 50f6b22c7..b8d2c4335 100644 --- a/solon-plugins/wx-java-cp-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-cp-solon-plugin/pom.xml @@ -4,7 +4,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml index bd69cd0ed..6ca319ad7 100644 --- a/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml b/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml index a52eab54c..28f80f00b 100644 --- a/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml @@ -4,7 +4,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml index c9329fd29..f78f9b5d5 100644 --- a/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-mp-solon-plugin/pom.xml b/solon-plugins/wx-java-mp-solon-plugin/pom.xml index 00f7a3951..6ca5283c1 100644 --- a/solon-plugins/wx-java-mp-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-mp-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-open-solon-plugin/pom.xml b/solon-plugins/wx-java-open-solon-plugin/pom.xml index 1d0a03fb7..dcd856dc2 100644 --- a/solon-plugins/wx-java-open-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-open-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-pay-solon-plugin/pom.xml b/solon-plugins/wx-java-pay-solon-plugin/pom.xml index ab870301a..26e0b7fac 100644 --- a/solon-plugins/wx-java-pay-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-pay-solon-plugin/pom.xml @@ -5,7 +5,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/solon-plugins/wx-java-qidian-solon-plugin/pom.xml b/solon-plugins/wx-java-qidian-solon-plugin/pom.xml index d46c9ca32..cb0caaa1e 100644 --- a/solon-plugins/wx-java-qidian-solon-plugin/pom.xml +++ b/solon-plugins/wx-java-qidian-solon-plugin/pom.xml @@ -3,7 +3,7 @@ wx-java-solon-plugins com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index f37903c7e..ff2ce8823 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml index 083072f60..de7a38953 100644 --- a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml index 0d9e5e4e4..9f22f7950 100644 --- a/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml @@ -3,7 +3,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml index 6aa13ae81..514a67b3e 100644 --- a/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml index a560bf8e0..df23601c7 100644 --- a/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/pom.xml index 2d6c78009..fa0b98aab 100644 --- a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml index 32431c28c..05f595ac2 100644 --- a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 7e9ffbe30..25d5f6675 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml index 0857fc4e1..88b11099a 100644 --- a/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 5d0c2d026..9e95574bc 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 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 index 3b01d26f4..c5cf07e79 100644 --- 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 @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index 0b9e203b8..72c856f27 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/pom.xml index c8b08a8a0..1964bcbbf 100644 --- a/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 7bbfdbfbf..ecdb92573 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml index f26d5dd88..7e314df78 100644 --- a/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml @@ -3,7 +3,7 @@ wx-java-spring-boot-starters com.github.binarywang - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml index 272e07de5..a55cc1922 100644 --- a/weixin-graal/pom.xml +++ b/weixin-graal/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-graal diff --git a/weixin-java-channel/pom.xml b/weixin-java-channel/pom.xml index ffd3c6ddf..68edb075c 100644 --- a/weixin-java-channel/pom.xml +++ b/weixin-java-channel/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-channel diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 33fd85d4b..98b7ddda6 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 922d4f6b8..e109b1c60 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 318d538a1..2a1b5e4f1 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index f0c590bab..487728ea4 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index c05fc5270..6fa96d8ae 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 7098d8d8a..c9037cdf7 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B 4.0.0 diff --git a/weixin-java-qidian/pom.xml b/weixin-java-qidian/pom.xml index e40a096bf..b98ca26e4 100644 --- a/weixin-java-qidian/pom.xml +++ b/weixin-java-qidian/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 4.8.1.B + 4.8.2.B weixin-java-qidian