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..c30b37203 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,21 @@
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 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 +60,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 +125,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\":\"日报\"");
+ }
+}