userIdList) throws WxErrorException;
/**
*
@@ -41,13 +40,63 @@ public interface WxCpOaService {
* @param datetime 需要获取规则的当天日期
* @param userIdList 需要获取打卡规则的用户列表
* @return 打卡规则列表
- * @throws WxErrorException 异常
+ * @throws WxErrorException
*/
List getCheckinOption(Date datetime, List userIdList) throws WxErrorException;
/**
*
- * 获取审批数据
+ *
+ * 批量获取审批单号
+ *
+ * 审批应用及有权限的自建应用,可通过Secret调用本接口,以获取企业一段时间内企业微信“审批应用”单据的审批编号,支持按模板类型、申请人、部门、申请单审批状态等条件筛选。
+ * 自建应用调用此接口,需在“管理后台-应用管理-审批-API-审批数据权限”中,授权应用允许提交审批单据。
+ *
+ * 一次拉取调用最多拉取100个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
+ *
+ * API doc : https://work.weixin.qq.com/api/doc/90000/90135/91816
+ *
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @param cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取
+ * @param size 一次请求拉取审批单数量,默认值为100,上限值为100
+ * @param filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件,nullable
+ * @return WxCpApprovalInfo
+ * @throws WxErrorException
+ */
+ WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, Integer cursor, Integer size,
+ List filters) throws WxErrorException;
+
+ /**
+ * short method
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return WxCpApprovalInfo
+ * @throws WxErrorException
+ * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo
+ */
+ WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException;
+
+ /**
+ *
+ * 获取审批申请详情
+ *
+ * 企业可通过审批应用或自建应用Secret调用本接口,根据审批单号查询企业微信“审批应用”的审批申请详情。
+ *
+ * API Doc : https://work.weixin.qq.com/api/doc/90000/90135/91983
+ *
+ *
+ * @param spNo 审批单编号。
+ * @return WxCpApprovaldetail
+ * @throws WxErrorException
+ */
+ WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException;
+
+ /**
+ *
+ * 获取审批数据 (已过期, 请使用"批量获取审批单号" && "获取审批申请详情")
* 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
* API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530
*
@@ -55,10 +104,32 @@ public interface WxCpOaService {
* @param startTime 获取审批记录的开始时间
* @param endTime 获取审批记录的结束时间
* @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取
- * @throws WxErrorException 异常
+ * @throws WxErrorException
+ * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo
+ * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalDetail
*/
+ @Deprecated
WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException;
- List getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException;
+ /**
+ * 获取公费电话拨打记录
+ *
+ * @param startTime 查询的起始时间戳
+ * @param endTime 查询的结束时间戳
+ * @param offset 分页查询的偏移量
+ * @param limit 分页查询的每页大小,默认为100条,如该参数大于100则按100处理
+ * @return
+ * @throws WxErrorException
+ */
+ List getDialRecord(Date startTime, Date endTime, Integer offset,
+ Integer limit) throws WxErrorException;
+
+ /**
+ * 获取审批模板详情
+ * @param templateId 模板ID
+ * @return
+ * @throws WxErrorException
+ */
+ WxCpTemplateResult getTemplateDetail(@NonNull String templateId)throws WxErrorException;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index 9c7396ab1b..9dd1333bfa 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -205,7 +205,7 @@ public WxCpProviderToken getProviderToken(String corpId, String providerSecret)
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("corpid", corpId);
jsonObject.addProperty("provider_secret", providerSecret);
- return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN), jsonObject.toString()));
+ return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(Tp.GET_PROVIDER_TOKEN), jsonObject.toString()));
}
@Override
@@ -281,7 +281,9 @@ protected T executeInternal(RequestExecutor executor, String uri, E
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
this.configStorage.expireAccessToken();
- return execute(executor, uri, data);
+ if (this.getWxCpConfigStorage().autoRefreshToken()) {
+ return this.execute(executor, uri, data);
+ }
}
if (error.getErrorCode() != 0) {
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java
index fe8e3c08e3..dea5428c1b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java
@@ -194,7 +194,9 @@ protected T executeInternal(RequestExecutor executor, String uri, E
if (error.getErrorCode() == 42009) {
// 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token
this.configStorage.expireSuiteAccessToken();
- return execute(executor, uri, data);
+ if (this.getWxCpTpConfigStorage().autoRefreshToken()) {
+ return this.execute(executor, uri, data);
+ }
}
if (error.getErrorCode() != 0) {
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
index 8a5b7d56e8..044b1e5d49 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
@@ -25,6 +25,13 @@ public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxEr
return WxCpUserExternalContactInfo.fromJson(responseContent);
}
+ @Override
+ public WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException {
+ final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_DETAIL + userId);
+ String responseContent = this.mainService.get(url, null);
+ return WxCpUserExternalContactInfo.fromJson(responseContent);
+ }
+
@Override
public List listExternalContacts(String userId) throws WxErrorException {
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java
index b8449ced13..0484e1f62a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java
@@ -5,15 +5,12 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpOaService;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult;
-import me.chanjar.weixin.cp.bean.WxCpCheckinData;
-import me.chanjar.weixin.cp.bean.WxCpCheckinOption;
-import me.chanjar.weixin.cp.bean.WxCpDialRecord;
-import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
+import me.chanjar.weixin.cp.bean.oa.*;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import java.util.Date;
@@ -22,7 +19,7 @@
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*;
/**
- * .
+ * 企业微信 OA 接口实现
*
* @author Element
* @date 2019-04-06 11:20
@@ -31,6 +28,9 @@
public class WxCpOaServiceImpl implements WxCpOaService {
private final WxCpService mainService;
+ private static final int MONTH_SECONDS = 30 * 24 * 60 * 60;
+ private static final int USER_IDS_LIMIT = 100;
+
@Override
public List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime,
List userIdList) throws WxErrorException {
@@ -38,14 +38,14 @@ public List getCheckinData(Integer openCheckinDataType, Date st
throw new RuntimeException("starttime and endtime can't be null");
}
- if (userIdList == null || userIdList.size() > 100) {
- throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取");
+ if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) {
+ throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取");
}
long endtimestamp = endTime.getTime() / 1000L;
long starttimestamp = startTime.getTime() / 1000L;
- if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) {
+ if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) {
throw new RuntimeException("获取记录时间跨度不超过一个月");
}
@@ -79,8 +79,8 @@ public List getCheckinOption(Date datetime, List user
throw new RuntimeException("datetime can't be null");
}
- if (userIdList == null || userIdList.size() > 100) {
- throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取");
+ if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) {
+ throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取");
}
JsonArray jsonArray = new JsonArray();
@@ -104,6 +104,59 @@ public List getCheckinOption(Date datetime, List user
);
}
+ @Override
+ public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime,
+ Integer cursor, Integer size, List filters) throws WxErrorException {
+
+ if (cursor == null) {
+ cursor = 0;
+ }
+
+ if (size == null) {
+ size = 100;
+ }
+
+ if (size < 0 || size > 100) {
+ throw new IllegalArgumentException("size参数错误,请使用[1-100]填充,默认100");
+ }
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("starttime", startTime.getTime() / 1000L);
+ jsonObject.addProperty("endtime", endTime.getTime() / 1000L);
+ jsonObject.addProperty("size", size);
+ jsonObject.addProperty("cursor", cursor);
+
+ if (filters != null && !filters.isEmpty()) {
+ JsonArray filterJsonArray = new JsonArray();
+ for (WxCpApprovalInfoQueryFilter filter : filters) {
+ filterJsonArray.add(new JsonParser().parse(filter.toJson()));
+ }
+ jsonObject.add("filters", filterJsonArray);
+ }
+
+ final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_INFO);
+ String responseContent = this.mainService.post(url, jsonObject.toString());
+
+ return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalInfo.class);
+ }
+
+ @Override
+ public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException {
+ return this.getApprovalInfo(startTime, endTime, null, null, null);
+ }
+
+ @Override
+ public WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException {
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("sp_no", spNo);
+
+ final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DETAIL);
+ String responseContent = this.mainService.post(url, jsonObject.toString());
+
+ return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDetailResult.class);
+ }
+
@Override
public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
@@ -139,7 +192,7 @@ public List getDialRecord(Date startTime, Date endTime, Integer
long endtimestamp = endTime.getTime() / 1000L;
long starttimestamp = startTime.getTime() / 1000L;
- if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) {
+ if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) {
throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询");
}
@@ -156,4 +209,13 @@ public List getDialRecord(Date startTime, Date endTime, Integer
}.getType()
);
}
+
+ @Override
+ public WxCpTemplateResult getTemplateDetail(@NonNull String templateId) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("template_id",templateId);
+ final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_TEMPLATE_DETAIL);
+ String responseContent = this.mainService.post(url, jsonObject.toString());
+ return WxCpGsonBuilder.create().fromJson(responseContent,WxCpTemplateResult.class);
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java
index b7389afa2b..90354154a6 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java
@@ -1,15 +1,15 @@
package me.chanjar.weixin.cp.bean;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* 微信用户信息.
*
@@ -27,6 +27,8 @@ public class WxCpUser implements Serializable {
private Gender gender;
private String email;
private String avatar;
+ private String thumbAvatar;
+
/**
* 地址。长度最大128个字符
*/
@@ -34,6 +36,10 @@ public class WxCpUser implements Serializable {
private String avatarMediaId;
private Integer status;
private Integer enable;
+ /**
+ * 别名;第三方仅通讯录应用可获取
+ */
+ private String alias;
private Integer isLeader;
/**
* is_leader_in_dept.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java
new file mode 100644
index 0000000000..26b37aea9c
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import lombok.Data;
+import me.chanjar.weixin.cp.bean.oa.applydata.Content;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 审批申请数据
+ *
+ * @author element
+ */
+@Data
+public class WxCpApprovalApplyData implements Serializable {
+
+ private static final long serialVersionUID = 4061352949894274704L;
+
+ private List contents;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java
new file mode 100644
index 0000000000..f648a6a915
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 申请人信息
+ * @author element
+ */
+@Data
+public class WxCpApprovalApplyer extends WxCpOperator implements Serializable {
+
+ private static final long serialVersionUID = -8974662568286821271L;
+
+ /**
+ * 申请人所在部门id
+ */
+ @SerializedName("partyid")
+ private String partyId;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java
new file mode 100644
index 0000000000..8a70e3e6e9
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 审批申请备注信息
+ *
+ * @author element
+ */
+@Data
+public class WxCpApprovalComment implements Serializable {
+
+ private static final long serialVersionUID = -5430367411926856292L;
+
+ /**
+ * 备注人信息
+ */
+ private WxCpOperator commentUserInfo;
+
+ /**
+ * 备注提交时间戳,Unix时间戳
+ */
+ @SerializedName("commenttime")
+ private Long commentTime;
+
+ /**
+ * 备注id
+ */
+ @SerializedName("commentid")
+ private String commentId;
+
+ /**
+ * 备注文本内容
+ */
+ @SerializedName("commentcontent")
+ private String commentContent;
+
+ /**
+ * 备注附件id,可能有多个
+ */
+ @SerializedName("media_id")
+ private List mediaIds;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDataResult.java
similarity index 96%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDataResult.java
index 383c526568..b348c97a94 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDataResult.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.oa;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@@ -12,6 +12,7 @@
* @author Element
* @date 2019-04-06 14:36
*/
+@Deprecated
@Data
public class WxCpApprovalDataResult implements Serializable {
private static final long serialVersionUID = -1046940445840716590L;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java
new file mode 100644
index 0000000000..5021a57ee6
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java
@@ -0,0 +1,78 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 审批申请详情
+ *
+ * @author element
+ */
+@Data
+public class WxCpApprovalDetail implements Serializable {
+
+ private static final long serialVersionUID = 1353393306564207170L;
+
+ /**
+ * 审批编号
+ */
+ @SerializedName("sp_no")
+ private String spNo;
+
+ /**
+ * 审批申请类型名称(审批模板名称)
+ */
+ @SerializedName("sp_name")
+ private String spName;
+
+ /**
+ * 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
+ */
+ @SerializedName("sp_status")
+ private WxCpSpStatus spStatus;
+
+ /**
+ * 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。
+ */
+ @SerializedName("template_id")
+ private String templateId;
+
+ /**
+ * 审批申请提交时间,Unix时间戳
+ */
+ @SerializedName("apply_time")
+ private Long applyTime;
+
+ /**
+ * 申请人信息
+ */
+ private WxCpApprovalApplyer applyer;
+
+ /**
+ * 审批流程信息,可能有多个审批节点
+ */
+ @SerializedName("sp_record")
+ private WxCpApprovalRecord spRecord;
+
+ /**
+ * 抄送信息,可能有多个抄送节点
+ */
+ @SerializedName("notifyer")
+ private WxCpOperator notifyer;
+
+ /**
+ * 审批申请数据
+ */
+ @SerializedName("apply_data")
+ private WxCpApprovalApplyData applyData;
+
+ /**
+ * 审批申请备注信息,可能有多个备注节点
+ */
+ @SerializedName("comments")
+ private List comments;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java
new file mode 100644
index 0000000000..eb8cd1c1ad
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 审批申请详情响应结果
+ *
+ * @author element
+ */
+@Data
+public class WxCpApprovalDetailResult implements Serializable {
+
+ private static final long serialVersionUID = 3909779949756252918L;
+
+ @SerializedName("errcode")
+ private Integer errCode;
+
+ @SerializedName("errmsg")
+ private String errMsg;
+
+ @SerializedName("info")
+ private WxCpApprovalDetail info;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java
new file mode 100644
index 0000000000..b12d88baf8
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author element
+ */
+@Data
+public class WxCpApprovalInfo implements Serializable {
+
+ private static final long serialVersionUID = 7387181805254287167L;
+
+ @SerializedName("errcode")
+ private Integer errCode;
+
+ @SerializedName("errmsg")
+ private String errMsg;
+
+ @SerializedName("sp_no_list")
+ private List spNoList;
+
+ @SerializedName("next_cursor")
+ private Integer nextCursor;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java
new file mode 100644
index 0000000000..5271312081
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java
@@ -0,0 +1,61 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 批量获取审批单号的筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件
+ * 注意:
+ * 仅“部门”支持同时配置多个筛选条件。
+ * 不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系
+ *
+ *
+ * @author element
+ */
+@Data
+public class WxCpApprovalInfoQueryFilter implements Serializable {
+
+ private static final long serialVersionUID = 3318064927980231802L;
+
+ private WxCpApprovalInfoQueryFilter.KEY key;
+
+ private Object value;
+
+ public String toJson() {
+ return WxGsonBuilder.create().toJson(this);
+ }
+
+ public static enum KEY {
+
+ /**
+ * template_id - 模板类型/模板id;
+ */
+ @SerializedName("template_id")
+ TEMPLATE_ID("template_id"),
+ /**
+ * creator - 申请人;
+ */
+ @SerializedName("creator")
+ CREATOR("creator"),
+ /**
+ * department - 审批单提单者所在部门;
+ */
+ @SerializedName("department")
+ DEPARTMENT("department"),
+ /**
+ * sp_status - 审批状态。
+ */
+ @SerializedName("sp_status")
+ SP_STATUS("sp_status");
+
+ private String value;
+
+ private KEY(String value) {
+ this.value = value;
+ }
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java
new file mode 100644
index 0000000000..3325eaa4ac
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 审批流程信息
+ * @author element
+ */
+@Data
+public class WxCpApprovalRecord implements Serializable {
+
+ private static final long serialVersionUID = -327230786004105887L;
+
+ @SerializedName("sp_status")
+ private WxCpRecordSpStatus status;
+
+ @SerializedName("approverattr")
+ private WxCpApproverAttr approverAttr;
+
+ private List details;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java
new file mode 100644
index 0000000000..4c966c9d6f
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 审批节点详情
+ * @author element
+ */
+@Data
+public class WxCpApprovalRecordDetail implements Serializable {
+
+ private static final long serialVersionUID = -9142079764088495301L;
+
+ /**
+ * 分支审批人
+ */
+ @SerializedName("approver")
+ private WxCpOperator approver;
+
+ /**
+ * 审批意见
+ */
+ @SerializedName("speech")
+ private String speech;
+
+ /**
+ * 分支审批人审批状态
+ */
+ @SerializedName("sp_status")
+ private WxCpRecordSpStatus spStatus;
+
+ /**
+ * 节点分支审批人审批操作时间戳,0表示未操作
+ */
+ @SerializedName("sptime")
+ private Long spTime;
+
+ /**
+ * 节点分支审批人审批意见附件
+ */
+ @SerializedName("media_id")
+ private List mediaIds;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java
new file mode 100644
index 0000000000..15e55f2f72
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * 审批方式
+ *
+ * @author element
+ */
+public enum WxCpApproverAttr {
+ /**
+ * 或签
+ */
+ @SerializedName("1")
+ ONE_SIGN(1),
+ /**
+ * 会签
+ */
+ @SerializedName("2")
+ ALL_SIGN(2);
+
+ private Integer attr;
+
+ private WxCpApproverAttr(Integer attr) {
+ this.attr = attr;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java
similarity index 92%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java
index d2fbf0f9d7..b76553ca63 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.oa;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@@ -47,4 +47,8 @@ public class WxCpCheckinData implements Serializable {
@SerializedName("mediaids")
private List mediaIds;
+
+ private Integer lat;
+
+ private Integer lng;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinOption.java
similarity index 98%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinOption.java
index c554e3d706..70cd4b202a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinOption.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.oa;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpDialRecord.java
similarity index 97%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpDialRecord.java
index 4f93b3decc..f3cf7d9881 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpDialRecord.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.oa;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java
new file mode 100644
index 0000000000..063234dac2
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * 企业微信操作人
+ *
+ * @author element
+ */
+@Data
+public class WxCpOperator implements Serializable {
+
+ private static final long serialVersionUID = 5797144853574346736L;
+
+ /**
+ * 企业微信userid
+ */
+ @SerializedName("userid")
+ private String userId;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java
new file mode 100644
index 0000000000..206a0aa04e
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * 审批记录(节点)分支审批状态
+ *
+ * 1-审批中;2-已同意;3-已驳回;4-已转审
+ *
+ * @author element
+ */
+public enum WxCpRecordSpStatus {
+
+ /**
+ * 审批中
+ */
+ @SerializedName("1")
+ AUDITING(1),
+ /**
+ * 已同意
+ */
+ @SerializedName("2")
+ PASSED(2),
+ /**
+ * 已驳回
+ */
+ @SerializedName("3")
+ REJECTED(3),
+ /**
+ * 已转审
+ */
+ @SerializedName("4")
+ TURNED(4);
+
+ private Integer status;
+
+ private WxCpRecordSpStatus(Integer status) {
+ this.status = status;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java
new file mode 100644
index 0000000000..c3d8005f50
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java
@@ -0,0 +1,54 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * 审批单状态
+ * (1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
+ *
+ * @author element
+ */
+public enum WxCpSpStatus {
+
+ /**
+ * 审批中
+ */
+ @SerializedName("1")
+ AUDITING(1),
+ /**
+ * 已通过
+ */
+ @SerializedName("2")
+ PASSED(2),
+ /**
+ * 已驳回
+ */
+ @SerializedName("3")
+ REJECTED(3),
+ /**
+ * 已撤销
+ */
+ @SerializedName("4")
+ UNDONE(4),
+ /**
+ * 通过后撤销
+ */
+ @SerializedName("6")
+ PASS_UNDONE(6),
+ /**
+ * 已删除
+ */
+ @SerializedName("7")
+ DELETED(7),
+ /**
+ * 已支付
+ */
+ @SerializedName("10")
+ ALREADY_PAY(10);
+
+ private Integer status;
+
+ private WxCpSpStatus(Integer status) {
+ this.status = status;
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java
new file mode 100644
index 0000000000..df25aabf37
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.cp.bean.oa;
+
+import com.google.gson.JsonObject;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateContent;
+import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateControls;
+import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateTitle;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 审批模板详情
+ *
+ * @author gyv12345@163.com
+ */
+@Data
+public class WxCpTemplateResult implements Serializable {
+ private static final long serialVersionUID = 6690547131189343887L;
+
+ @SerializedName("errcode")
+ private Integer errCode;
+
+ @SerializedName("errmsg")
+ private String errMsg;
+
+ @SerializedName("template_names")
+ private List templateNames;
+
+ @SerializedName("template_content")
+ private TemplateContent templateContent;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java
new file mode 100644
index 0000000000..c4eb4ada0f
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.cp.bean.oa.applydata;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author element
+ */
+@Data
+public class Content implements Serializable {
+ private static final long serialVersionUID = 8456821731930526935L;
+
+ private String control;
+
+ private String id;
+
+ @SerializedName("title")
+ private List titles;
+
+ private ContentValue value;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java
new file mode 100644
index 0000000000..24d5fafc2d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java
@@ -0,0 +1,18 @@
+package me.chanjar.weixin.cp.bean.oa.applydata;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author element
+ */
+@Data
+public class ContentTitle implements Serializable {
+
+ private static final long serialVersionUID = -4501999157383517007L;
+
+ private String text;
+ private String lang;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java
new file mode 100644
index 0000000000..7798338aa1
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java
@@ -0,0 +1,103 @@
+package me.chanjar.weixin.cp.bean.oa.applydata;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author element
+ */
+@Data
+public class ContentValue implements Serializable {
+
+ private static final long serialVersionUID = -5607678965965065261L;
+
+ private String text;
+
+ @SerializedName("new_number")
+ private Integer newNumber;
+
+ @SerializedName("new_money")
+ private Integer newMoney;
+
+ private ContentValue.Date date;
+
+ private ContentValue.Selector selector;
+
+ private List members;
+
+ private List departments;
+
+ private List files;
+
+ private List children;
+
+ @Data
+ public static class Date implements Serializable {
+
+ private static final long serialVersionUID = -6181554080062231138L;
+ private String type;
+
+ @SerializedName("s_timestamp")
+ private Long timestamp;
+ }
+
+ @Data
+ public static class Selector implements Serializable {
+
+ private static final long serialVersionUID = 7305458759126951773L;
+ private String type;
+ private List
+ *
+ * @param templateMessage 模版消息
+ * @throws WxErrorException .
*/
+ @Deprecated
void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException;
-
/**
*
+ * 发送订阅消息
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
*
- * 发送订阅消息
+ *
+ * @param subscribeMessage 订阅消息
+ * @throws WxErrorException .
*/
void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException;
-
/**
*
* 下发小程序和公众号统一的服务消息
* 详情请见: 下发小程序和公众号统一的服务消息
* 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
*
+ *
+ * @param uniformMessage 消息
+ * @throws WxErrorException .
*/
void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException;
+
+ /**
+ *
+ * 创建被分享动态消息的 activity_id.
+ * 动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html
+ *
+ * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.createActivityId.html
+ * 接口地址:GET https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN
+ *
+ *
+ * @return .
+ * @throws WxErrorException .
+ */
+ JsonObject createUpdatableMessageActivityId() throws WxErrorException;
+
+ /**
+ *
+ * 修改被分享的动态消息.
+ * 动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html
+ *
+ * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.setUpdatableMsg.html
+ * 接口地址:POST https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN
+ *
+ *
+ * @param msg 动态消息
+ * @throws WxErrorException .
+ */
+ void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException;
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
index 4c821e0714..7733b77ed8 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
@@ -32,6 +32,14 @@ public interface WxMaSecCheckService {
*/
boolean checkImage(File file) throws WxErrorException;
+ /**
+ * 校验一张图片是否含有违法违规内容
+ * @param fileUrl 文件网络地址
+ * @return 是否违规
+ * @throws WxErrorException .
+ */
+ boolean checkImage(String fileUrl) throws WxErrorException;
+
/**
*
* 检查一段文本是否含有违法违规内容。
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
index 52988f36e2..80150968dc 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
@@ -86,6 +86,11 @@ public interface WxMaService {
*/
String post(String url, String postData) throws WxErrorException;
+ /**
+ * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求.
+ */
+ String post(String url, Object obj) throws WxErrorException;
+
/**
*
* Service没有实现某个API的时候,可以用这个,
@@ -158,6 +163,13 @@ public interface WxMaService {
*/
WxMaTemplateService getTemplateService();
+ /**
+ * 返回订阅消息配置相关接口方法的实现类对象, 以方便调用其各个接口.
+ *
+ * @return WxMaSubscribeService
+ */
+ WxMaSubscribeService getSubscribeService();
+
/**
* 数据分析相关查询服务.
*
@@ -224,5 +236,15 @@ public interface WxMaService {
*/
RequestHttp getRequestHttp();
+ /**
+ * 获取物流助手接口服务对象
+ *
+ * @return
+ */
+ WxMaExpressService getExpressService();
+ /**
+ * 获取云开发接口服务对象
+ */
+ WxMaCloudService getCloudService();
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
new file mode 100644
index 0000000000..19e22a5eb6
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
@@ -0,0 +1,153 @@
+package cn.binarywang.wx.miniapp.api;
+
+import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult;
+import lombok.Data;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+import java.util.List;
+
+/**
+ * 订阅消息类
+ *
+ * @author Binary Wang
+ * @date 2019-12-15
+ */
+public interface WxMaSubscribeService {
+ /**
+ * 获取模板标题下的关键词列表.
+ */
+ String GET_PUB_TEMPLATE_TITLE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles";
+
+ /**
+ * 获取模板标题下的关键词列表.
+ */
+ String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords";
+
+ /**
+ * 组合模板并添加至帐号下的个人模板库.
+ */
+ String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate";
+
+ /**
+ * 获取当前帐号下的个人模板列表.
+ */
+ String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate";
+
+ /**
+ * 删除帐号下的某个模板.
+ */
+ String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate";
+
+ /**
+ * 获取小程序账号的类目
+ */
+ String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory";
+
+ /**
+ *
+ * 获取帐号所属类目下的公共模板标题
+ *
+ * 详情请见: 获取帐号所属类目下的公共模板标题
+ * 接口url格式: https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=ACCESS_TOKEN
+ *
+ *
+ * @param ids 类目 id,多个用逗号隔开
+ * @param limit 用于分页,表示拉取 limit 条记录。最大为 30。
+ * @param start 用于分页,表示从 start 开始。从 0 开始计数。
+ * @return .
+ * @throws WxErrorException .
+ */
+ WxMaPubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException;
+
+ /**
+ *
+ * 获取模板库某个模板标题下关键词库
+ *
+ * 详情请见: 获取模板标题下的关键词列表
+ * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=ACCESS_TOKEN
+ *
+ *
+ * @param id 模板标题 id,可通过接口获取
+ * @return .
+ * @throws WxErrorException .
+ */
+ List getPubTemplateKeyWordsById(String id) throws WxErrorException;
+
+ /**
+ *
+ * 组合模板并添加至帐号下的个人模板库
+ *
+ * 详情请见: 获取小程序模板库标题列表
+ * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=ACCESS_TOKEN
+ *
+ *
+ * @param id 模板标题 id,可通过接口获取,也可登录小程序后台查看获取
+ * @param keywordIdList 模板关键词列表
+ * @param sceneDesc 服务场景描述,15个字以内
+ * @return 添加至帐号下的模板id,发送小程序订阅消息时所需
+ * @throws WxErrorException .
+ */
+ String addTemplate(String id, List keywordIdList, String sceneDesc) throws WxErrorException;
+
+ /**
+ *
+ * 获取当前帐号下的个人模板列表
+ *
+ * 详情请见: 获取当前帐号下的个人模板列表
+ * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=ACCESS_TOKEN
+ *
+ *
+ * @return .
+ * @throws WxErrorException .
+ */
+ List getTemplateList() throws WxErrorException;
+
+ /**
+ *
+ * 删除帐号下的某个模板
+ *
+ * 详情请见: 删除帐号下的个人模板
+ * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=ACCESS_TOKEN
+ *
+ *
+ * @param templateId 要删除的模板id
+ * @return 删除是否成功
+ * @throws WxErrorException .
+ */
+ boolean delTemplate(String templateId) throws WxErrorException;
+
+ /**
+ *
+ * 获取小程序账号的类目
+ * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getCategory.html
+ * GET https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=ACCESS_TOKEN
+ *
+ *
+ * @return .
+ * @throws WxErrorException .
+ */
+ List getCategory() throws WxErrorException;
+
+ @Data
+ class CategoryData {
+ int id;
+ String name;
+ }
+
+ @Data
+ class TemplateInfo {
+ private String priTmplId;
+ private String title;
+ private String content;
+ private String example;
+ private int type;
+ }
+
+ @Data
+ class PubTemplateKeyword {
+ private int kid;
+ private String name;
+ private String example;
+ private String rule;
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java
index 3973774f00..cbdd3c7585 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java
@@ -8,6 +8,10 @@
import java.util.List;
+/**
+ * @author IOMan(lewis.lynn1006@gmail.com)
+ */
+@Deprecated
public interface WxMaTemplateService {
/**
* 获取小程序模板库标题列表.
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java
new file mode 100644
index 0000000000..984185649c
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java
@@ -0,0 +1,178 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import cn.binarywang.wx.miniapp.api.WxMaCloudService;
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.cloud.*;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 云开发相关接口实现类.
+ *
+ * @author Binary Wang
+ * @date 2020-01-22
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class WxMaCloudServiceImpl implements WxMaCloudService {
+ private static final JsonParser JSON_PARSER = new JsonParser();
+ private final WxMaService wxMaService;
+
+ @Override
+ public String invokeCloudFunction(String env, String name, String body) throws WxErrorException {
+ final String response = this.wxMaService.post(String.format(INVOKE_CLOUD_FUNCTION_URL, env, name), body);
+ return JSON_PARSER.parse(response).getAsJsonObject().get("resp_data").getAsString();
+ }
+
+ @Override
+ public JsonArray databaseAdd(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_ADD_URL, ImmutableMap.of("env", env, "query", query));
+ return JSON_PARSER.parse(response).getAsJsonObject().get("id_list").getAsJsonArray();
+ }
+
+ @Override
+ public int databaseDelete(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_DELETE_URL, ImmutableMap.of("env", env, "query", query));
+ return JSON_PARSER.parse(response).getAsJsonObject().get("deleted").getAsInt();
+ }
+
+ @Override
+ public WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_UPDATE_URL, ImmutableMap.of("env", env, "query", query));
+ return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseUpdateResult.class);
+ }
+
+ @Override
+ public WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_QUERY_URL, ImmutableMap.of("env", env, "query", query));
+ return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseQueryResult.class);
+ }
+
+ @Override
+ public JsonArray databaseAggregate(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_AGGREGATE_URL, ImmutableMap.of("env", env, "query", query));
+ return JSON_PARSER.parse(response).getAsJsonObject().get("data").getAsJsonArray();
+ }
+
+ @Override
+ public Long databaseCount(String env, String query) throws WxErrorException {
+ String response = this.wxMaService.post(DATABASE_COUNT_URL, ImmutableMap.of("env", env, "query", query));
+ return JSON_PARSER.parse(response).getAsJsonObject().get("count").getAsLong();
+ }
+
+ @Override
+ public void updateIndex(String env, String collectionName, List createIndexes,
+ List dropIndexNames) throws WxErrorException {
+ List