Skip to content

Commit 4c447e5

Browse files
committed
feat(cp): refine wedoc form share and statistic support
1 parent 7d3c8ec commit 4c447e5

File tree

9 files changed

+133
-30
lines changed

9 files changed

+133
-30
lines changed

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import me.chanjar.weixin.cp.bean.oa.doc.*;
77

88
import java.io.File;
9+
import java.util.Collections;
10+
import java.util.List;
911

1012
/**
1113
* 企业微信文档相关接口.
@@ -81,6 +83,19 @@ public interface WxCpOaWeDocService {
8183
*/
8284
WxCpDocShare docShare(@NonNull String docId) throws WxErrorException;
8385

86+
/**
87+
* 分享文档/收集表
88+
* 该接口用于获取文档或收集表的分享链接。
89+
* <p>
90+
* 请求方式:POST(HTTPS)
91+
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/doc_share?access_token=ACCESS_TOKEN
92+
*
93+
* @param request 分享请求,docid/formid 二选一
94+
* @return url 文档分享链接
95+
* @throws WxErrorException the wx error exception
96+
*/
97+
WxCpDocShare docShare(@NonNull WxCpDocShareRequest request) throws WxErrorException;
98+
8499
/**
85100
* 获取文档权限信息
86101
* 该接口用于获取文档、表格、智能表格的查看规则、文档通知范围及权限、安全设置信息。
@@ -434,7 +449,7 @@ public interface WxCpOaWeDocService {
434449
* 该接口用于创建收集表。
435450
* <p>
436451
* 请求方式:POST(HTTPS)
437-
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/create_form?access_token=ACCESS_TOKEN
452+
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/create_collect?access_token=ACCESS_TOKEN
438453
*
439454
* @param request 创建收集表请求
440455
* @return 创建收集表结果
@@ -447,7 +462,7 @@ public interface WxCpOaWeDocService {
447462
* 该接口用于编辑收集表。
448463
* <p>
449464
* 请求方式:POST(HTTPS)
450-
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/modify_form?access_token=ACCESS_TOKEN
465+
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/modify_collect?access_token=ACCESS_TOKEN
451466
*
452467
* @param request 编辑收集表请求
453468
* @return wx cp base resp
@@ -475,11 +490,23 @@ public interface WxCpOaWeDocService {
475490
* 请求方式:POST(HTTPS)
476491
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_form_statistic?access_token=ACCESS_TOKEN
477492
*
493+
* @param requests 收集表统计请求数组
494+
* @return 收集表统计信息数组
495+
* @throws WxErrorException the wx error exception
496+
*/
497+
List<WxCpFormStatistic> formStatistic(@NonNull List<WxCpFormStatisticRequest> requests) throws WxErrorException;
498+
499+
/**
500+
* 单个收集表统计查询的兼容封装,底层仍按官方数组请求发送。
501+
*
478502
* @param request 收集表统计请求
479503
* @return 收集表统计信息
480504
* @throws WxErrorException the wx error exception
481505
*/
482-
WxCpFormStatistic formStatistic(@NonNull WxCpFormStatisticRequest request) throws WxErrorException;
506+
default WxCpFormStatistic formStatistic(@NonNull WxCpFormStatisticRequest request) throws WxErrorException {
507+
List<WxCpFormStatistic> results = formStatistic(Collections.singletonList(request));
508+
return results == null || results.isEmpty() ? null : results.get(0);
509+
}
483510

484511
/**
485512
* 获取收集表答案

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import me.chanjar.weixin.cp.bean.oa.doc.*;
1313

1414
import java.io.File;
15+
import java.util.List;
1516

1617
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*;
1718

@@ -60,10 +61,13 @@ public WxCpDocInfo docInfo(@NonNull String docId) throws WxErrorException {
6061

6162
@Override
6263
public WxCpDocShare docShare(@NonNull String docId) throws WxErrorException {
64+
return docShare(WxCpDocShareRequest.builder().docId(docId).build());
65+
}
66+
67+
@Override
68+
public WxCpDocShare docShare(@NonNull WxCpDocShareRequest request) throws WxErrorException {
6369
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_DOC_SHARE);
64-
JsonObject jsonObject = new JsonObject();
65-
jsonObject.addProperty("docid", docId);
66-
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
70+
String responseContent = this.cpService.post(apiUrl, request.toJson());
6771
return WxCpDocShare.fromJson(responseContent);
6872
}
6973

@@ -314,10 +318,10 @@ public WxCpFormInfoResult formInfo(@NonNull String formId) throws WxErrorExcepti
314318
}
315319

316320
@Override
317-
public WxCpFormStatistic formStatistic(@NonNull WxCpFormStatisticRequest request) throws WxErrorException {
321+
public List<WxCpFormStatistic> formStatistic(@NonNull List<WxCpFormStatisticRequest> requests) throws WxErrorException {
318322
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_GET_FORM_STATISTIC);
319-
String responseContent = this.cpService.post(apiUrl, request.toJson());
320-
return WxCpFormStatistic.fromJson(responseContent);
323+
String responseContent = this.cpService.post(apiUrl, WxCpFormStatisticRequest.toJson(requests));
324+
return WxCpFormStatistic.listFromJson(responseContent);
321325
}
322326

323327
@Override
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package me.chanjar.weixin.cp.bean.oa.doc;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
import lombok.experimental.Accessors;
9+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
10+
11+
import java.io.Serializable;
12+
13+
/**
14+
* 文档/收集表分享请求.
15+
*/
16+
@Data
17+
@Builder
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
@Accessors(chain = true)
21+
public class WxCpDocShareRequest implements Serializable {
22+
private static final long serialVersionUID = 7760968921955136050L;
23+
24+
@SerializedName("docid")
25+
private String docId;
26+
27+
@SerializedName("formid")
28+
private String formId;
29+
30+
public static WxCpDocShareRequest fromJson(String json) {
31+
return WxCpGsonBuilder.create().fromJson(json, WxCpDocShareRequest.class);
32+
}
33+
34+
public String toJson() {
35+
return WxCpGsonBuilder.create().toJson(this);
36+
}
37+
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormInfo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ public static class FormSetting implements Serializable {
117117
@SerializedName("allow_multi_fill")
118118
private Boolean allowMultiFill;
119119

120+
@SerializedName("max_fill_cnt")
121+
private Integer maxFillCnt;
122+
120123
@SerializedName("timed_finish")
121124
private Long timedFinish;
122125

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatistic.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
99

1010
import java.io.Serializable;
11+
import java.util.Arrays;
1112
import java.util.List;
1213

1314
/**
@@ -20,6 +21,12 @@ public class WxCpFormStatistic extends WxCpBaseResp implements Serializable {
2021
@SerializedName("fill_cnt")
2122
private Long fillCnt;
2223

24+
@SerializedName("repeated_id")
25+
private String repeatedId;
26+
27+
@SerializedName("repeated_name")
28+
private String repeatedName;
29+
2330
@SerializedName("fill_user_cnt")
2431
private Long fillUserCnt;
2532

@@ -42,6 +49,11 @@ public static WxCpFormStatistic fromJson(String json) {
4249
return WxCpGsonBuilder.create().fromJson(json, WxCpFormStatistic.class);
4350
}
4451

52+
public static List<WxCpFormStatistic> listFromJson(String json) {
53+
WxCpFormStatistic[] results = WxCpGsonBuilder.create().fromJson(json, WxCpFormStatistic[].class);
54+
return results == null ? null : Arrays.asList(results);
55+
}
56+
4557
public String toJson() {
4658
return WxCpGsonBuilder.create().toJson(this);
4759
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpFormStatisticRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
1010

1111
import java.io.Serializable;
12+
import java.util.List;
1213

1314
/**
1415
* 收集表统计请求.
@@ -46,4 +47,8 @@ public static WxCpFormStatisticRequest fromJson(String json) {
4647
public String toJson() {
4748
return WxCpGsonBuilder.create().toJson(this);
4849
}
50+
51+
public static String toJson(List<WxCpFormStatisticRequest> requests) {
52+
return WxCpGsonBuilder.create().toJson(requests);
53+
}
4954
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,11 @@ interface Oa {
593593
/**
594594
* The constant WEDOC_CREATE_FORM.
595595
*/
596-
String WEDOC_CREATE_FORM = "/cgi-bin/wedoc/create_form";
596+
String WEDOC_CREATE_FORM = "/cgi-bin/wedoc/create_collect";
597597
/**
598598
* The constant WEDOC_MODIFY_FORM.
599599
*/
600-
String WEDOC_MODIFY_FORM = "/cgi-bin/wedoc/modify_form";
600+
String WEDOC_MODIFY_FORM = "/cgi-bin/wedoc/modify_collect";
601601
/**
602602
* The constant WEDOC_GET_FORM_INFO.
603603
*/

weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImplTest.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public void testLegacyApisUseExpectedPaths() throws WxErrorException {
4444
when(configStorage.getApiUrl(WEDOC_SPREADSHEET_BATCH_UPDATE)).thenReturn("https://api.test/spreadsheet/batch_update");
4545
when(configStorage.getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES)).thenReturn("https://api.test/spreadsheet/get_sheet_properties");
4646
when(configStorage.getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA)).thenReturn("https://api.test/spreadsheet/get_sheet_range_data");
47-
when(configStorage.getApiUrl(WEDOC_CREATE_FORM)).thenReturn("https://api.test/create_form");
48-
when(configStorage.getApiUrl(WEDOC_MODIFY_FORM)).thenReturn("https://api.test/modify_form");
47+
when(configStorage.getApiUrl(WEDOC_CREATE_FORM)).thenReturn("https://api.test/create_collect");
48+
when(configStorage.getApiUrl(WEDOC_MODIFY_FORM)).thenReturn("https://api.test/modify_collect");
4949
when(configStorage.getApiUrl(WEDOC_GET_FORM_INFO)).thenReturn("https://api.test/get_form_info");
5050
when(configStorage.getApiUrl(WEDOC_GET_FORM_STATISTIC)).thenReturn("https://api.test/get_form_statistic");
5151
when(configStorage.getApiUrl(WEDOC_GET_FORM_ANSWER)).thenReturn("https://api.test/get_form_answer");
@@ -74,14 +74,14 @@ public void testLegacyApisUseExpectedPaths() throws WxErrorException {
7474
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"properties\":[{\"sheet_id\":\"sheet1\",\"title\":\"Sheet A\",\"row_count\":20,\"column_count\":5}]}");
7575
when(cpService.post(eq("https://api.test/spreadsheet/get_sheet_range_data"), anyString()))
7676
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"grid_data\":{\"start_row\":0,\"start_column\":0,\"rows\":[{\"values\":[{\"cell_value\":{\"text\":\"hello\"}}]}]}}");
77-
when(cpService.post(eq("https://api.test/create_form"), anyString()))
78-
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"formid\":\"FORMID1\",\"url\":\"https://wedoc.test/form/1\"}");
79-
when(cpService.post(eq("https://api.test/modify_form"), anyString()))
77+
when(cpService.post(eq("https://api.test/create_collect"), anyString()))
78+
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"formid\":\"FORMID1\"}");
79+
when(cpService.post(eq("https://api.test/modify_collect"), anyString()))
8080
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}");
8181
when(cpService.post(eq("https://api.test/get_form_info"), anyString()))
8282
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"form_info\":{\"formid\":\"FORMID1\",\"form_title\":\"日报\"}}");
8383
when(cpService.post(eq("https://api.test/get_form_statistic"), anyString()))
84-
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"fill_cnt\":3,\"submit_users\":[{\"userid\":\"zhangsan\",\"answer_id\":1}]}");
84+
.thenReturn("[{\"repeated_id\":\"repeat-1\",\"fill_cnt\":3,\"submit_users\":[{\"userid\":\"zhangsan\",\"answer_id\":1}]}]");
8585
when(cpService.post(eq("https://api.test/get_form_answer"), anyString()))
8686
.thenReturn("{\"errcode\":0,\"errmsg\":\"ok\",\"answer\":{\"answer_list\":[{\"answer_id\":1,\"userid\":\"zhangsan\",\"reply\":{\"items\":[{\"question_id\":1,\"text_reply\":\"ok\"}]}}]}}");
8787

@@ -119,9 +119,11 @@ public void testLegacyApisUseExpectedPaths() throws WxErrorException {
119119
assertThat(docInfo.getDocBaseInfo().getDocName()).isEqualTo("日报");
120120
verify(cpService).post(eq("https://api.test/get_doc_base_info"), anyString());
121121

122-
WxCpDocShare docShare = service.docShare("doc1");
122+
WxCpDocShare docShare = service.docShare(WxCpDocShareRequest.builder().formId("FORMID1").build());
123123
assertThat(docShare.getShareUrl()).isEqualTo("https://wedoc.test/share/1");
124-
verify(cpService).post(eq("https://api.test/doc_share"), anyString());
124+
ArgumentCaptor<String> docShareBodyCaptor = ArgumentCaptor.forClass(String.class);
125+
verify(cpService).post(eq("https://api.test/doc_share"), docShareBodyCaptor.capture());
126+
assertThat(docShareBodyCaptor.getValue()).contains("\"formid\":\"FORMID1\"");
125127

126128
WxCpDocAuthInfo docAuthInfo = service.docGetAuth("doc1");
127129
assertThat(docAuthInfo.getAccessRule().getEnableCorpInternal()).isTrue();
@@ -195,15 +197,15 @@ public void testLegacyApisUseExpectedPaths() throws WxErrorException {
195197
.formInfo(formInfo)
196198
.build());
197199
assertThat(formCreateResult.getFormId()).isEqualTo("FORMID1");
198-
verify(cpService).post(eq("https://api.test/create_form"), anyString());
200+
verify(cpService).post(eq("https://api.test/create_collect"), anyString());
199201

200202
WxCpBaseResp formModifyResp = service.formModify(WxCpFormModifyRequest.builder()
201203
.oper(1)
202204
.formId("FORMID1")
203205
.formInfo(formInfo)
204206
.build());
205207
assertThat(formModifyResp.getErrcode()).isZero();
206-
verify(cpService).post(eq("https://api.test/modify_form"), anyString());
208+
verify(cpService).post(eq("https://api.test/modify_collect"), anyString());
207209

208210
WxCpFormInfoResult formInfoResult = service.formInfo("FORMID1");
209211
assertThat(formInfoResult.getFormInfo().getFormId()).isEqualTo("FORMID1");
@@ -215,7 +217,10 @@ public void testLegacyApisUseExpectedPaths() throws WxErrorException {
215217
.repeatedId("repeat-1")
216218
.build());
217219
assertThat(formStatistic.getFillCnt()).isEqualTo(3);
218-
verify(cpService).post(eq("https://api.test/get_form_statistic"), anyString());
220+
ArgumentCaptor<String> formStatisticBodyCaptor = ArgumentCaptor.forClass(String.class);
221+
verify(cpService).post(eq("https://api.test/get_form_statistic"), formStatisticBodyCaptor.capture());
222+
assertThat(formStatisticBodyCaptor.getValue()).startsWith("[");
223+
assertThat(formStatisticBodyCaptor.getValue()).contains("\"repeated_id\":\"repeat-1\"");
219224

220225
WxCpFormAnswer formAnswer = service.formAnswer(WxCpFormAnswerRequest.builder()
221226
.repeatedId("repeat-1")

weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpOaWeDocJsonTest.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,10 @@ public void testDocCreateRenameInfoAndShareJson() {
7777
String createJson = "{"
7878
+ "\"errcode\":0,"
7979
+ "\"errmsg\":\"ok\","
80-
+ "\"url\":\"https://wedoc.test/doc/1\","
8180
+ "\"docid\":\"doc123\""
8281
+ "}";
8382
WxCpDocCreateData createData = WxCpDocCreateData.fromJson(createJson);
8483
assertThat(createData.getDocId()).isEqualTo("doc123");
85-
assertThat(createData.getUrl()).isEqualTo("https://wedoc.test/doc/1");
8684

8785
WxCpDocRenameRequest renameRequest = WxCpDocRenameRequest.builder()
8886
.docId("doc123")
@@ -106,6 +104,11 @@ public void testDocCreateRenameInfoAndShareJson() {
106104
assertThat(docInfo.getDocBaseInfo().getDocId()).isEqualTo("doc123");
107105
assertThat(docInfo.getDocBaseInfo().getDocName()).isEqualTo("日报");
108106

107+
WxCpDocShareRequest shareRequest = WxCpDocShareRequest.builder()
108+
.formId("FORMID1")
109+
.build();
110+
assertThat(shareRequest.toJson()).contains("\"formid\":\"FORMID1\"");
111+
109112
String shareJson = "{"
110113
+ "\"errcode\":0,"
111114
+ "\"errmsg\":\"ok\","
@@ -157,30 +160,37 @@ public void testFormInfoResultFromJson() {
157160
+ "\"formid\":\"FORMID1\","
158161
+ "\"form_title\":\"api创建的收集表\","
159162
+ "\"form_question\":{\"items\":[{\"question_id\":1,\"title\":\"问题1\",\"pos\":1,\"status\":1,\"reply_type\":1,\"must_reply\":true}]},"
160-
+ "\"form_setting\":{\"fill_out_auth\":1},"
163+
+ "\"form_setting\":{\"fill_out_auth\":1,\"max_fill_cnt\":2},"
161164
+ "\"repeated_id\":[\"REPEAT_ID1\"]"
162165
+ "}"
163166
+ "}";
164167

165168
WxCpFormInfoResult result = WxCpFormInfoResult.fromJson(json);
166169
assertThat(result.getFormInfo().getFormId()).isEqualTo("FORMID1");
167170
assertThat(result.getFormInfo().getFormQuestion().getItems().get(0).getTitle()).isEqualTo("问题1");
171+
assertThat(result.getFormInfo().getFormSetting().getMaxFillCnt()).isEqualTo(2);
168172
assertThat(result.getFormInfo().getRepeatedId()).containsExactly("REPEAT_ID1");
169173
}
170174

171175
@Test
172176
public void testFormStatisticAndAnswerFromJson() {
173-
String statisticJson = "{"
174-
+ "\"errcode\":0,"
175-
+ "\"errmsg\":\"ok\","
177+
String statisticRequestJson = WxCpFormStatisticRequest.toJson(Collections.singletonList(
178+
WxCpFormStatisticRequest.builder().repeatedId("REPEAT_ID1").reqType(1).limit(100L).cursor(0L).build()
179+
));
180+
assertThat(statisticRequestJson).startsWith("[");
181+
assertThat(statisticRequestJson).contains("\"repeated_id\":\"REPEAT_ID1\"");
182+
183+
String statisticJson = "[{"
184+
+ "\"repeated_id\":\"REPEAT_ID1\","
185+
+ "\"repeated_name\":\"第1次收集\","
176186
+ "\"fill_cnt\":1,"
177187
+ "\"fill_user_cnt\":1,"
178188
+ "\"unfill_user_cnt\":2,"
179189
+ "\"submit_users\":[{\"userid\":\"zhangsan\",\"answer_id\":3,\"submit_time\":1668418200,\"user_name\":\"张三\"}],"
180190
+ "\"has_more\":false,"
181191
+ "\"cursor\":1"
182-
+ "}";
183-
WxCpFormStatistic statistic = WxCpFormStatistic.fromJson(statisticJson);
192+
+ "}]";
193+
WxCpFormStatistic statistic = WxCpFormStatistic.listFromJson(statisticJson).get(0);
184194
assertThat(statistic.getSubmitUsers()).hasSize(1);
185195
assertThat(statistic.getSubmitUsers().get(0).getAnswerId()).isEqualTo(3L);
186196

0 commit comments

Comments
 (0)