* 获取企业号应用信息
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java
index 95f747e3..741ee906 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java
@@ -1,20 +1,20 @@
package me.chanjar.weixin.cp.api;
-import java.util.List;
-
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
import me.chanjar.weixin.cp.bean.WxCpChat;
+import java.util.List;
+
/**
* 群聊服务.
*
* @author gaigeshen
*/
public interface WxCpChatService {
- String APPCHAT_CREATE = "https://qyapi.weixin.qq.com/cgi-bin/appchat/create";
- String APPCHAT_UPDATE = "https://qyapi.weixin.qq.com/cgi-bin/appchat/update";
- String APPCHAT_GET_CHATID = "https://qyapi.weixin.qq.com/cgi-bin/appchat/get?chatid=";
+
+ @Deprecated
+ String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException;
/**
* 创建群聊会话,注意:刚创建的群,如果没有下发消息,在企业微信不会出现该群.
@@ -24,15 +24,13 @@ public interface WxCpChatService {
* @param users 群成员id列表。至少2人,至多500人
* @param chatId 群聊的唯一标志,不能与已有的群重复;字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z。如果不填,系统会随机生成群id
* @return 创建的群聊会话chatId
- * @throws WxErrorException 发生异常
- */
- String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException;
-
- /**
- * chatCreate 同名方法
+ * @throws WxErrorException 异常
*/
String create(String name, String owner, List users, String chatId) throws WxErrorException;
+ @Deprecated
+ void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException;
+
/**
* 修改群聊会话.
*
@@ -41,26 +39,19 @@ public interface WxCpChatService {
* @param owner 新群主的id。若不需更新,请忽略此参数(null or empty)
* @param usersToAdd 添加成员的id列表,若不需要更新,则传递空对象或者空集合
* @param usersToDelete 踢出成员的id列表,若不需要更新,则传递空对象或者空集合
- * @throws WxErrorException 发生异常
- */
- void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException;
-
- /**
- * chatUpdate 同名方法
+ * @throws WxErrorException 异常
*/
void update(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException;
+ @Deprecated
+ WxCpChat chatGet(String chatId) throws WxErrorException;
+
/**
* 获取群聊会话.
*
* @param chatId 群聊编号
* @return 群聊会话
- * @throws WxErrorException 发生异常
- */
- WxCpChat chatGet(String chatId) throws WxErrorException;
-
- /**
- * chatGet 同名方法
+ * @throws WxErrorException 异常
*/
WxCpChat get(String chatId) throws WxErrorException;
@@ -71,6 +62,7 @@ public interface WxCpChatService {
* 文档地址:https://work.weixin.qq.com/api/doc#90000/90135/90248
*
* @param message 要发送的消息内容对象
+ * @throws WxErrorException 异常
*/
void sendMsg(WxCpAppChatMessage message) throws WxErrorException;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
index 82e571ac..c86816b7 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
@@ -1,10 +1,10 @@
package me.chanjar.weixin.cp.api;
-import java.util.List;
-
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpDepart;
+import java.util.List;
+
/**
*
* 部门管理接口
@@ -19,7 +19,7 @@ public interface WxCpDepartmentService {
*
* 部门管理接口 - 创建部门.
* 最多支持创建500个部门
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口
+ * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/90205
*
*
* @param depart 部门
@@ -30,19 +30,20 @@ public interface WxCpDepartmentService {
/**
*
- * 部门管理接口 - 查询部门.
- * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E5.88.97.E8.A1.A8
+ * 部门管理接口 - 获取部门列表.
+ * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/90208
*
*
* @param id 部门id。获取指定部门及其下的子部门。非必需,可为null
+ * @return 获取的部门列表
* @throws WxErrorException 异常
*/
List list(Long id) throws WxErrorException;
/**
*
- * 部门管理接口 - 修改部门名.
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口
+ * 部门管理接口 - 更新部门.
+ * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/90206
* 如果id为0(未部门),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
*
*
@@ -54,6 +55,8 @@ public interface WxCpDepartmentService {
/**
*
* 部门管理接口 - 删除部门.
+ * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/90207
+ * 应用须拥有指定部门的管理权限
*
*
* @param departId 部门id
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java
new file mode 100644
index 00000000..92f22586
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java
@@ -0,0 +1,58 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 外部联系人管理接口,企业微信的外部联系人的接口和通讯录接口已经拆离
+ * Created by Joe Cao on 2019/6/14
+ *
+ *
+ * @author JoeCao
+ */
+public interface WxCpExternalContactService {
+ /**
+ * 获取外部联系人详情.
+ *
+ * 企业可通过此接口,根据外部联系人的userid,拉取外部联系人详情。权限说明:
+ * 企业需要使用外部联系人管理secret所获取的accesstoken来调用
+ * 第三方应用需拥有“企业客户”权限。
+ * 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+ *
+ *
+ * @param userId 外部联系人的userid
+ */
+ WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException;
+
+ /**
+ * 获取外部联系人列表.
+ *
+ * 企业可通过此接口获取指定成员添加的客户列表。
+ * 客户是指配置了客户联系功能的成员所添加的外部联系人。
+ * 没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。
+ * 第三方应用需拥有“企业客户”权限。
+ * 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+ *
+ *
+ * @param userId 外部联系人的userid
+ * @return List of External wx id
+ */
+ List listExternalContacts(String userId) throws WxErrorException;
+
+
+ /**
+ * 企业和第三方服务商可通过此接口获取配置了客户联系功能的成员(Customer Contact)列表。
+ *
+ * 企业需要使用外部联系人管理secret所获取的accesstoken来调用(accesstoken如何获取?);
+ * 第三方应用需拥有“企业客户”权限。
+ * 第三方应用只能获取到可见范围内的配置了客户联系功能的成员
+ *
+ *
+ * @return List of CpUser id
+ */
+ List listFollowUser() throws WxErrorException;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
index 31ce6b59..a51e04e1 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
@@ -1,12 +1,12 @@
package me.chanjar.weixin.cp.api;
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
-import me.chanjar.weixin.common.error.WxErrorException;
-
/**
*
* 媒体管理接口.
@@ -16,10 +16,6 @@ import me.chanjar.weixin.common.error.WxErrorException;
* @author Binary Wang
*/
public interface WxCpMediaService {
- String MEDIA_GET_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/get";
- String MEDIA_UPLOAD_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=";
- String IMG_UPLOAD_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg";
- String JSSDK_MEDIA_GET_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/get/jssdk";
/**
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java
index 068c037a..309b9812 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java
@@ -12,6 +12,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
* @author Binary Wang
*/
public interface WxCpMenuService {
+
/**
*
* 自定义菜单创建接口
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java
deleted file mode 100644
index e8cf874e..00000000
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package me.chanjar.weixin.cp.api;
-
-import me.chanjar.weixin.common.error.WxErrorException;
-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 java.util.Date;
-import java.util.List;
-
-/**
- * @author Element
- * @Package me.chanjar.weixin.cp.api
- * @date 2019-04-06 10:52
- * @Description:
- * 企业微信OA相关接口
- *
- *
- */
-public interface WxCpOAService {
-
- /**
- *
- * 获取打卡数据
- * API doc : https://work.weixin.qq.com/api/doc#90000/90135/90262
- *
- *
- * @param openCheckinDataType 打卡类型。1:上下班打卡;2:外出打卡;3:全部打卡
- * @param starttime 获取打卡记录的开始时间
- * @param endtime 获取打卡记录的结束时间
- * @param userIdList 需要获取打卡记录的用户列表
- */
- List getCheckinData(Integer openCheckinDataType, Date starttime, Date endtime, List userIdList) throws WxErrorException;
-
- /**
- *
- * 获取打卡规则
- * API doc : https://work.weixin.qq.com/api/doc#90000/90135/90263
- *
- *
- * @param datetime 需要获取规则的当天日期
- * @param userIdList 需要获取打卡规则的用户列表
- * @return
- * @throws WxErrorException
- */
- List getCheckinOption(Date datetime, List userIdList) throws WxErrorException;
-
- /**
- *
- * 获取审批数据
- * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
- * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530
- *
- *
- * @param starttime 获取审批记录的开始时间
- * @param endtime 获取审批记录的结束时间
- * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取
- * @return
- * @throws WxErrorException
- */
- WxCpApprovalDataResult getApprovalData(Date starttime, Date endtime, Long nextSpnum) throws WxErrorException;
-
- List getDialRecord(Date starttime, Date endtime, Integer offset, Integer limit) throws WxErrorException;
-
-}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
index 5f3d6daa..7c42ea63 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
@@ -1,20 +1,22 @@
package me.chanjar.weixin.cp.api;
import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import me.chanjar.weixin.cp.bean.WxCpUserDetail;
/**
*
- * OAuth2相关管理接口
+ * OAuth2相关管理接口.
* Created by BinaryWang on 2017/6/24.
*
*
* @author Binary Wang
*/
public interface WxCpOAuth2Service {
+
/**
*
- * 构造oauth2授权的url连接
+ * 构造oauth2授权的url连接.
*
*
* @param state 状态码
@@ -24,7 +26,7 @@ public interface WxCpOAuth2Service {
/**
*
- * 构造oauth2授权的url连接
+ * 构造oauth2授权的url连接.
* 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code
*
*
@@ -57,16 +59,18 @@ public interface WxCpOAuth2Service {
*
*
* @param code 微信oauth授权返回的代码
- * @return [userid, deviceid]
+ * @return WxCpOauth2UserInfo
+ * @throws WxErrorException 异常
* @see #getUserInfo(Integer, String)
*/
- String[] getUserInfo(String code) throws WxErrorException;
+ WxCpOauth2UserInfo getUserInfo(String code) throws WxErrorException;
/**
*
* 根据code获取成员信息
* http://qydev.weixin.qq.com/wiki/index.php?title=根据code获取成员信息
* https://work.weixin.qq.com/api/doc#10028/根据code获取成员信息
+ * https://work.weixin.qq.com/api/doc#90000/90135/91023 获取访问用户身份
* 因为企业号oauth2.0必须在应用设置里设置通过ICP备案的可信域名,所以无法测试,因此这个方法很可能是坏的。
*
* 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出
@@ -74,10 +78,11 @@ public interface WxCpOAuth2Service {
*
* @param agentId 企业号应用的id
* @param code 通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
- * @return [UserId, DeviceId, OpenId, user_ticket, expires_in]
+ * @return WxCpOauth2UserInfo
+ * @throws WxErrorException 异常
* @see #getUserInfo(String)
*/
- String[] getUserInfo(Integer agentId, String code) throws WxErrorException;
+ WxCpOauth2UserInfo getUserInfo(Integer agentId, String code) throws WxErrorException;
/**
*
@@ -92,6 +97,8 @@ public interface WxCpOAuth2Service {
*
*
* @param userTicket 成员票据
+ * @return WxCpUserDetail
+ * @throws WxErrorException 异常
*/
WxCpUserDetail getUserDetail(String userTicket) throws WxErrorException;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaService.java
new file mode 100644
index 00000000..c6f90d3e
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaService.java
@@ -0,0 +1,64 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+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 java.util.Date;
+import java.util.List;
+
+/**
+ * 企业微信OA相关接口.
+ *
+ * @author Element
+ * @date 2019-04-06 10:52
+ */
+public interface WxCpOaService {
+
+ /**
+ *
+ * 获取打卡数据
+ * API doc : https://work.weixin.qq.com/api/doc#90000/90135/90262
+ *
+ *
+ * @param openCheckinDataType 打卡类型。1:上下班打卡;2:外出打卡;3:全部打卡
+ * @param startTime 获取打卡记录的开始时间
+ * @param endTime 获取打卡记录的结束时间
+ * @param userIdList 需要获取打卡记录的用户列表
+ * @return 打卡数据列表
+ * @throws WxErrorException 异常
+ */
+ List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, List userIdList) throws WxErrorException;
+
+ /**
+ *
+ * 获取打卡规则
+ * API doc : https://work.weixin.qq.com/api/doc#90000/90135/90263
+ *
+ *
+ * @param datetime 需要获取规则的当天日期
+ * @param userIdList 需要获取打卡规则的用户列表
+ * @return 打卡规则列表
+ * @throws WxErrorException 异常
+ */
+ List getCheckinOption(Date datetime, List userIdList) throws WxErrorException;
+
+ /**
+ *
+ * 获取审批数据
+ * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
+ * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530
+ *
+ *
+ * @param startTime 获取审批记录的开始时间
+ * @param endTime 获取审批记录的结束时间
+ * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取
+ * @throws WxErrorException 异常
+ */
+ WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException;
+
+ List getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) 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 364723db..e25fd63c 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
@@ -13,19 +13,10 @@ import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
/**
- * 微信API的Service
+ * 微信API的Service.
* @author chanjaster
*/
public interface WxCpService {
- String GET_JSAPI_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
- String GET_AGENT_CONFIG_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?&type=agent_config";
- String MESSAGE_SEND = "https://qyapi.weixin.qq.com/cgi-bin/message/send";
- String GET_CALLBACK_IP = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip";
- String BATCH_REPLACE_PARTY = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty";
- String BATCH_REPLACE_USER = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser";
- String BATCH_GET_RESULT = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid=";
- String JSCODE_TO_SESSION_URL = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session";
-
/**
*
* 验证推送过来的消息的正确性
@@ -293,7 +284,9 @@ public interface WxCpService {
* 获取用户相关接口的服务类对象
*/
WxCpUserService getUserService();
-
+
+ WxCpExternalContactService getExternalContactService();
+
/**
* 获取群聊服务
*
@@ -310,7 +303,7 @@ public interface WxCpService {
WxCpAgentService getAgentService();
- WxCpOAService getOAService();
+ WxCpOaService getOAService();
/**
* http请求对象
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
index 9624f9e4..78f1d791 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
@@ -17,6 +17,7 @@ import java.util.List;
* @author Binary Wang
*/
public interface WxCpTagService {
+
/**
* 创建标签.
*
@@ -51,6 +52,14 @@ public interface WxCpTagService {
*/
List listUsersByTagId(String tagId) throws WxErrorException;
+ /**
+ * 获取标签成员.
+ * 对应: http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 中的get接口
+ *
+ * @param tagId 标签id
+ */
+ WxCpTagGetResult get(String tagId) throws WxErrorException;
+
/**
* 增加标签成员.
*
@@ -69,13 +78,4 @@ public interface WxCpTagService {
*/
WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds, List partyIds) throws WxErrorException;
-
- /**
- * 获取标签成员.
- * 对应: http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 中的get接口
- *
- * @param tagId 标签id
- */
- WxCpTagGetResult get(String tagId) throws WxErrorException;
-
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java
index 038c2dd3..5bf50d36 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java
@@ -14,6 +14,7 @@ import java.util.List;
* @date 2019-05-16
*/
public interface WxCpTaskCardService {
+
/**
*
* 更新任务卡片消息状态
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java
new file mode 100644
index 00000000..40ffcf55
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java
@@ -0,0 +1,169 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
+import me.chanjar.weixin.cp.bean.WxCpTpCorp;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+
+/**
+ * 微信第三方应用API的Service.
+ *
+ * @author zhenjun cai
+ */
+public interface WxCpTpService {
+
+ /**
+ *
+ * 验证推送过来的消息的正确性
+ * 详情请见: https://work.weixin.qq.com/api/doc#90000/90139/90968/消息体签名校验
+ *
+ *
+ * @param msgSignature 消息签名
+ * @param timestamp 时间戳
+ * @param nonce 随机数
+ * @param data 微信传输过来的数据,有可能是echoStr,有可能是xml消息
+ */
+ boolean checkSignature(String msgSignature, String timestamp, String nonce, String data);
+
+ /**
+ * 获取suite_access_token, 不强制刷新suite_access_token
+ *
+ * @see #getSuiteAccessToken(boolean)
+ */
+ String getSuiteAccessToken() throws WxErrorException;
+
+ /**
+ *
+ * 获取suite_access_token,本方法线程安全
+ * 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限
+ * 另:本service的所有方法都会在suite_access_token过期是调用此方法
+ * 程序员在非必要情况下尽量不要主动调用此方法
+ * 详情请见: https://work.weixin.qq.com/api/doc#90001/90143/90600
+ *
+ *
+ * @param forceRefresh 强制刷新
+ */
+ String getSuiteAccessToken(boolean forceRefresh) throws WxErrorException;
+
+ /**
+ * 获得suite_ticket,不强制刷新suite_ticket
+ *
+ * @see #getSuiteTicket(boolean)
+ */
+ String getSuiteTicket() throws WxErrorException;
+
+ /**
+ *
+ * 获得suite_ticket
+ * 由于suite_ticket是微信服务器定时推送(每10分钟),不能主动获取,如果碰到过期只能抛异常
+ *
+ * 详情请见:https://work.weixin.qq.com/api/doc#90001/90143/90628
+ *
+ *
+ * @param forceRefresh 强制刷新
+ */
+ String getSuiteTicket(boolean forceRefresh) throws WxErrorException;
+
+ /**
+ * 小程序登录凭证校验
+ *
+ * @param jsCode 登录时获取的 code
+ */
+ WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException;
+
+ /**
+ * 获取企业凭证
+ *
+ * @param authCorpid 授权方corpid
+ * @param permanentCode 永久授权码,通过get_permanent_code获取
+ */
+ WxAccessToken getCorpToken(String authCorpid, String permanentCode) throws WxErrorException;
+
+ /**
+ * 获取企业永久授权码
+ *
+ * @param authCode
+ * @return
+ */
+ WxCpTpCorp getPermanentCode(String authCode) throws WxErrorException;
+
+ /**
+ * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求
+ *
+ * @param url 接口地址
+ * @param queryParam 请求参数
+ */
+ String get(String url, String queryParam) throws WxErrorException;
+
+ /**
+ * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求
+ *
+ * @param url 接口地址
+ * @param postData 请求body字符串
+ */
+ String post(String url, String postData) throws WxErrorException;
+
+ /**
+ *
+ * Service没有实现某个API的时候,可以用这个,
+ * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+ * 可以参考,{@link MediaUploadRequestExecutor}的实现方法
+ *
+ *
+ * @param executor 执行器
+ * @param uri 请求地址
+ * @param data 参数
+ * @param 请求值类型
+ * @param 返回值类型
+ */
+ T execute(RequestExecutor executor, String uri, E data) throws WxErrorException;
+
+ /**
+ *
+ * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试
+ * 默认:1000ms
+ *
+ *
+ * @param retrySleepMillis 重试休息时间
+ */
+ void setRetrySleepMillis(int retrySleepMillis);
+
+ /**
+ *
+ * 设置当微信系统响应系统繁忙时,最大重试次数
+ * 默认:5次
+ *
+ *
+ * @param maxRetryTimes 最大重试次数
+ */
+ void setMaxRetryTimes(int maxRetryTimes);
+
+ /**
+ * 初始化http请求对象
+ */
+ void initHttp();
+
+ /**
+ * 获取WxMpConfigStorage 对象
+ *
+ * @return WxMpConfigStorage
+ */
+ WxCpTpConfigStorage getWxCpTpConfigStorage();
+
+ /**
+ * 注入 {@link WxCpTpConfigStorage} 的实现
+ *
+ * @param wxConfigProvider 配置对象
+ */
+ void setWxCpTpConfigStorage(WxCpTpConfigStorage wxConfigProvider);
+
+ /**
+ * http请求对象
+ */
+ RequestHttp, ?> getRequestHttp();
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java
index 310a1efa..8cc77a2d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java
@@ -1,13 +1,13 @@
package me.chanjar.weixin.cp.api;
-import java.util.List;
-import java.util.Map;
-
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpInviteResult;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
+import java.util.List;
+import java.util.Map;
+
/**
*
* 用户管理接口
@@ -17,6 +17,7 @@ import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
* @author Binary Wang
*/
public interface WxCpUserService {
+
/**
*
* 用在二次验证的时候.
@@ -136,6 +137,23 @@ public interface WxCpUserService {
*/
String openid2UserId(String openid) throws WxErrorException;
+ /**
+ *
+ *
+ * 通过手机号获取其所对应的userid。
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=ACCESS_TOKEN
+ *
+ * 文档地址:https://work.weixin.qq.com/api/doc#90001/90143/91693
+ *
+ *
+ * @param mobile 手机号码。长度为5~32个字节
+ * @return userid mobile对应的成员userid
+ * @throws WxErrorException .
+ */
+ String getUserId(String mobile) throws WxErrorException;
+
/**
* 获取外部联系人详情.
*
@@ -146,6 +164,10 @@ public interface WxCpUserService {
*
*
* @param userId 外部联系人的userid
+ * @return 联系人详情
+ * @throws WxErrorException .
*/
WxCpUserExternalContactInfo getExternalContact(String userId) 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 3eb99b79..c7f10f6b 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
@@ -5,6 +5,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -23,6 +24,7 @@ import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
import me.chanjar.weixin.cp.bean.WxCpMessage;
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,22 +33,24 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.*;
+
/**
* @author chanjarster
*/
+@Slf4j
public abstract class BaseWxCpServiceImpl implements WxCpService, RequestHttp {
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
-
- private WxCpUserService userService = new WxCpUserServiceImpl(this);
- private WxCpChatService chatService = new WxCpChatServiceImpl(this);
+ private WxCpUserService userService = new WxCpUserServiceImpl(this);
+ private WxCpChatService chatService = new WxCpChatServiceImpl(this);
private WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(this);
- private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this);
- private WxCpMenuService menuService = new WxCpMenuServiceImpl(this);
- private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this);
- private WxCpTagService tagService = new WxCpTagServiceImpl(this);
- private WxCpAgentService agentService = new WxCpAgentServiceImpl(this);
- private WxCpOAService oaService = new WxCpOAServiceImpl(this);
- private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this);
+ private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this);
+ private WxCpMenuService menuService = new WxCpMenuServiceImpl(this);
+ private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this);
+ private WxCpTagService tagService = new WxCpTagServiceImpl(this);
+ private WxCpAgentService agentService = new WxCpAgentServiceImpl(this);
+ private WxCpOaService oaService = new WxCpOaServiceImpl(this);
+ private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this);
+ private WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this);
/**
* 全局的是否正在刷新access token的锁
@@ -80,7 +84,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data)
.equals(msgSignature);
} catch (Exception e) {
- this.log.error("Checking signature failed, and the reason is :" + e.getMessage());
+ log.error("Checking signature failed, and the reason is :" + e.getMessage());
return false;
}
}
@@ -104,7 +108,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
if (this.configStorage.isAgentJsapiTicketExpired()) {
synchronized (this.globalAgentJsapiTicketRefreshLock) {
if (this.configStorage.isAgentJsapiTicketExpired()) {
- String responseContent = this.get(WxCpService.GET_AGENT_CONFIG_TICKET, null);
+ String responseContent = this.get(this.configStorage.getApiUrl(GET_AGENT_CONFIG_TICKET), null);
JsonObject jsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
this.configStorage.updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(),
jsonObject.get("expires_in").getAsInt());
@@ -129,7 +133,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
if (this.configStorage.isJsapiTicketExpired()) {
synchronized (this.globalJsapiTicketRefreshLock) {
if (this.configStorage.isJsapiTicketExpired()) {
- String responseContent = this.get(WxCpService.GET_JSAPI_TICKET, null);
+ String responseContent = this.get(this.configStorage.getApiUrl(GET_JSAPI_TICKET), null);
JsonObject tmpJsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
this.configStorage.updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(),
tmpJsonObject.get("expires_in").getAsInt());
@@ -170,7 +174,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
message.setAgentId(this.getWxCpConfigStorage().getAgentId());
}
- return WxCpMessageSendResult.fromJson(this.post(WxCpService.MESSAGE_SEND, message.toJson()));
+ return WxCpMessageSendResult.fromJson(this.post(this.configStorage.getApiUrl(MESSAGE_SEND), message.toJson()));
}
@Override
@@ -179,13 +183,13 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
params.put("js_code", jsCode);
params.put("grant_type", "authorization_code");
- String result = this.get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
+ String result = this.get(this.configStorage.getApiUrl(JSCODE_TO_SESSION), Joiner.on("&").withKeyValueSeparator("=").join(params));
return WxCpMaJsCode2SessionResult.fromJson(result);
}
@Override
public String[] getCallbackIp() throws WxErrorException {
- String responseContent = get(WxCpService.GET_CALLBACK_IP, null);
+ String responseContent = get(this.configStorage.getApiUrl(GET_CALLBACK_IP), null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray();
String[] ips = new String[jsonArray.size()];
@@ -216,7 +220,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
return this.executeInternal(executor, uri, data);
} catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) {
- this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
//最后一次重试失败后,直接抛出异常,不再等待
throw new RuntimeException("微信服务端异常,超出重试次数");
}
@@ -228,7 +232,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
if (error.getErrorCode() == -1) {
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
- this.log.debug("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
+ log.debug("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
@@ -239,7 +243,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
}
} while (retryTimes++ < this.maxRetryTimes);
- this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
throw new RuntimeException("微信服务端异常,超出重试次数");
}
@@ -255,7 +259,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
try {
T result = executor.execute(uriWithAccessToken, data);
- this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
+ log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
@@ -272,12 +276,12 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
}
if (error.getErrorCode() != 0) {
- this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
throw new WxErrorException(error, e);
}
return null;
} catch (IOException e) {
- this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new RuntimeException(e);
}
}
@@ -329,19 +333,19 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
public String replaceParty(String mediaId) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("media_id", mediaId);
- return post(WxCpService.BATCH_REPLACE_PARTY, jsonObject.toString());
+ return post(this.configStorage.getApiUrl(BATCH_REPLACE_PARTY), jsonObject.toString());
}
@Override
public String replaceUser(String mediaId) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("media_id", mediaId);
- return post(WxCpService.BATCH_REPLACE_USER, jsonObject.toString());
+ return post(this.configStorage.getApiUrl(BATCH_REPLACE_USER), jsonObject.toString());
}
@Override
public String getTaskResult(String joinId) throws WxErrorException {
- String url = WxCpService.BATCH_GET_RESULT + joinId;
+ String url = this.configStorage.getApiUrl(BATCH_GET_RESULT + joinId);
return get(url, null);
}
@@ -383,13 +387,18 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
return userService;
}
+ @Override
+ public WxCpExternalContactService getExternalContactService() {
+ return externalContactService;
+ }
+
@Override
public WxCpChatService getChatService() {
return chatService;
}
@Override
- public WxCpOAService getOAService() {
+ public WxCpOaService getOAService() {
return oaService;
}
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
new file mode 100644
index 00000000..92c6ac29
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java
@@ -0,0 +1,239 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.common.base.Joiner;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.WxType;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.DataUtils;
+import me.chanjar.weixin.common.util.crypto.SHA1;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
+import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
+import me.chanjar.weixin.cp.api.WxCpTpService;
+import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
+import me.chanjar.weixin.cp.bean.WxCpTpCorp;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zhenjun cai
+ */
+@Slf4j
+public abstract class BaseWxCpTpServiceImpl implements WxCpTpService, RequestHttp {
+
+ /**
+ * 全局的是否正在刷新access token的锁.
+ */
+ protected final Object globalSuiteAccessTokenRefreshLock = new Object();
+
+ /**
+ * 全局的是否正在刷新jsapi_ticket的锁.
+ */
+ protected final Object globalSuiteTicketRefreshLock = new Object();
+
+ protected WxCpTpConfigStorage configStorage;
+
+ /**
+ * 临时文件目录.
+ */
+ private File tmpDirFile;
+ private int retrySleepMillis = 1000;
+ private int maxRetryTimes = 5;
+
+ @Override
+ public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) {
+ try {
+ return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data)
+ .equals(msgSignature);
+ } catch (Exception e) {
+ log.error("Checking signature failed, and the reason is :" + e.getMessage());
+ return false;
+ }
+ }
+
+ @Override
+ public String getSuiteAccessToken() throws WxErrorException {
+ return getSuiteAccessToken(false);
+ }
+
+ @Override
+ public String getSuiteTicket() throws WxErrorException {
+ return getSuiteTicket(false);
+ }
+
+ @Override
+ public String getSuiteTicket(boolean forceRefresh) throws WxErrorException {
+// suite ticket由微信服务器推送,不能强制刷新
+// if (forceRefresh) {
+// this.configStorage.expireSuiteTicket();
+// }
+
+ if (this.configStorage.isSuiteTicketExpired()) {
+ // 本地suite ticket 不存在或者过期
+ WxError wxError = WxError.fromJson("{\"errcode\":40085, \"errmsg\":\"invaild suite ticket\"}", WxType.CP);
+ throw new WxErrorException(wxError);
+ }
+ return this.configStorage.getSuiteTicket();
+ }
+
+
+ @Override
+ public WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException {
+ Map params = new HashMap<>(2);
+ params.put("js_code", jsCode);
+ params.put("grant_type", "authorization_code");
+
+ String result = this.get(configStorage.getApiUrl(WxCpApiPathConsts.Tp.JSCODE_TO_SESSION), Joiner.on("&").withKeyValueSeparator("=").join(params));
+ return WxCpMaJsCode2SessionResult.fromJson(result);
+ }
+
+
+ @Override
+ public WxAccessToken getCorpToken(String authCorpid, String permanentCode) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("auth_corpid", authCorpid);
+ jsonObject.addProperty("permanent_code", permanentCode);
+ String result = post(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_CORP_TOKEN), jsonObject.toString());
+
+ return WxAccessToken.fromJson(result);
+ }
+
+
+ @Override
+ public WxCpTpCorp getPermanentCode(String authCode) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("auth_code", authCode);
+
+ String result = post(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_PERMANENT_CODE), jsonObject.toString());
+ jsonObject = new JsonParser().parse(result).getAsJsonObject();
+ WxCpTpCorp wxCpTpCorp = WxCpTpCorp.fromJson(jsonObject.get("auth_corp_info").getAsString());
+ wxCpTpCorp.setPermanentCode(jsonObject.get("permanent_code").getAsString());
+ return wxCpTpCorp;
+ }
+
+ @Override
+ public String get(String url, String queryParam) throws WxErrorException {
+ return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
+ }
+
+ @Override
+ public String post(String url, String postData) throws WxErrorException {
+ return execute(SimplePostRequestExecutor.create(this), url, postData);
+ }
+
+ /**
+ * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求.
+ */
+ @Override
+ public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ int retryTimes = 0;
+ do {
+ try {
+ return this.executeInternal(executor, uri, data);
+ } catch (WxErrorException e) {
+ if (retryTimes + 1 > this.maxRetryTimes) {
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ //最后一次重试失败后,直接抛出异常,不再等待
+ throw new RuntimeException("微信服务端异常,超出重试次数");
+ }
+
+ WxError error = e.getError();
+ /*
+ * -1 系统繁忙, 1000ms后重试
+ */
+ if (error.getErrorCode() == -1) {
+ int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
+ try {
+ log.debug("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
+ Thread.sleep(sleepMillis);
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ }
+ } else {
+ throw e;
+ }
+ }
+ } while (retryTimes++ < this.maxRetryTimes);
+
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ throw new RuntimeException("微信服务端异常,超出重试次数");
+ }
+
+ protected T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ E dataForLog = DataUtils.handleDataWithSecret(data);
+
+ if (uri.contains("suite_access_token=")) {
+ throw new IllegalArgumentException("uri参数中不允许有suite_access_token: " + uri);
+ }
+ String suiteAccessToken = getSuiteAccessToken(false);
+
+ String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken;
+
+ try {
+ T result = executor.execute(uriWithAccessToken, data);
+ log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
+ return result;
+ } catch (WxErrorException e) {
+ WxError error = e.getError();
+ /*
+ * 发生以下情况时尝试刷新suite_access_token
+ * 42009 suite_access_token已过期
+ */
+ if (error.getErrorCode() == 42009) {
+ // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token
+ this.configStorage.expireSuiteAccessToken();
+ return execute(executor, uri, data);
+ }
+
+ if (error.getErrorCode() != 0) {
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
+ throw new WxErrorException(error, e);
+ }
+ return null;
+ } catch (IOException e) {
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setWxCpTpConfigStorage(WxCpTpConfigStorage wxConfigProvider) {
+ this.configStorage = wxConfigProvider;
+ this.initHttp();
+ }
+
+ @Override
+ public void setRetrySleepMillis(int retrySleepMillis) {
+ this.retrySleepMillis = retrySleepMillis;
+ }
+
+
+ @Override
+ public void setMaxRetryTimes(int maxRetryTimes) {
+ this.maxRetryTimes = maxRetryTimes;
+ }
+
+ public File getTmpDirFile() {
+ return this.tmpDirFile;
+ }
+
+ public void setTmpDirFile(File tmpDirFile) {
+ this.tmpDirFile = tmpDirFile;
+ }
+
+ @Override
+ public RequestHttp, ?> getRequestHttp() {
+ return this;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
index 3a977b81..6a9b7746 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
@@ -1,11 +1,9 @@
package me.chanjar.weixin.cp.api.impl;
-import java.util.List;
-
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
-
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpAgentService;
@@ -13,6 +11,10 @@ import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpAgent;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.List;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Agent.*;
+
/**
*
@@ -22,14 +24,11 @@ import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
*
* @author huansinho
*/
+@RequiredArgsConstructor
public class WxCpAgentServiceImpl implements WxCpAgentService {
private static final JsonParser JSON_PARSER = new JsonParser();
- private WxCpService mainService;
-
- public WxCpAgentServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public WxCpAgent get(Integer agentId) throws WxErrorException {
@@ -37,14 +36,13 @@ public class WxCpAgentServiceImpl implements WxCpAgentService {
throw new IllegalArgumentException("缺少agentid参数");
}
- String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?agentid=" + agentId;
- String responseContent = this.mainService.get(url, null);
+ String responseContent = this.mainService.get(String.format(this.mainService.getWxCpConfigStorage().getApiUrl(AGENT_GET), agentId), null);
return WxCpAgent.fromJson(responseContent);
}
@Override
public void set(WxCpAgent agentInfo) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/set";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(AGENT_SET);
String responseContent = this.mainService.post(url, agentInfo.toJson());
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (jsonObject.get("errcode").getAsInt() != 0) {
@@ -54,7 +52,7 @@ public class WxCpAgentServiceImpl implements WxCpAgentService {
@Override
public List list() throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/list";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(AGENT_LIST);
String responseContent = this.mainService.get(url, null);
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (jsonObject.get("errcode").getAsInt() != 0) {
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java
index 05d298c9..bd5baf01 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java
@@ -1,12 +1,14 @@
package me.chanjar.weixin.cp.api.impl;
import com.google.gson.JsonParser;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.cp.api.WxCpChatService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
import me.chanjar.weixin.cp.bean.WxCpChat;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
@@ -14,24 +16,18 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Chat.*;
+
/**
* 群聊服务实现.
*
* @author gaigeshen
*/
+@RequiredArgsConstructor
public class WxCpChatServiceImpl implements WxCpChatService {
private static final JsonParser JSON_PARSER = new JsonParser();
private final WxCpService cpService;
- /**
- * 创建群聊服务实现的实例.
- *
- * @param cpService 企业微信的服务
- */
- WxCpChatServiceImpl(WxCpService cpService) {
- this.cpService = cpService;
- }
-
@Override
public String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException {
Map data = new HashMap<>(4);
@@ -47,7 +43,7 @@ public class WxCpChatServiceImpl implements WxCpChatService {
if (StringUtils.isNotBlank(chatId)) {
data.put("chatid", chatId);
}
- String result = this.cpService.post(APPCHAT_CREATE, WxGsonBuilder.create().toJson(data));
+ String result = this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_CREATE), WxGsonBuilder.create().toJson(data));
return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString();
}
@@ -76,7 +72,7 @@ public class WxCpChatServiceImpl implements WxCpChatService {
data.put("del_user_list", usersToDelete);
}
- this.cpService.post(APPCHAT_UPDATE, WxGsonBuilder.create().toJson(data));
+ this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_UPDATE), WxGsonBuilder.create().toJson(data));
}
@Override
@@ -86,7 +82,7 @@ public class WxCpChatServiceImpl implements WxCpChatService {
@Override
public WxCpChat chatGet(String chatId) throws WxErrorException {
- String result = this.cpService.get(APPCHAT_GET_CHATID + chatId, null);
+ String result = this.cpService.get(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_GET_CHATID + chatId), null);
return WxCpGsonBuilder.create()
.fromJson(JSON_PARSER.parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class);
}
@@ -98,7 +94,7 @@ public class WxCpChatServiceImpl implements WxCpChatService {
@Override
public void sendMsg(WxCpAppChatMessage message) throws WxErrorException {
- this.cpService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/send", message.toJson());
+ this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_SEND), message.toJson());
}
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
index 481115fa..fb2224e3 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
@@ -1,17 +1,21 @@
package me.chanjar.weixin.cp.api.impl;
-import java.util.List;
-
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.cp.api.WxCpDepartmentService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.List;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Department.*;
+
/**
*
* 部门管理接口
@@ -20,16 +24,13 @@ import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpDepartmentServiceImpl implements WxCpDepartmentService {
- private WxCpService mainService;
-
- public WxCpDepartmentServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public Long create(WxCpDepart depart) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEPARTMENT_CREATE);
String responseContent = this.mainService.post(url, depart.toJson());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return GsonHelper.getAsLong(tmpJsonElement.getAsJsonObject().get("id"));
@@ -37,19 +38,19 @@ public class WxCpDepartmentServiceImpl implements WxCpDepartmentService {
@Override
public void update(WxCpDepart group) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEPARTMENT_UPDATE);
this.mainService.post(url, group.toJson());
}
@Override
public void delete(Long departId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?id=" + departId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(DEPARTMENT_DELETE), departId);
this.mainService.get(url, null);
}
@Override
public List list(Long id) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEPARTMENT_LIST);
if (id != null) {
url += "?id=" + id;
}
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
new file mode 100644
index 00000000..18910008
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpExternalContactService;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
+import me.chanjar.weixin.cp.bean.WxCpUserExternalContactList;
+import me.chanjar.weixin.cp.bean.WxCpUserWithExternalPermission;
+
+import java.util.List;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.ExternalContact.*;
+
+public class WxCpExternalContactServiceImpl implements WxCpExternalContactService {
+ private WxCpService mainService;
+
+ public WxCpExternalContactServiceImpl(WxCpService mainService) {
+ this.mainService = mainService;
+ }
+
+ @Override
+ public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException {
+ String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(GET_EXTERNAL_CONTACT + userId), null);
+
+ return WxCpUserExternalContactInfo.fromJson(responseContent);
+ }
+
+ @Override
+ public List listExternalContacts(String userId) throws WxErrorException {
+ String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId), null);
+ WxCpUserExternalContactList list = WxCpUserExternalContactList.fromJson(responseContent);
+ return list.getExternalUserId();
+ }
+
+ @Override
+ public List listFollowUser() throws WxErrorException {
+ String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(GET_FOLLOW_USER_LIST), null);
+ WxCpUserWithExternalPermission list = WxCpUserWithExternalPermission.fromJson(responseContent);
+ return list.getFollowUser();
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java
index 7a3dc444..05e13cfc 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java
@@ -1,10 +1,6 @@
package me.chanjar.weixin.cp.api.impl;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.UUID;
-
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
@@ -12,6 +8,14 @@ import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.cp.api.WxCpMediaService;
import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.UUID;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.*;
/**
*
@@ -21,12 +25,9 @@ import me.chanjar.weixin.cp.api.WxCpService;
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpMediaServiceImpl implements WxCpMediaService {
- private WxCpService mainService;
-
- public WxCpMediaServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream)
@@ -37,7 +38,7 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
@Override
public WxMediaUploadResult upload(String mediaType, File file) throws WxErrorException {
return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()),
- MEDIA_UPLOAD_URL + mediaType, file);
+ this.mainService.getWxCpConfigStorage().getApiUrl(MEDIA_UPLOAD + mediaType), file);
}
@Override
@@ -45,7 +46,7 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
return this.mainService.execute(
BaseMediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(),
this.mainService.getWxCpConfigStorage().getTmpDirFile()),
- MEDIA_GET_URL, "media_id=" + mediaId);
+ this.mainService.getWxCpConfigStorage().getApiUrl(MEDIA_GET), "media_id=" + mediaId);
}
@Override
@@ -53,13 +54,13 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
return this.mainService.execute(
BaseMediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(),
this.mainService.getWxCpConfigStorage().getTmpDirFile()),
- JSSDK_MEDIA_GET_URL, "media_id=" + mediaId);
+ this.mainService.getWxCpConfigStorage().getApiUrl(JSSDK_MEDIA_GET), "media_id=" + mediaId);
}
@Override
public String uploadImg(File file) throws WxErrorException {
final WxMediaUploadResult result = this.mainService
- .execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), IMG_UPLOAD_URL, file);
+ .execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), this.mainService.getWxCpConfigStorage().getApiUrl(IMG_UPLOAD), file);
return result.getUrl();
}
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
index f58eff47..85abe71f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
@@ -1,24 +1,26 @@
package me.chanjar.weixin.cp.api.impl;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpMenuService;
import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Menu.*;
+
/**
*
- * 菜单管理相关接口
+ * 菜单管理相关接口.
* Created by Binary Wang on 2017-6-25.
- * @author Binary Wang
*
+ *
+ * @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpMenuServiceImpl implements WxCpMenuService {
- private WxCpService mainService;
-
- public WxCpMenuServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public void create(WxMenu menu) throws WxErrorException {
@@ -27,7 +29,7 @@ public class WxCpMenuServiceImpl implements WxCpMenuService {
@Override
public void create(Integer agentId, WxMenu menu) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" + agentId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_CREATE), agentId);
this.mainService.post(url, menu.toJson());
}
@@ -38,7 +40,7 @@ public class WxCpMenuServiceImpl implements WxCpMenuService {
@Override
public void delete(Integer agentId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?agentid=" + agentId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_DELETE), agentId);
this.mainService.get(url, null);
}
@@ -49,7 +51,7 @@ public class WxCpMenuServiceImpl implements WxCpMenuService {
@Override
public WxMenu get(Integer agentId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?agentid=" + agentId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_GET), agentId);
try {
String resultContent = this.mainService.get(url, null);
return WxCpGsonBuilder.create().fromJson(resultContent, WxMenu.class);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
index 3507de07..2005bc36 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
@@ -3,30 +3,35 @@ package me.chanjar.weixin.cp.api.impl;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.cp.api.WxCpOAuth2Service;
import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import me.chanjar.weixin.cp.bean.WxCpUserDetail;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import static me.chanjar.weixin.common.api.WxConsts.OAuth2Scope.*;
+import static me.chanjar.weixin.common.api.WxConsts.OAuth2Scope.SNSAPI_PRIVATEINFO;
+import static me.chanjar.weixin.common.api.WxConsts.OAuth2Scope.SNSAPI_USERINFO;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.OAuth2.*;
+
/**
*
- *
+ * oauth2相关接口实现类.
* Created by Binary Wang on 2017-6-25.
- * @author Binary Wang
- *
- * @author Binary Wang
*
+ *
+ * @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpOAuth2ServiceImpl implements WxCpOAuth2Service {
- private WxCpService mainService;
-
- public WxCpOAuth2ServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public String buildAuthorizationUrl(String state) {
@@ -38,55 +43,54 @@ public class WxCpOAuth2ServiceImpl implements WxCpOAuth2Service {
@Override
public String buildAuthorizationUrl(String redirectUri, String state) {
- return this.buildAuthorizationUrl(redirectUri, state, WxConsts.OAuth2Scope.SNSAPI_BASE);
+ return this.buildAuthorizationUrl(redirectUri, state, SNSAPI_BASE);
}
@Override
public String buildAuthorizationUrl(String redirectUri, String state, String scope) {
- StringBuilder url = new StringBuilder("https://open.weixin.qq.com/connect/oauth2/authorize?");
- url.append("appid=").append(this.mainService.getWxCpConfigStorage().getCorpId());
+ StringBuilder url = new StringBuilder(URL_OAUTH2_AUTHORIZE);
+ url.append("?appid=").append(this.mainService.getWxCpConfigStorage().getCorpId());
url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectUri));
url.append("&response_type=code");
url.append("&scope=").append(scope);
- if (WxConsts.OAuth2Scope.SNSAPI_PRIVATEINFO.equals(scope)
- || WxConsts.OAuth2Scope.SNSAPI_USERINFO.equals(scope)) {
+ if (SNSAPI_PRIVATEINFO.equals(scope) || SNSAPI_USERINFO.equals(scope)) {
url.append("&agentid=").append(this.mainService.getWxCpConfigStorage().getAgentId());
}
if (state != null) {
url.append("&state=").append(state);
}
+
url.append("#wechat_redirect");
return url.toString();
}
@Override
- public String[] getUserInfo(String code) throws WxErrorException {
+ public WxCpOauth2UserInfo getUserInfo(String code) throws WxErrorException {
return this.getUserInfo(this.mainService.getWxCpConfigStorage().getAgentId(), code);
}
@Override
- public String[] getUserInfo(Integer agentId, String code) throws WxErrorException {
- String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?code=%s&agentid=%d",
- code, agentId);
- String responseText = this.mainService.get(url, null);
+ public WxCpOauth2UserInfo getUserInfo(Integer agentId, String code) throws WxErrorException {
+ String responseText = this.mainService.get(String.format(this.mainService.getWxCpConfigStorage().getApiUrl(GET_USER_INFO), code, agentId), null);
JsonElement je = new JsonParser().parse(responseText);
JsonObject jo = je.getAsJsonObject();
- return new String[]{GsonHelper.getString(jo, "UserId"),
- GsonHelper.getString(jo, "DeviceId"),
- GsonHelper.getString(jo, "OpenId"),
- GsonHelper.getString(jo, "user_ticket"),
- GsonHelper.getString(jo, "expires_in")
- };
+
+ return WxCpOauth2UserInfo.builder()
+ .userId(GsonHelper.getString(jo, "UserId"))
+ .deviceId(GsonHelper.getString(jo, "DeviceId"))
+ .openId(GsonHelper.getString(jo, "OpenId"))
+ .userTicket(GsonHelper.getString(jo, "user_ticket"))
+ .expiresIn(GsonHelper.getString(jo, "expires_in"))
+ .build();
}
@Override
public WxCpUserDetail getUserDetail(String userTicket) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail";
JsonObject param = new JsonObject();
param.addProperty("user_ticket", userTicket);
- String responseText = this.mainService.post(url, param.toString());
+ String responseText = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_USER_DETAIL), param.toString());
return WxCpGsonBuilder.create().fromJson(responseText, WxCpUserDetail.class);
}
}
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
similarity index 70%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImpl.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java
index 2d1ca6ab..5d7d758c 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,36 +5,34 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.cp.api.WxCpOAService;
+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.util.json.WxCpGsonBuilder;
import java.util.Date;
import java.util.List;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*;
+
/**
* @author Element
- * @Package me.chanjar.weixin.cp.api.impl
* @date 2019-04-06 11:20
- * @Description: TODO
*/
-public class WxCpOAServiceImpl implements WxCpOAService {
-
- private WxCpService mainService;
-
- public WxCpOAServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+@RequiredArgsConstructor
+public class WxCpOaServiceImpl implements WxCpOaService {
+ private final WxCpService mainService;
@Override
- public List getCheckinData(Integer openCheckinDataType, Date starttime, Date endtime, List userIdList) throws WxErrorException {
-
- if (starttime == null || endtime == null) {
+ public List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime,
+ List userIdList) throws WxErrorException {
+ if (startTime == null || endTime == null) {
throw new RuntimeException("starttime and endtime can't be null");
}
@@ -42,15 +40,13 @@ public class WxCpOAServiceImpl implements WxCpOAService {
throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取");
}
- long endtimestamp = endtime.getTime() / 1000L;
- long starttimestamp = starttime.getTime() / 1000L;
+ long endtimestamp = endTime.getTime() / 1000L;
+ long starttimestamp = startTime.getTime() / 1000L;
if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) {
throw new RuntimeException("获取记录时间跨度不超过一个月");
}
- String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata";
-
JsonObject jsonObject = new JsonObject();
JsonArray jsonArray = new JsonArray();
@@ -64,7 +60,7 @@ public class WxCpOAServiceImpl implements WxCpOAService {
jsonObject.add("useridlist", jsonArray);
- String responseContent = this.mainService.post(url, jsonObject.toString());
+ String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_DATA), jsonObject.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
.fromJson(
@@ -76,7 +72,6 @@ public class WxCpOAServiceImpl implements WxCpOAService {
@Override
public List getCheckinOption(Date datetime, List userIdList) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinoption";
if (datetime == null) {
throw new RuntimeException("datetime can't be null");
}
@@ -94,7 +89,7 @@ public class WxCpOAServiceImpl implements WxCpOAService {
jsonObject.addProperty("datetime", datetime.getTime() / 1000L);
jsonObject.add("useridlist", jsonArray);
- String responseContent = this.mainService.post(url, jsonObject.toString());
+ String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_OPTION), jsonObject.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
@@ -106,24 +101,20 @@ public class WxCpOAServiceImpl implements WxCpOAService {
}
@Override
- public WxCpApprovalDataResult getApprovalData(Date starttime, Date endtime, Long nextSpnum) throws WxErrorException {
-
- String url = "https://qyapi.weixin.qq.com/cgi-bin/corp/getapprovaldata";
+ public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
- jsonObject.addProperty("starttime", starttime.getTime() / 1000L);
- jsonObject.addProperty("endtime", endtime.getTime() / 1000L);
+ jsonObject.addProperty("starttime", startTime.getTime() / 1000L);
+ jsonObject.addProperty("endtime", endTime.getTime() / 1000L);
if (nextSpnum != null) {
jsonObject.addProperty("next_spnum", nextSpnum);
}
- String responseContent = this.mainService.post(url, jsonObject.toString());
+ String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DATA), jsonObject.toString());
return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDataResult.class);
}
@Override
- public List getDialRecord(Date starttime, Date endtime, Integer offset, Integer limit) throws WxErrorException {
-
- String url = "https://qyapi.weixin.qq.com/cgi-bin/dial/get_dial_record";
+ public List getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
if (offset == null) {
@@ -137,10 +128,10 @@ public class WxCpOAServiceImpl implements WxCpOAService {
jsonObject.addProperty("offset", offset);
jsonObject.addProperty("limit", limit);
- if (starttime != null && endtime != null) {
+ if (startTime != null && endTime != null) {
- long endtimestamp = endtime.getTime() / 1000L;
- long starttimestamp = starttime.getTime() / 1000L;
+ long endtimestamp = endTime.getTime() / 1000L;
+ long starttimestamp = startTime.getTime() / 1000L;
if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) {
throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询");
@@ -148,11 +139,9 @@ public class WxCpOAServiceImpl implements WxCpOAService {
jsonObject.addProperty("start_time", starttimestamp);
jsonObject.addProperty("end_time", endtimestamp);
-
-
}
- String responseContent = this.mainService.post(url, jsonObject.toString());
+ String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_DIAL_RECORD), jsonObject.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
index 86e23716..d181af67 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
@@ -8,8 +8,8 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.HttpType;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
-import me.chanjar.weixin.cp.api.WxCpOAService;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -19,9 +19,12 @@ import org.apache.http.impl.client.CloseableHttpClient;
import java.io.IOException;
+/**
+ * @author someone
+ */
public class WxCpServiceApacheHttpClientImpl extends BaseWxCpServiceImpl {
- protected CloseableHttpClient httpClient;
- protected HttpHost httpProxy;
+ private CloseableHttpClient httpClient;
+ private HttpHost httpProxy;
@Override
public CloseableHttpClient getRequestHttpClient() {
@@ -45,9 +48,8 @@ public class WxCpServiceApacheHttpClientImpl extends BaseWxCpServiceImpl {
- protected HttpConnectionProvider httpClient;
- protected ProxyInfo httpProxy;
-
+ private HttpConnectionProvider httpClient;
+ private ProxyInfo httpProxy;
@Override
public HttpConnectionProvider getRequestHttpClient() {
@@ -35,11 +42,8 @@ public class WxCpServiceJoddHttpImpl extends BaseWxCpServiceImpl 0) {
- httpProxy = new ProxyInfo(ProxyInfo.ProxyType.HTTP, configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
+ httpProxy = new ProxyInfo(ProxyInfo.ProxyType.HTTP, configStorage.getHttpProxyHost(),
+ configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
}
httpClient = JoddHttp.httpConnectionProvider;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
index 9163ce03..596dc060 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.cp.api.impl;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.error.WxError;
@@ -11,10 +12,15 @@ import okhttp3.*;
import java.io.IOException;
-public class WxCpServiceOkHttpImpl extends BaseWxCpServiceImpl {
- protected OkHttpClient httpClient;
- protected OkHttpProxyInfo httpProxy;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.GET_TOKEN;
+/**
+ * @author someone
+ */
+@Slf4j
+public class WxCpServiceOkHttpImpl extends BaseWxCpServiceImpl {
+ private OkHttpClient httpClient;
+ private OkHttpProxyInfo httpProxy;
@Override
public OkHttpClient getRequestHttpClient() {
@@ -38,35 +44,35 @@ public class WxCpServiceOkHttpImpl extends BaseWxCpServiceImpl 0) {
httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(),
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOnTpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOnTpImpl.java
new file mode 100644
index 00000000..35eab626
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOnTpImpl.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpTpService;
+
+/**
+ *
+ * 默认接口实现类,使用apache httpclient实现,配合第三方应用service使用
+ * Created by zhenjun cai.
+ *
+ *
+ * @author zhenjun cai
+ */
+@RequiredArgsConstructor
+public class WxCpServiceOnTpImpl extends WxCpServiceApacheHttpClientImpl {
+ private final WxCpTpService wxCpTpService;
+
+ @Override
+ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+ if (!this.configStorage.isAccessTokenExpired() && !forceRefresh) {
+ return this.configStorage.getAccessToken();
+ }
+ //access token通过第三方应用service获取
+ //corpSecret对应企业永久授权码
+ WxAccessToken accessToken = wxCpTpService.getCorpToken(this.configStorage.getCorpId(), this.configStorage.getCorpSecret());
+
+ this.configStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ return this.configStorage.getAccessToken();
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java
index 22bb0fcf..d0e97c6e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java
@@ -1,13 +1,8 @@
package me.chanjar.weixin.cp.api.impl;
-import java.util.List;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
+import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpTagService;
@@ -15,27 +10,32 @@ import me.chanjar.weixin.cp.bean.WxCpTag;
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult;
import me.chanjar.weixin.cp.bean.WxCpTagGetResult;
import me.chanjar.weixin.cp.bean.WxCpUser;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.List;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.*;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.TAG_CREATE;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.TAG_UPDATE;
+
/**
*
- * 标签管理接口
+ * 标签管理接口.
* Created by Binary Wang on 2017-6-25.
- * @author Binary Wang
*
+ *
+ * @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpTagServiceImpl implements WxCpTagService {
- private WxCpService mainService;
-
- public WxCpTagServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public String create(String tagName) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/create";
JsonObject o = new JsonObject();
o.addProperty("tagname", tagName);
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_CREATE);
String responseContent = this.mainService.post(url, o.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("tagid").getAsString();
@@ -43,7 +43,7 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public void update(String tagId, String tagName) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/update";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_UPDATE);
JsonObject o = new JsonObject();
o.addProperty("tagid", tagId);
o.addProperty("tagname", tagName);
@@ -52,13 +52,13 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public void delete(String tagId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/delete?tagid=" + tagId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(TAG_DELETE), tagId);
this.mainService.get(url, null);
}
@Override
public List listAll() throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/list";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_LIST);
String responseContent = this.mainService.get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
@@ -71,7 +71,7 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public List listUsersByTagId(String tagId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagid=" + tagId;
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(TAG_GET), tagId);
String responseContent = this.mainService.get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
@@ -84,7 +84,7 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List userIds, List partyIds) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_ADD_TAG_USERS);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("tagid", tagId);
this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject);
@@ -94,7 +94,7 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds, List partyIds) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_DEL_TAG_USERS);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("tagid", tagId);
this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject);
@@ -122,15 +122,12 @@ public class WxCpTagServiceImpl implements WxCpTagService {
@Override
public WxCpTagGetResult get(String tagId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get";
- if (tagId != null) {
- url += "?tagId=" + tagId;
- } else {
+ if (tagId == null) {
throw new IllegalArgumentException("缺少tagId参数");
}
+ String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(TAG_GET), tagId);
String responseContent = this.mainService.get(url, null);
-
return WxCpTagGetResult.fromJson(responseContent);
}
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
index 3011320d..97530a6e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
@@ -5,11 +5,14 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpTaskCardService;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.TaskCard.*;
+
/**
*
* 任务卡片管理接口.
@@ -33,7 +36,7 @@ public class WxCpTaskCardServiceImpl implements WxCpTaskCardService {
data.put("task_id", taskId);
data.put("clicked_key", clickedKey);
- String url = "https://qyapi.weixin.qq.com/cgi-bin/message/update_taskcard";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_TASK_CARD);
this.mainService.post(url, WxGsonBuilder.create().toJson(data));
}
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceApacheHttpClientImpl.java
new file mode 100644
index 00000000..14e75125
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceApacheHttpClientImpl.java
@@ -0,0 +1,114 @@
+package me.chanjar.weixin.cp.api.impl;
+
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import me.chanjar.weixin.common.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.HttpType;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
+import org.apache.http.Consts;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.IOException;
+
+/**
+ * @author someone
+ */
+public class WxCpTpServiceApacheHttpClientImpl extends BaseWxCpTpServiceImpl {
+ private CloseableHttpClient httpClient;
+ private HttpHost httpProxy;
+
+ @Override
+ public CloseableHttpClient getRequestHttpClient() {
+ return httpClient;
+ }
+
+ @Override
+ public HttpHost getRequestHttpProxy() {
+ return httpProxy;
+ }
+
+ @Override
+ public HttpType getRequestType() {
+ return HttpType.APACHE_HTTP;
+ }
+
+ @Override
+ public String getSuiteAccessToken(boolean forceRefresh) throws WxErrorException {
+ if (!this.configStorage.isSuiteAccessTokenExpired() && !forceRefresh) {
+ return this.configStorage.getSuiteAccessToken();
+ }
+
+ synchronized (this.globalSuiteAccessTokenRefreshLock) {
+ try {
+ HttpPost httpPost = new HttpPost(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_SUITE_TOKEN));
+ if (this.httpProxy != null) {
+ RequestConfig config = RequestConfig.custom()
+ .setProxy(this.httpProxy).build();
+ httpPost.setConfig(config);
+ }
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("suite_id", this.configStorage.getSuiteId());
+ jsonObject.addProperty("suite_secret", this.configStorage.getSuiteSecret());
+ jsonObject.addProperty("suite_ticket", this.getSuiteTicket());
+ StringEntity entity = new StringEntity(jsonObject.toString(), Consts.UTF_8);
+ httpPost.setEntity(entity);
+
+ String resultContent;
+ try (CloseableHttpClient httpclient = getRequestHttpClient();
+ CloseableHttpResponse response = httpclient.execute(httpPost)) {
+ resultContent = new BasicResponseHandler().handleResponse(response);
+ } finally {
+ httpPost.releaseConnection();
+ }
+ WxError error = WxError.fromJson(resultContent, WxType.CP);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ jsonObject = new JsonParser().parse(resultContent).getAsJsonObject();
+ String suiteAccussToken = jsonObject.get("suite_access_token").getAsString();
+ Integer expiresIn = jsonObject.get("expires_in").getAsInt();
+ this.configStorage.updateSuiteAccessToken(suiteAccussToken, expiresIn);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return this.configStorage.getSuiteAccessToken();
+ }
+
+ @Override
+ public void initHttp() {
+ ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage.getApacheHttpClientBuilder();
+ if (null == apacheHttpClientBuilder) {
+ apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
+ }
+
+ apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost())
+ .httpProxyPort(this.configStorage.getHttpProxyPort())
+ .httpProxyUsername(this.configStorage.getHttpProxyUsername())
+ .httpProxyPassword(this.configStorage.getHttpProxyPassword());
+
+ if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
+ this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort());
+ }
+
+ this.httpClient = apacheHttpClientBuilder.build();
+ }
+
+ @Override
+ public WxCpTpConfigStorage getWxCpTpConfigStorage() {
+ return this.configStorage;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java
new file mode 100644
index 00000000..f5582021
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java
@@ -0,0 +1,12 @@
+package me.chanjar.weixin.cp.api.impl;
+
+/**
+ *
+ * 默认接口实现类,使用apache httpclient实现
+ * Created by zhenjun cai.
+ *
+ *
+ * @author zhenjun cai
+ */
+public class WxCpTpServiceImpl extends WxCpTpServiceApacheHttpClientImpl {
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java
index 84a16f34..c75f7566 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java
@@ -1,23 +1,23 @@
package me.chanjar.weixin.cp.api.impl;
-import java.util.List;
-import java.util.Map;
-
import com.google.common.collect.Maps;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
+import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpUserService;
import me.chanjar.weixin.cp.bean.WxCpInviteResult;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.List;
+import java.util.Map;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.User.*;
+
/**
*
* Created by BinaryWang on 2017/6/24.
@@ -25,59 +25,54 @@ import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxCpUserServiceImpl implements WxCpUserService {
- private WxCpService mainService;
-
- public WxCpUserServiceImpl(WxCpService mainService) {
- this.mainService = mainService;
- }
+ private final WxCpService mainService;
@Override
public void authenticate(String userId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?userid=" + userId;
- this.mainService.get(url, null);
+ this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(USER_AUTHENTICATE + userId), null);
}
@Override
public void create(WxCpUser user) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/create";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_CREATE);
this.mainService.post(url, user.toJson());
}
@Override
public void update(WxCpUser user) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/update";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_UPDATE);
this.mainService.post(url, user.toJson());
}
@Override
public void delete(String... userIds) throws WxErrorException {
if (userIds.length == 1) {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/delete?userid=" + userIds[0];
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_DELETE + userIds[0]);
this.mainService.get(url, null);
return;
}
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete";
JsonObject jsonObject = new JsonObject();
JsonArray jsonArray = new JsonArray();
- for (String userid : userIds) {
- jsonArray.add(new JsonPrimitive(userid));
+ for (String userId : userIds) {
+ jsonArray.add(new JsonPrimitive(userId));
}
+
jsonObject.add("useridlist", jsonArray);
- this.mainService.post(url, jsonObject.toString());
+ this.mainService.post(USER_BATCH_DELETE, jsonObject.toString());
}
@Override
public WxCpUser getById(String userid) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?userid=" + userid;
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_GET + userid);
String responseContent = this.mainService.get(url, null);
return WxCpUser.fromJson(responseContent);
}
@Override
public List listByDepartment(Long departId, Boolean fetchChild, Integer status) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/list?department_id=" + departId;
String params = "";
if (fetchChild != null) {
params += "&fetch_child=" + (fetchChild ? "1" : "0");
@@ -88,6 +83,7 @@ public class WxCpUserServiceImpl implements WxCpUserService {
params += "&status=0";
}
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_LIST + departId);
String responseContent = this.mainService.get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
@@ -99,7 +95,6 @@ public class WxCpUserServiceImpl implements WxCpUserService {
@Override
public List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?department_id=" + departId;
String params = "";
if (fetchChild != null) {
params += "&fetch_child=" + (fetchChild ? "1" : "0");
@@ -110,6 +105,7 @@ public class WxCpUserServiceImpl implements WxCpUserService {
params += "&status=0";
}
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_SIMPLE_LIST + departId);
String responseContent = this.mainService.get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.create()
@@ -122,7 +118,6 @@ public class WxCpUserServiceImpl implements WxCpUserService {
@Override
public WxCpInviteResult invite(List userIds, List partyIds, List tagIds) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/invite";
JsonObject jsonObject = new JsonObject();
if (userIds != null) {
JsonArray jsonArray = new JsonArray();
@@ -148,12 +143,13 @@ public class WxCpUserServiceImpl implements WxCpUserService {
jsonObject.add("tag", jsonArray);
}
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(BATCH_INVITE);
return WxCpInviteResult.fromJson(this.mainService.post(url, jsonObject.toString()));
}
@Override
public Map userId2Openid(String userId, Integer agentId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid";
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_CONVERT_TO_OPENID);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("userid", userId);
if (agentId != null) {
@@ -176,9 +172,19 @@ public class WxCpUserServiceImpl implements WxCpUserService {
@Override
public String openid2UserId(String openid) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_userid";
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("openid", openid);
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(USER_CONVERT_TO_USERID);
+ String responseContent = this.mainService.post(url, jsonObject.toString());
+ JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
+ return tmpJsonElement.getAsJsonObject().get("userid").getAsString();
+ }
+
+ @Override
+ public String getUserId(String mobile) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("mobile", mobile);
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_USER_ID);
String responseContent = this.mainService.post(url, jsonObject.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("userid").getAsString();
@@ -186,7 +192,7 @@ public class WxCpUserServiceImpl implements WxCpUserService {
@Override
public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException {
- String url = "https://qyapi.weixin.qq.com/cgi-bin/crm/get_external_contact?external_userid=" + userId;
+ String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_EXTERNAL_CONTACT + userId);
String responseContent = this.mainService.get(url, null);
return WxCpUserExternalContactInfo.fromJson(responseContent);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java
index 96639f6c..0af13a84 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java
@@ -6,7 +6,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import me.chanjar.weixin.cp.WxCpConsts.AppChatMsgType;
+import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
index a22efd0e..b07e3d54 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
@@ -8,11 +8,15 @@ import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import me.chanjar.weixin.cp.bean.messagebuilder.*;
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
+import me.chanjar.weixin.cp.constant.WxCpConsts;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+
+import static me.chanjar.weixin.common.api.WxConsts.KefuMsgType.*;
/**
* 消息.
@@ -40,9 +44,13 @@ public class WxCpMessage implements Serializable {
private String btnTxt;
private List articles = new ArrayList<>();
private List mpnewsArticles = new ArrayList<>();
+ private String appId;
+ private String page;
+ private Boolean emphasisFirstItem;
+ private Map contentItems;
/**
- * 任务卡片特有的属性
+ * 任务卡片特有的属性.
*/
private String taskId;
private List taskButtons = new ArrayList<>();
@@ -117,10 +125,16 @@ public class WxCpMessage implements Serializable {
return new TaskCardBuilder();
}
+ /**
+ * 获得小程序通知消息builder.
+ */
+ public static MiniProgramNoticeMsgBuilder newMiniProgramNoticeBuilder() {
+ return new MiniProgramNoticeMsgBuilder();
+ }
/**
*
- * 请使用
+ * 请使用.
* {@link KefuMsgType#TEXT}
* {@link KefuMsgType#IMAGE}
* {@link KefuMsgType#VOICE}
@@ -130,6 +144,7 @@ public class WxCpMessage implements Serializable {
* {@link KefuMsgType#MPNEWS}
* {@link KefuMsgType#MARKDOWN}
* {@link KefuMsgType#TASKCARD}
+ * {@link KefuMsgType#MINIPROGRAM_NOTICE}
*
*
* @param msgType 消息类型
@@ -169,19 +184,19 @@ public class WxCpMessage implements Serializable {
private void handleMsgType(JsonObject messageJson) {
switch (this.getMsgType()) {
- case KefuMsgType.TEXT: {
+ case TEXT: {
JsonObject text = new JsonObject();
text.addProperty("content", this.getContent());
messageJson.add("text", text);
break;
}
- case KefuMsgType.MARKDOWN: {
+ case MARKDOWN: {
JsonObject text = new JsonObject();
text.addProperty("content", this.getContent());
messageJson.add("markdown", text);
break;
}
- case KefuMsgType.TEXTCARD: {
+ case TEXTCARD: {
JsonObject text = new JsonObject();
text.addProperty("title", this.getTitle());
text.addProperty("description", this.getDescription());
@@ -190,25 +205,25 @@ public class WxCpMessage implements Serializable {
messageJson.add("textcard", text);
break;
}
- case KefuMsgType.IMAGE: {
+ case IMAGE: {
JsonObject image = new JsonObject();
image.addProperty("media_id", this.getMediaId());
messageJson.add("image", image);
break;
}
- case KefuMsgType.FILE: {
+ case FILE: {
JsonObject image = new JsonObject();
image.addProperty("media_id", this.getMediaId());
messageJson.add("file", image);
break;
}
- case KefuMsgType.VOICE: {
+ case VOICE: {
JsonObject voice = new JsonObject();
voice.addProperty("media_id", this.getMediaId());
messageJson.add("voice", voice);
break;
}
- case KefuMsgType.VIDEO: {
+ case VIDEO: {
JsonObject video = new JsonObject();
video.addProperty("media_id", this.getMediaId());
video.addProperty("thumb_media_id", this.getThumbMediaId());
@@ -217,7 +232,7 @@ public class WxCpMessage implements Serializable {
messageJson.add("video", video);
break;
}
- case KefuMsgType.NEWS: {
+ case NEWS: {
JsonObject newsJsonObject = new JsonObject();
JsonArray articleJsonArray = new JsonArray();
for (NewArticle article : this.getArticles()) {
@@ -232,7 +247,7 @@ public class WxCpMessage implements Serializable {
messageJson.add("news", newsJsonObject);
break;
}
- case KefuMsgType.MPNEWS: {
+ case MPNEWS: {
JsonObject newsJsonObject = new JsonObject();
if (this.getMediaId() != null) {
newsJsonObject.addProperty("media_id", this.getMediaId());
@@ -255,7 +270,7 @@ public class WxCpMessage implements Serializable {
messageJson.add("mpnews", newsJsonObject);
break;
}
- case KefuMsgType.TASKCARD: {
+ case TASKCARD: {
JsonObject text = new JsonObject();
text.addProperty("title", this.getTitle());
text.addProperty("description", this.getDescription());
@@ -291,6 +306,25 @@ public class WxCpMessage implements Serializable {
messageJson.add("taskcard", text);
break;
}
+ case MINIPROGRAM_NOTICE: {
+ JsonObject notice = new JsonObject();
+ notice.addProperty("appid", this.getAppId());
+ notice.addProperty("page", this.getPage());
+ notice.addProperty("description", this.getDescription());
+ notice.addProperty("title", this.getTitle());
+ notice.addProperty("emphasis_first_item", this.getEmphasisFirstItem());
+ JsonArray content = new JsonArray();
+ for (Map.Entry item : this.getContentItems().entrySet()) {
+ JsonObject articleJson = new JsonObject();
+ articleJson.addProperty("key", item.getKey());
+ articleJson.addProperty("value", item.getValue());
+ content.add(articleJson);
+ }
+ notice.add("content_item", content);
+
+ messageJson.add("miniprogram_notice", notice);
+ break;
+ }
default: {
// do nothing
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpOauth2UserInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpOauth2UserInfo.java
new file mode 100644
index 00000000..9122f18d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpOauth2UserInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.cp.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * 用oauth2获取用户信息的结果类
+ * Created by BinaryWang on 2019/5/26.
+ *
+ *
+ * @author Binary Wang
+ */
+@Data
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class WxCpOauth2UserInfo {
+ private String openId;
+ private String deviceId;
+ private String userId;
+ private String userTicket;
+ private String expiresIn;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java
index 28cc4807..244419b0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java
@@ -29,19 +29,19 @@ public class WxCpTagGetResult implements Serializable {
private String errmsg;
/**
- * 用户列表
+ * 用户列表.
*/
@SerializedName("userlist")
private List userlist;
/**
- * 部门列表
+ * 部门列表.
*/
@SerializedName("partylist")
private List partylist;
/**
- * 标签名称
+ * 标签名称.
*/
@SerializedName("tagname")
private String tagname;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCorp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCorp.java
new file mode 100644
index 00000000..9ca59b84
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpCorp.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.cp.bean;
+
+import java.io.Serializable;
+
+import com.google.gson.annotations.SerializedName;
+
+import lombok.Data;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 微信部门.
+ *
+ * @author Daniel Qian
+ */
+@Data
+public class WxCpTpCorp implements Serializable {
+
+ private static final long serialVersionUID = -5028321625140879571L;
+ @SerializedName("corpid")
+ private String corpId;
+ @SerializedName("corp_name")
+ private String corpName;
+ @SerializedName("corp_full_name")
+ private String corpFullName;
+ @SerializedName("corp_type")
+ private String corpType;
+ @SerializedName("corp_square_logo_url")
+ private String corpSquareLogoUrl;
+ @SerializedName("corp_user_max")
+ private String corpUserMax;
+ @SerializedName("permanent_code")
+ private String permanentCode;
+
+ public static WxCpTpCorp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpTpCorp.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java
new file mode 100644
index 00000000..53e068db
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.cp.bean;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.util.XmlUtils;
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.ImageBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.NewsBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.TextBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.VideoBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.VoiceBuilder;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
+import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
+
+/**
+ * 回调推送的message
+ * https://work.weixin.qq.com/api/doc#90001/90143/90612
+ *
+ * @author zhenjun cai
+ */
+@XStreamAlias("xml")
+@Slf4j
+@Data
+public class WxCpTpXmlMessage implements Serializable {
+
+ private static final long serialVersionUID = 6031833682211475786L;
+ /**
+ * 使用dom4j解析的存放所有xml属性和值的map.
+ */
+ private Map allFieldsMap;
+
+ @XStreamAlias("SuiteId")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String suiteId;
+
+ @XStreamAlias("InfoType")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String infoType;
+
+ @XStreamAlias("TimeStamp")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String timeStamp;
+
+ @XStreamAlias("SuiteTicket")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String suiteTicket;
+
+ @XStreamAlias("AuthCode")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String authCode;
+
+ public static WxCpTpXmlMessage fromXml(String xml) {
+ //修改微信变态的消息内容格式,方便解析
+ //xml = xml.replace("", "");
+ final WxCpTpXmlMessage xmlPackage = XStreamTransformer.fromXml(WxCpTpXmlMessage.class, xml);
+ xmlPackage.setAllFieldsMap(XmlUtils.xml2Map(xml));
+ return xmlPackage;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlPackage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlPackage.java
new file mode 100644
index 00000000..82c33f52
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlPackage.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.cp.bean;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import lombok.Data;
+import me.chanjar.weixin.common.util.XmlUtils;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.ImageBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.NewsBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.TextBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.VideoBuilder;
+import me.chanjar.weixin.cp.bean.outxmlbuilder.VoiceBuilder;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
+import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
+
+/**
+ * 回调消息包.
+ * https://work.weixin.qq.com/api/doc#90001/90143/91116
+ *
+ * @author zhenjun cai
+ */
+@XStreamAlias("xml")
+@Data
+public class WxCpTpXmlPackage implements Serializable {
+
+ private static final long serialVersionUID = 6031833682211475786L;
+ /**
+ * 使用dom4j解析的存放所有xml属性和值的map.
+ */
+ private Map allFieldsMap;
+
+ @XStreamAlias("ToUserName")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String toUserName;
+
+ @XStreamAlias("AgentID")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String agentId;
+
+ @XStreamAlias("Encrypt")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String msgEncrypt;
+
+ public static WxCpTpXmlPackage fromXml(String xml) {
+ //修改微信变态的消息内容格式,方便解析
+ //xml = xml.replace(" ", "");
+ final WxCpTpXmlPackage xmlPackage = XStreamTransformer.fromXml(WxCpTpXmlPackage.class, xml);
+ xmlPackage.setAllFieldsMap(XmlUtils.xml2Map(xml));
+ return xmlPackage;
+ }
+}
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 dcf4789e..8f4e4989 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
@@ -31,6 +31,11 @@ public class WxCpUser implements Serializable {
private Integer status;
private Integer enable;
private Integer isLeader;
+ /**
+ * is_leader_in_dept.
+ * 个数必须和department一致,表示在所在的部门内是否为上级。1表示为上级,0表示非上级。在审批等应用里可以用来标识上级审批人
+ */
+ private Integer[] isLeaderInDept;
private final List extAttrs = new ArrayList<>();
private Integer hideMobile;
private String englishName;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
index 466eac4a..d099e4ee 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
@@ -1,16 +1,11 @@
package me.chanjar.weixin.cp.bean;
-import java.util.List;
-
import com.google.gson.annotations.SerializedName;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
+import lombok.*;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.List;
+
/**
*
* 外部联系人详情
@@ -118,9 +113,26 @@ public class WxCpUserExternalContactInfo {
private String description;
@SerializedName("createtime")
private Long createTime;
+ private String state;
+ @SerializedName("remark_company")
+ private String remarkCompany;
+ @SerializedName("remark_mobiles")
+ private String[] remarkMobiles;
+ private Tag[] tags;
+
}
public static WxCpUserExternalContactInfo fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalContactInfo.class);
}
+
+ @Setter
+ @Getter
+ public static class Tag {
+ @SerializedName("group_name")
+ private String groupName;
+ @SerializedName("tag_name")
+ private String tagName;
+ private int type;
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactList.java
new file mode 100644
index 00000000..25e42ffc
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactList.java
@@ -0,0 +1,58 @@
+package me.chanjar.weixin.cp.bean;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ *
+ * 外部联系人列表
+ * Created by Joe Cao on 2019/6/16.
+ * 参考文档:https://work.weixin.qq.com/api/doc#90001/90143/91570
+ *
+ *
+ * @author Joe Cao
+ */
+public class WxCpUserExternalContactList {
+ @SerializedName("errcode")
+ @Expose
+ private Long errcode;
+ @SerializedName("errmsg")
+ @Expose
+ private String errmsg;
+
+ @SerializedName("external_userid")
+ @Expose
+ private List externalUserId = null;
+
+ public Long getErrcode() {
+ return errcode;
+ }
+
+ public void setErrcode(Long errcode) {
+ this.errcode = errcode;
+ }
+
+ public String getErrmsg() {
+ return errmsg;
+ }
+
+ public void setErrmsg(String errmsg) {
+ this.errmsg = errmsg;
+ }
+
+
+ public List getExternalUserId() {
+ return externalUserId;
+ }
+
+ public void setExternalUserId(List externalUserId) {
+ this.externalUserId = externalUserId;
+ }
+
+ public static WxCpUserExternalContactList fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalContactList.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserWithExternalPermission.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserWithExternalPermission.java
new file mode 100644
index 00000000..2530c79d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserWithExternalPermission.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.cp.bean;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+public class WxCpUserWithExternalPermission {
+ @SerializedName("errcode")
+ @Expose
+ private Long errcode;
+ @SerializedName("errmsg")
+ @Expose
+ private String errmsg;
+
+ @SerializedName("follow_user")
+ @Expose
+ private List followUser = null;
+
+ public Long getErrcode() {
+ return errcode;
+ }
+
+ public void setErrcode(Long errcode) {
+ this.errcode = errcode;
+ }
+
+ public String getErrmsg() {
+ return errmsg;
+ }
+
+ public void setErrmsg(String errmsg) {
+ this.errmsg = errmsg;
+ }
+
+ public List getFollowUser() {
+ return followUser;
+ }
+
+ public void setFollowUser(List followUser) {
+ this.followUser = followUser;
+ }
+
+
+ public static WxCpUserWithExternalPermission fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpUserWithExternalPermission.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
index e6b2be19..771e5729 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
@@ -162,7 +162,7 @@ public class WxCpXmlMessage implements Serializable {
/**
* 通讯录变更事件.
- * 请参考常量 me.chanjar.weixin.cp.WxCpConsts.ContactChangeType
+ * 请参考常量 me.chanjar.weixin.cp.constant.WxCpConsts.ContactChangeType
*/
@XStreamAlias("ChangeType")
@XStreamConverter(value = XStreamCDataConverter.class)
@@ -175,6 +175,26 @@ public class WxCpXmlMessage implements Serializable {
@XStreamConverter(value = XStreamCDataConverter.class)
private String userId;
+ /**
+ * 变更信息的外部联系人的userid,注意不是企业成员的帐号.
+ */
+ @XStreamAlias("ExternalUserID")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String externalUserId;
+
+ /**
+ * 添加此用户的「联系我」方式配置的state参数,可用于识别添加此用户的渠道.
+ */
+ @XStreamAlias("State")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String state;
+
+ /**
+ * 欢迎语code,可用于发送欢迎语.
+ */
+ @XStreamAlias("WelcomeCode")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String welcomeCode;
/**
* 新的UserID,变更时推送(userid由系统生成时可更改一次).
*/
@@ -191,11 +211,11 @@ public class WxCpXmlMessage implements Serializable {
private String name;
/**
- * 成员部门列表.
+ * 成员部门列表,变更时推送,仅返回该应用有查看权限的部门id.
*/
@XStreamAlias("Department")
@XStreamConverter(value = XStreamCDataConverter.class)
- private String department;
+ private Long[] departments;
/**
* 手机号码.
@@ -244,6 +264,12 @@ public class WxCpXmlMessage implements Serializable {
@XStreamAlias("IsLeader")
private Integer isLeader;
+ /**
+ * 表示所在部门是否为上级,0-否,1-是,顺序与Department字段的部门逐一对应.
+ */
+ @XStreamAlias("IsLeaderInDept")
+ private Integer[] isLeaderInDept;
+
/**
* 座机.
*/
@@ -268,7 +294,7 @@ public class WxCpXmlMessage implements Serializable {
* 部门Id.
*/
@XStreamAlias("Id")
- private Integer id;
+ private Long id;
/**
* 父部门id.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
new file mode 100644
index 00000000..cf44c0f0
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
@@ -0,0 +1,69 @@
+package me.chanjar.weixin.cp.bean.messagebuilder;
+
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+
+import java.util.Map;
+
+/**
+ *
+ * miniprogram_notice 类型的消息 builder
+ * Created by Binary Wang on 2019/6/16.
+ *
+ *
+ * @author Binary Wang
+ */
+public class MiniProgramNoticeMsgBuilder extends BaseBuilder {
+ private String title;
+ private String description;
+ private String appId;
+ private String page;
+ private Boolean emphasisFirstItem;
+ private Map contentItems;
+
+ public MiniProgramNoticeMsgBuilder() {
+ this.msgType = WxConsts.KefuMsgType.MINIPROGRAM_NOTICE;
+ }
+
+ public MiniProgramNoticeMsgBuilder appId(String appId) {
+ this.appId = appId;
+ return this;
+ }
+
+ public MiniProgramNoticeMsgBuilder page(String page) {
+ this.page = page;
+ return this;
+ }
+
+ public MiniProgramNoticeMsgBuilder title(String title) {
+ this.title = title;
+ return this;
+ }
+
+ public MiniProgramNoticeMsgBuilder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public MiniProgramNoticeMsgBuilder contentItems(Map contentItems) {
+ this.contentItems = contentItems;
+ return this;
+ }
+
+ public MiniProgramNoticeMsgBuilder emphasisFirstItem(Boolean emphasisFirstItem) {
+ this.emphasisFirstItem = emphasisFirstItem;
+ return this;
+ }
+
+ @Override
+ public WxCpMessage build() {
+ WxCpMessage m = super.build();
+ m.setContentItems(this.contentItems);
+ m.setAppId(this.appId);
+ m.setDescription(this.description);
+ m.setTitle(this.title);
+ m.setEmphasisFirstItem(this.emphasisFirstItem);
+ m.setPage(this.page);
+ return m;
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
index e1373814..c4dbf8f1 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
@@ -6,18 +6,32 @@ import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import java.io.File;
/**
- * 微信客户端配置存储
+ * 微信客户端配置存储.
*
* @author Daniel Qian
*/
public interface WxCpConfigStorage {
+ /**
+ * 设置企业微信服务器 baseUrl.
+ * 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl
+ *
+ * @param baseUrl 企业微信服务器 Url
+ */
+ void setBaseApiUrl(String baseUrl);
+
+ /**
+ * 读取企业微信 API Url.
+ * 支持私有化企业微信服务器.
+ */
+ String getApiUrl(String path);
+
String getAccessToken();
boolean isAccessTokenExpired();
/**
- * 强制将access token过期掉
+ * 强制将access token过期掉.
*/
void expireAccessToken();
@@ -30,12 +44,12 @@ public interface WxCpConfigStorage {
boolean isJsapiTicketExpired();
/**
- * 强制将jsapi ticket过期掉
+ * 强制将jsapi ticket过期掉.
*/
void expireJsapiTicket();
/**
- * 应该是线程安全的
+ * 应该是线程安全的.
*/
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
@@ -44,12 +58,12 @@ public interface WxCpConfigStorage {
boolean isAgentJsapiTicketExpired();
/**
- * 强制将jsapi ticket过期掉
+ * 强制将jsapi ticket过期掉.
*/
void expireAgentJsapiTicket();
/**
- * 应该是线程安全的
+ * 应该是线程安全的.
*/
void updateAgentJsapiTicket(String jsapiTicket, int expiresInSeconds);
@@ -78,7 +92,7 @@ public interface WxCpConfigStorage {
File getTmpDirFile();
/**
- * http client builder
+ * http client builder.
*
* @return ApacheHttpClientBuilder
*/
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java
new file mode 100644
index 00000000..fadfb0bd
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java
@@ -0,0 +1,86 @@
+package me.chanjar.weixin.cp.config;
+
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+
+import java.io.File;
+
+/**
+ * 微信客户端(第三方应用)配置存储
+ *
+ * @author zhenjun cai
+ */
+public interface WxCpTpConfigStorage {
+
+ /**
+ * 设置企业微信服务器 baseUrl.
+ * 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl
+ *
+ * @param baseUrl 企业微信服务器 Url
+ */
+ void setBaseApiUrl(String baseUrl);
+
+ /**
+ * 读取企业微信 API Url.
+ * 支持私有化企业微信服务器.
+ */
+ String getApiUrl(String path);
+
+ String getSuiteAccessToken();
+
+ boolean isSuiteAccessTokenExpired();
+
+ /**
+ * 强制将suite access token过期掉.
+ */
+ void expireSuiteAccessToken();
+
+ void updateSuiteAccessToken(WxAccessToken suiteAccessToken);
+
+ void updateSuiteAccessToken(String suiteAccessToken, int expiresIn);
+
+ String getSuiteTicket();
+
+ boolean isSuiteTicketExpired();
+
+ /**
+ * 强制将suite ticket过期掉.
+ */
+ void expireSuiteTicket();
+
+ /**
+ * 应该是线程安全的.
+ */
+ void updateSuiteTicket(String suiteTicket, int expiresInSeconds);
+
+ String getCorpId();
+
+ String getCorpSecret();
+
+ String getSuiteId();
+
+ String getSuiteSecret();
+
+ String getToken();
+
+ String getAesKey();
+
+ long getExpiresTime();
+
+ String getHttpProxyHost();
+
+ int getHttpProxyPort();
+
+ String getHttpProxyUsername();
+
+ String getHttpProxyPassword();
+
+ File getTmpDirFile();
+
+ /**
+ * http client builder.
+ *
+ * @return ApacheHttpClientBuilder
+ */
+ ApacheHttpClientBuilder getApacheHttpClientBuilder();
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
similarity index 79%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
index a501edeb..87ed4f61 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
@@ -1,44 +1,63 @@
-package me.chanjar.weixin.cp.config;
+package me.chanjar.weixin.cp.config.impl;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import java.io.File;
+import java.io.Serializable;
/**
- * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
+ * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化.
*
* @author Daniel Qian
*/
-public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
+public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
+ private static final long serialVersionUID = 1154541446729462780L;
- protected volatile String corpId;
- protected volatile String corpSecret;
+ private volatile String corpId;
+ private volatile String corpSecret;
- protected volatile String token;
+ private volatile String token;
protected volatile String accessToken;
- protected volatile String aesKey;
+ private volatile String aesKey;
protected volatile Integer agentId;
- protected volatile long expiresTime;
+ private volatile long expiresTime;
- protected volatile String oauth2redirectUri;
+ private volatile String oauth2redirectUri;
- protected volatile String httpProxyHost;
- protected volatile int httpProxyPort;
- protected volatile String httpProxyUsername;
- protected volatile String httpProxyPassword;
+ private volatile String httpProxyHost;
+ private volatile int httpProxyPort;
+ private volatile String httpProxyUsername;
+ private volatile String httpProxyPassword;
- protected volatile String jsapiTicket;
- protected volatile long jsapiTicketExpiresTime;
+ private volatile String jsapiTicket;
+ private volatile long jsapiTicketExpiresTime;
- protected volatile String agentJsapiTicket;
- protected volatile long agentJsapiTicketExpiresTime;
+ private volatile String agentJsapiTicket;
+ private volatile long agentJsapiTicketExpiresTime;
- protected volatile File tmpDirFile;
+ private volatile File tmpDirFile;
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
+ private volatile String baseApiUrl;
+
+ @Override
+ public void setBaseApiUrl(String baseUrl) {
+ this.baseApiUrl = baseUrl;
+ }
+
+ @Override
+ public String getApiUrl(String path) {
+ if (baseApiUrl == null) {
+ baseApiUrl = WxCpApiPathConsts.DEFAULT_CP_BASE_URL;
+ }
+ return baseApiUrl + path;
+ }
+
@Override
public String getAccessToken() {
return this.accessToken;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
similarity index 89%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
index 7c72de0e..ecaa47cc 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
@@ -1,7 +1,9 @@
-package me.chanjar.weixin.cp.config;
+package me.chanjar.weixin.cp.config.impl;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@@ -16,7 +18,7 @@ import java.io.File;
*
* @author gaigeshen
*/
-public class WxCpJedisConfigStorage implements WxCpConfigStorage {
+public class WxCpRedisConfigImpl implements WxCpConfigStorage {
private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN";
private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME";
private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET";
@@ -38,23 +40,38 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
private volatile File tmpDirFile;
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
- public WxCpJedisConfigStorage(JedisPool jedisPool) {
+ protected volatile String baseApiUrl;
+
+ @Override
+ public void setBaseApiUrl(String baseUrl) {
+ this.baseApiUrl = baseUrl;
+ }
+
+ @Override
+ public String getApiUrl(String path) {
+ if (baseApiUrl == null) {
+ baseApiUrl = WxCpApiPathConsts.DEFAULT_CP_BASE_URL;
+ }
+ return baseApiUrl + path;
+ }
+
+ public WxCpRedisConfigImpl(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
- public WxCpJedisConfigStorage(String host, int port) {
+ public WxCpRedisConfigImpl(String host, int port) {
jedisPool = new JedisPool(host, port);
}
- public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port) {
+ public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port) {
jedisPool = new JedisPool(poolConfig, host, port);
}
- public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password) {
+ public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port, int timeout, String password) {
jedisPool = new JedisPool(poolConfig, host, port, timeout, password);
}
- public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password, int database) {
+ public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port, int timeout, String password, int database) {
jedisPool = new JedisPool(poolConfig, host, port, timeout, password, database);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java
new file mode 100644
index 00000000..d8be83c2
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java
@@ -0,0 +1,248 @@
+package me.chanjar.weixin.cp.config.impl;
+
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化.
+ *
+ * @author someone
+ */
+public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializable {
+ private static final long serialVersionUID = 6678780920621872824L;
+
+ private volatile String corpId;
+ private volatile String corpSecret;
+
+ private volatile String suiteId;
+ private volatile String suiteSecret;
+
+ private volatile String token;
+ private volatile String suiteAccessToken;
+ private volatile String aesKey;
+ private volatile long expiresTime;
+
+ private volatile String oauth2redirectUri;
+
+ private volatile String httpProxyHost;
+ private volatile int httpProxyPort;
+ private volatile String httpProxyUsername;
+ private volatile String httpProxyPassword;
+
+ private volatile String suiteTicket;
+ private volatile long suiteTicketExpiresTime;
+
+ private volatile File tmpDirFile;
+
+ private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
+
+ private volatile String baseApiUrl;
+
+ @Override
+ public void setBaseApiUrl(String baseUrl) {
+ this.baseApiUrl = baseUrl;
+ }
+
+ @Override
+ public String getApiUrl(String path) {
+ if (baseApiUrl == null) {
+ baseApiUrl = "https://qyapi.weixin.qq.com";
+ }
+ return baseApiUrl + path;
+ }
+
+ @Override
+ public String getSuiteAccessToken() {
+ return this.suiteAccessToken;
+ }
+
+ public void setSuiteAccessToken(String suiteAccessToken) {
+ this.suiteAccessToken = suiteAccessToken;
+ }
+
+ @Override
+ public boolean isSuiteAccessTokenExpired() {
+ return System.currentTimeMillis() > this.expiresTime;
+ }
+
+ @Override
+ public void expireSuiteAccessToken() {
+ this.expiresTime = 0;
+ }
+
+ @Override
+ public synchronized void updateSuiteAccessToken(WxAccessToken suiteAccessToken) {
+ updateSuiteAccessToken(suiteAccessToken.getAccessToken(), suiteAccessToken.getExpiresIn());
+ }
+
+ @Override
+ public synchronized void updateSuiteAccessToken(String suiteAccessToken, int expiresInSeconds) {
+ this.suiteAccessToken = suiteAccessToken;
+ this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+ }
+
+ @Override
+ public String getCorpId() {
+ return this.corpId;
+ }
+
+ public void setCorpId(String corpId) {
+ this.corpId = corpId;
+ }
+
+ @Override
+ public String getCorpSecret() {
+ return this.corpSecret;
+ }
+
+ public void setCorpSecret(String corpSecret) {
+ this.corpSecret = corpSecret;
+ }
+
+ @Override
+ public String getSuiteTicket() {
+ return this.suiteTicket;
+ }
+
+ public void setSuiteTicket(String suiteTicket) {
+ this.suiteTicket = suiteTicket;
+ }
+
+ public long getSuiteTicketExpiresTime() {
+ return this.suiteTicketExpiresTime;
+ }
+
+ public void setSuiteTicketExpiresTime(long suiteTicketExpiresTime) {
+ this.suiteTicketExpiresTime = suiteTicketExpiresTime;
+ }
+
+ @Override
+ public boolean isSuiteTicketExpired() {
+ return System.currentTimeMillis() > this.suiteTicketExpiresTime;
+ }
+
+ @Override
+ public synchronized void updateSuiteTicket(String suiteTicket, int expiresInSeconds) {
+ this.suiteTicket = suiteTicket;
+ // 预留200秒的时间
+ this.suiteTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+ }
+
+ @Override
+ public void expireSuiteTicket() {
+ this.suiteTicketExpiresTime = 0;
+ }
+
+ @Override
+ public String getSuiteId() {
+ return this.suiteId;
+ }
+
+ public void setSuiteId(String corpId) {
+ this.suiteId = corpId;
+ }
+
+ @Override
+ public String getSuiteSecret() {
+ return this.suiteSecret;
+ }
+
+ public void setSuiteSecret(String corpSecret) {
+ this.suiteSecret = corpSecret;
+ }
+
+ @Override
+ public String getToken() {
+ return this.token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ @Override
+ public long getExpiresTime() {
+ return this.expiresTime;
+ }
+
+ public void setExpiresTime(long expiresTime) {
+ this.expiresTime = expiresTime;
+ }
+
+ @Override
+ public String getAesKey() {
+ return this.aesKey;
+ }
+
+ public void setAesKey(String aesKey) {
+ this.aesKey = aesKey;
+ }
+
+ public void setOauth2redirectUri(String oauth2redirectUri) {
+ this.oauth2redirectUri = oauth2redirectUri;
+ }
+
+ @Override
+ public String getHttpProxyHost() {
+ return this.httpProxyHost;
+ }
+
+ public void setHttpProxyHost(String httpProxyHost) {
+ this.httpProxyHost = httpProxyHost;
+ }
+
+ @Override
+ public int getHttpProxyPort() {
+ return this.httpProxyPort;
+ }
+
+ public void setHttpProxyPort(int httpProxyPort) {
+ this.httpProxyPort = httpProxyPort;
+ }
+
+ @Override
+ public String getHttpProxyUsername() {
+ return this.httpProxyUsername;
+ }
+
+ public void setHttpProxyUsername(String httpProxyUsername) {
+ this.httpProxyUsername = httpProxyUsername;
+ }
+
+ @Override
+ public String getHttpProxyPassword() {
+ return this.httpProxyPassword;
+ }
+
+ public void setHttpProxyPassword(String httpProxyPassword) {
+ this.httpProxyPassword = httpProxyPassword;
+ }
+
+ @Override
+ public String toString() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ @Override
+ public File getTmpDirFile() {
+ return this.tmpDirFile;
+ }
+
+ public void setTmpDirFile(File tmpDirFile) {
+ this.tmpDirFile = tmpDirFile;
+ }
+
+ @Override
+ public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
+ return this.apacheHttpClientBuilder;
+ }
+
+ public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
+ this.apacheHttpClientBuilder = apacheHttpClientBuilder;
+ }
+}
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
new file mode 100644
index 00000000..6de1a63a
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
@@ -0,0 +1,113 @@
+package me.chanjar.weixin.cp.constant;
+
+
+/**
+ *
+ * 企业微信api地址常量类
+ * Created by BinaryWang on 2019-06-02.
+ *
+ *
+ * @author Binary Wang
+ */
+public final class WxCpApiPathConsts {
+ public static final String DEFAULT_CP_BASE_URL = "https://qyapi.weixin.qq.com";
+
+ public static final String GET_JSAPI_TICKET = "/cgi-bin/get_jsapi_ticket";
+ public static final String GET_AGENT_CONFIG_TICKET = "/cgi-bin/ticket/get?&type=agent_config";
+ public static final String MESSAGE_SEND = "/cgi-bin/message/send";
+ public static final String GET_CALLBACK_IP = "/cgi-bin/getcallbackip";
+ public static final String BATCH_REPLACE_PARTY = "/cgi-bin/batch/replaceparty";
+ public static final String BATCH_REPLACE_USER = "/cgi-bin/batch/replaceuser";
+ public static final String BATCH_GET_RESULT = "/cgi-bin/batch/getresult?jobid=";
+ public static final String JSCODE_TO_SESSION = "/cgi-bin/miniprogram/jscode2session";
+ public static final String GET_TOKEN = "/cgi-bin/gettoken?&corpid=%s&corpsecret=%s";
+
+ public static class Agent {
+ public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d";
+ public static final String AGENT_SET = "/cgi-bin/agent/set";
+ public static final String AGENT_LIST = "/cgi-bin/agent/list";
+ }
+
+ public static class OAuth2 {
+ public static final String GET_USER_INFO = "/cgi-bin/user/getuserinfo?code=%s&agentid=%d";
+ public static final String GET_USER_DETAIL = "/cgi-bin/user/getuserdetail";
+ public static final String URL_OAUTH2_AUTHORIZE = "https://open.weixin.qq.com/connect/oauth2/authorize";
+ }
+
+ public static class Chat {
+ public static final String APPCHAT_CREATE = "/cgi-bin/appchat/create";
+ public static final String APPCHAT_UPDATE = "/cgi-bin/appchat/update";
+ public static final String APPCHAT_GET_CHATID = "/cgi-bin/appchat/get?chatid=";
+ public static final String APPCHAT_SEND = "/cgi-bin/appchat/send";
+ }
+
+ public static class Department {
+ public static final String DEPARTMENT_CREATE = "/cgi-bin/department/create";
+ public static final String DEPARTMENT_UPDATE = "/cgi-bin/department/update";
+ public static final String DEPARTMENT_DELETE = "/cgi-bin/department/delete?id=%d";
+ public static final String DEPARTMENT_LIST = "/cgi-bin/department/list";
+ }
+
+ public static class Media {
+ public static final String MEDIA_GET = "/cgi-bin/media/get";
+ public static final String MEDIA_UPLOAD = "/cgi-bin/media/upload?type=";
+ public static final String IMG_UPLOAD = "/cgi-bin/media/uploadimg";
+ public static final String JSSDK_MEDIA_GET = "/cgi-bin/media/get/jssdk";
+ }
+
+ public static class Menu {
+ public static final String MENU_CREATE = "/cgi-bin/menu/create?agentid=%d";
+ public static final String MENU_DELETE = "/cgi-bin/menu/delete?agentid=%d";
+ public static final String MENU_GET = "/cgi-bin/menu/get?agentid=%d";
+ }
+
+ public static class Oa {
+ public static final String GET_CHECKIN_DATA = "/cgi-bin/checkin/getcheckindata";
+ public static final String GET_CHECKIN_OPTION = "/cgi-bin/checkin/getcheckinoption";
+ public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata";
+ public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record";
+ }
+
+ public static class Tag {
+ public static final String TAG_CREATE = "/cgi-bin/tag/create";
+ public static final String TAG_UPDATE = "/cgi-bin/tag/update";
+ public static final String TAG_DELETE = "/cgi-bin/tag/delete?tagid=%s";
+ public static final String TAG_LIST = "/cgi-bin/tag/list";
+ public static final String TAG_GET = "/cgi-bin/tag/get?tagid=%s";
+ public static final String TAG_ADD_TAG_USERS = "/cgi-bin/tag/addtagusers";
+ public static final String TAG_DEL_TAG_USERS = "/cgi-bin/tag/deltagusers";
+ }
+
+ public static class TaskCard {
+ public static final String UPDATE_TASK_CARD = "/cgi-bin/message/update_taskcard";
+ }
+
+ public static class Tp {
+ public static final String JSCODE_TO_SESSION = "/cgi-bin/service/miniprogram/jscode2session";
+ public static final String GET_CORP_TOKEN = "/cgi-bin/service/get_corp_token";
+ public static final String GET_PERMANENT_CODE = "/cgi-bin/service/get_permanent_code";
+ public static final String GET_SUITE_TOKEN = "/cgi-bin/service/get_suite_token";
+ }
+
+ public static class User {
+ public static final String USER_AUTHENTICATE = "/cgi-bin/user/authsucc?userid=";
+ public static final String USER_CREATE = "/cgi-bin/user/create";
+ public static final String USER_UPDATE = "/cgi-bin/user/update";
+ public static final String USER_DELETE = "/cgi-bin/user/delete?userid=";
+ public static final String USER_BATCH_DELETE = "/cgi-bin/user/batchdelete";
+ public static final String USER_GET = "/cgi-bin/user/get?userid=";
+ public static final String USER_LIST = "/cgi-bin/user/list?department_id=";
+ public static final String USER_SIMPLE_LIST = "/cgi-bin/user/simplelist?department_id=";
+ public static final String BATCH_INVITE = "/cgi-bin/batch/invite";
+ public static final String USER_CONVERT_TO_OPENID = "/cgi-bin/user/convert_to_openid";
+ public static final String USER_CONVERT_TO_USERID = "/cgi-bin/user/convert_to_userid";
+ public static final String GET_USER_ID = "/cgi-bin/user/getuserid";
+ public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid=";
+ }
+
+ public static class ExternalContact {
+ public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid=";
+ public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid=";
+ public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list";
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
similarity index 87%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
index 87892ecc..aa4eded4 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.cp;
+package me.chanjar.weixin.cp.constant;
/**
*
@@ -89,6 +89,26 @@ public class WxCpConsts {
*/
public static final String TASKCARD_CLICK = "taskcard_click";
+ /**
+ * 企业成员添加外部联系人事件推送
+ */
+ public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact";
+
+
+ }
+
+ /**
+ * 企业外部联系人变更事件的CHANGE_TYPE
+ */
+ public static class ExternalContactChangeType {
+ /**
+ * 新增外部联系人
+ */
+ public static final String ADD_EXTERNAL_CONTACT = "add_external_contact";
+ /**
+ * 删除外部联系人
+ */
+ public static final String DEL_EXTERNAL_CONTACT = "del_external_contact";
}
/**
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpTpCryptUtil.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpTpCryptUtil.java
new file mode 100644
index 00000000..453d1700
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpTpCryptUtil.java
@@ -0,0 +1,52 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ *
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ *
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ *
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+package me.chanjar.weixin.cp.util.crypto;
+
+import org.apache.commons.codec.binary.Base64;
+
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
+import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+
+public class WxCpTpCryptUtil extends WxCryptUtil {
+
+ /**
+ * 构造函数
+ *
+ * @param wxCpConfigStorage
+ */
+ public WxCpTpCryptUtil(WxCpTpConfigStorage wxCpTpConfigStorage) {
+ /*
+ * @param token 公众平台上,开发者设置的token
+ * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
+ * @param appidOrCorpid 公众平台corpId
+ */
+ String encodingAesKey = wxCpTpConfigStorage.getAesKey();
+ String token = wxCpTpConfigStorage.getToken();
+ String corpId = wxCpTpConfigStorage.getCorpId();
+
+ this.token = token;
+ this.appidOrCorpid = corpId;
+ this.aesKey = Base64.decodeBase64(encodingAesKey + "=");
+ }
+
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java
index 84ee7c0f..ed125c57 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java
@@ -70,6 +70,7 @@ public class WxCpUserGsonAdapter implements JsonDeserializer, JsonSeri
user.setStatus(GsonHelper.getInteger(o, "status"));
user.setEnable(GsonHelper.getInteger(o, "enable"));
user.setIsLeader(GsonHelper.getInteger(o, "isleader"));
+ user.setIsLeaderInDept(GsonHelper.getIntArray(o, "is_leader_in_dept"));
user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile"));
user.setEnglishName(GsonHelper.getString(o, "english_name"));
user.setTelephone(GsonHelper.getString(o, "telephone"));
@@ -197,6 +198,13 @@ public class WxCpUserGsonAdapter implements JsonDeserializer, JsonSeri
if (user.getIsLeader() != null) {
o.addProperty("isleader", user.getIsLeader());
}
+ if (user.getIsLeaderInDept() != null && user.getIsLeaderInDept().length > 0) {
+ JsonArray ary = new JsonArray();
+ for (int item : user.getIsLeaderInDept()) {
+ ary.add(item);
+ }
+ o.add("is_leader_in_dept", ary);
+ }
if (user.getHideMobile() != null) {
o.addProperty("hide_mobile", user.getHideMobile());
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
index 5ef1503d..3c6174c9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
@@ -1,117 +1,135 @@
-package me.chanjar.weixin.cp.util.xml;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.thoughtworks.xstream.XStream;
-import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
-
-public class XStreamTransformer {
-
- protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
-
- /**
- * xml -> pojo
- */
- @SuppressWarnings("unchecked")
- public static T fromXml(Class clazz, String xml) {
- T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
- return object;
- }
-
- @SuppressWarnings("unchecked")
- public static T fromXml(Class clazz, InputStream is) {
- T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
- return object;
- }
-
- /**
- * 注册扩展消息的解析器.
- *
- * @param clz 类型
- * @param xStream xml解析器
- */
- public static void register(Class clz, XStream xStream) {
- CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
- }
-
- /**
- * pojo -> xml.
- */
- public static String toXml(Class clazz, T object) {
- return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
- }
-
- private static Map configXStreamInstance() {
- Map map = new HashMap<>();
- map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
- map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
- map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
- map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
- map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
- map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
- return map;
- }
-
- private static XStream configWxCpXmlMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlMessage.class);
- xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
- xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
- xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
- xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutImageMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutImageMessage.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutNewsMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
- xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutTextMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutTextMessage.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutVideoMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
- xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutVoiceMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
- return xstream;
- }
-
-}
+package me.chanjar.weixin.cp.util.xml;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.XStream;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import me.chanjar.weixin.cp.bean.WxCpTpXmlMessage;
+import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
+import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
+
+public class XStreamTransformer {
+
+ protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+
+ /**
+ * xml -> pojo
+ */
+ @SuppressWarnings("unchecked")
+ public static T fromXml(Class clazz, String xml) {
+ T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
+ return object;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T fromXml(Class clazz, InputStream is) {
+ T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
+ return object;
+ }
+
+ /**
+ * 注册扩展消息的解析器.
+ *
+ * @param clz 类型
+ * @param xStream xml解析器
+ */
+ public static void register(Class clz, XStream xStream) {
+ CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
+ }
+
+ /**
+ * pojo -> xml.
+ */
+ public static String toXml(Class clazz, T object) {
+ return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
+ }
+
+ private static Map configXStreamInstance() {
+ Map map = new HashMap<>();
+ map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
+ map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
+ map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
+ map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
+ map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
+ map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
+ map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
+ map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
+ return map;
+ }
+
+ private static XStream configWxCpXmlMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlMessage.class);
+ xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutImageMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutImageMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutNewsMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
+ xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutTextMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutTextMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutVideoMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutVoiceMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpTpXmlPackage() {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxCpTpXmlPackage.class);
+
+ return xstream;
+ }
+
+ private static XStream configWxCpTpXmlMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxCpTpXmlMessage.class);
+
+ return xstream;
+ }
+
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
index c87b6455..c15e3af4 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
@@ -12,7 +12,7 @@ import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
-import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
public class ApiTestModule implements Module {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@@ -44,7 +44,7 @@ public class ApiTestModule implements Module {
}
@XStreamAlias("xml")
- public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage {
+ public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl {
protected String userId;
@@ -52,6 +52,8 @@ public class ApiTestModule implements Module {
protected String tagId;
+ protected String externalUserId;
+
public String getUserId() {
return this.userId;
}
@@ -76,12 +78,22 @@ public class ApiTestModule implements Module {
this.tagId = tagId;
}
+ public String getExternalUserId() {
+ return externalUserId;
+ }
+
+ public void setExternalUserId(String externalUserId) {
+ this.externalUserId = externalUserId;
+ }
+
@Override
public String toString() {
return super.toString() + " > WxXmlCpConfigStorage{" +
"userId='" + this.userId + '\'' +
", departmentId='" + this.departmentId + '\'' +
", tagId='" + this.tagId + '\'' +
+ ", externalUserId='" + this.externalUserId + '\'' +
+
'}';
}
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java
index 2e89e5e7..0bd8a24d 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.cp.api;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
@@ -13,8 +14,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Test
+@Slf4j
public class WxCpBusyRetryTest {
-
@DataProvider(name = "getService")
public Object[][] getService() {
WxCpService service = new WxCpServiceImpl() {
@@ -23,7 +24,7 @@ public class WxCpBusyRetryTest {
public synchronized T executeInternal(
RequestExecutor executor, String uri, E data)
throws WxErrorException {
- this.log.info("Executed");
+ log.info("Executed");
throw new WxErrorException(WxError.builder().errorCode(-1).build());
}
};
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
index 5c93f38f..d0984565 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.cp.api;
+import com.google.common.collect.ImmutableMap;
import org.testng.annotations.*;
import com.google.inject.Inject;
@@ -107,4 +108,27 @@ public class WxCpMessageAPITest {
System.out.println(messageSendResult.getInvalidUserList());
System.out.println(messageSendResult.getInvalidTagList());
}
+
+ @Test
+ public void testSendMessage_miniprogram_notice() throws WxErrorException {
+ WxCpMessage message = WxCpMessage
+ .newMiniProgramNoticeBuilder()
+ .toUser(configStorage.getUserId())
+ .appId("wx123123123123123")
+ .page("pages/index?userid=zhangsan&orderid=123123123")
+ .title("会议室预订成功通知")
+ .description("4月27日 16:16")
+ .emphasisFirstItem(true)
+ .contentItems(ImmutableMap.of("会议室","402",
+ "会议地点","广州TIT-402会议室",
+ "会议时间","2018年8月1日 09:00-09:30"))
+ .build();
+
+ WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ assertNotNull(messageSendResult);
+ System.out.println(messageSendResult);
+ System.out.println(messageSendResult.getInvalidPartyList());
+ System.out.println(messageSendResult.getInvalidUserList());
+ System.out.println(messageSendResult.getInvalidTagList());
+ }
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java
index 4ce49724..90d2f14a 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java
@@ -6,7 +6,7 @@ import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpAgentService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpAgent;
-import org.testng.Assert;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -71,7 +71,7 @@ public class WxCpAgentServiceImplTest {
@Test
public void testGet() throws Exception {
String returnJson = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\",\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\",\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}, {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]},\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]},\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0,\"isreportenter\": 0,\"home_url\": \"\"}";
- when(wxService.get("https://qyapi.weixin.qq.com/cgi-bin/agent/get?agentid=9", null)).thenReturn(returnJson);
+ when(wxService.get(String.format(wxService.getWxCpConfigStorage().getApiUrl(WxCpApiPathConsts.Agent.AGENT_GET), 9), null)).thenReturn(returnJson);
when(wxService.getAgentService()).thenReturn(new WxCpAgentServiceImpl(wxService));
WxCpAgentService wxAgentService = this.wxService.getAgentService();
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
index 4b25985f..bb4d3904 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
@@ -8,7 +8,7 @@ import org.testng.annotations.*;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.cp.WxCpConsts.AppChatMsgType;
+import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType;
import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
new file mode 100644
index 00000000..d39fd6e4
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertNotNull;
+
+@Guice(modules = ApiTestModule.class)
+public class WxCpExternalContactServiceImplTest {
+ @Inject
+ private WxCpService wxCpService;
+ @Inject
+ protected ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage;
+ private String userId = "someone" + System.currentTimeMillis();
+
+ @Test
+ public void testGetExternalContact() throws WxErrorException {
+ String externalUserId = this.configStorage.getExternalUserId();
+ WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getExternalContact(externalUserId);
+ System.out.println(result);
+ assertNotNull(result);
+ }
+
+ @Test
+ public void testListExternalContacts() throws WxErrorException {
+ String userId = this.configStorage.getUserId();
+ List ret = this.wxCpService.getExternalContactService().listExternalContacts(userId);
+ System.out.println(ret);
+ assertNotNull(ret);
+ }
+
+ @Test
+ public void testListExternalWithPermission() throws WxErrorException {
+ List ret = this.wxCpService.getExternalContactService().listFollowUser();
+ System.out.println(ret);
+ assertNotNull(ret);
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java
index 21801e4b..4df87563 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java
@@ -4,10 +4,13 @@ import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import me.chanjar.weixin.cp.bean.WxCpUserDetail;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
+import static org.assertj.core.api.Assertions.assertThat;
+
/**
*
* Created by BinaryWang on 2018/4/22.
@@ -28,6 +31,13 @@ public class WxCpOAuth2ServiceImplTest {
@Test
public void testGetUserInfo() throws WxErrorException {
- this.wxService.getOauth2Service().getUserInfo("abc");
+ final WxCpOauth2UserInfo result = this.wxService.getOauth2Service().getUserInfo("abc");
+ assertThat(result).isNotNull();
+ System.out.println(result);
}
+
+ @Test
+ public void testBuildAuthorizationUrl() {
+ }
+
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
similarity index 97%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
index 9497a562..4810cd81 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
@@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @date 2019-04-20 13:46
*/
@Guice(modules = ApiTestModule.class)
-public class WxCpOAServiceImplTest {
+public class WxCpOaServiceImplTest {
@Inject
protected WxCpService wxService;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java
index 5a6e8cca..8d21bf17 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java
@@ -10,6 +10,7 @@ import me.chanjar.weixin.cp.bean.WxCpTag;
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult;
import me.chanjar.weixin.cp.bean.WxCpTagGetResult;
import me.chanjar.weixin.cp.bean.WxCpUser;
+import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -22,10 +23,10 @@ import static org.testng.Assert.assertNotEquals;
/**
*
- *
* Created by Binary Wang on 2017-6-25.
- * @author Binary Wang
*
+ *
+ * @author Binary Wang
*/
@Guice(modules = ApiTestModule.class)
public class WxCpTagServiceImplTest {
@@ -35,7 +36,7 @@ public class WxCpTagServiceImplTest {
@Inject
protected ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage;
- protected String tagId;
+ private String tagId;
@Test
public void testCreate() throws Exception {
@@ -83,7 +84,7 @@ public class WxCpTagServiceImplTest {
public void testGet() throws WxErrorException {
String apiResultJson = "{\"errcode\": 0,\"errmsg\": \"ok\",\"userlist\": [{\"userid\": \"0124035\",\"name\": \"王五\"},{\"userid\": \"0114035\",\"name\": \"梦雪\"}],\"partylist\": [9576,9567,9566],\"tagname\": \"测试标签-001\"}";
WxCpService wxService = mock(WxCpService.class);
- when(wxService.get("https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagId=150", null)).thenReturn(apiResultJson);
+ when(wxService.get(String.format(wxService.getWxCpConfigStorage().getApiUrl(WxCpApiPathConsts.Tag.TAG_GET), 150), null)).thenReturn(apiResultJson);
when(wxService.getTagService()).thenReturn(new WxCpTagServiceImpl(wxService));
WxCpTagService wxCpTagService = wxService.getTagService();
@@ -96,7 +97,6 @@ public class WxCpTagServiceImplTest {
assertEquals(3, wxCpTagGetResult.getPartylist().size());
assertEquals("测试标签-001", wxCpTagGetResult.getTagname());
-
}
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
index 2ec33e7b..23c86768 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
@@ -93,7 +93,7 @@ public class WxCpUserServiceImplTest {
@Test
public void testInvite() throws Exception {
WxCpInviteResult result = this.wxCpService.getUserService().invite(
- Lists.newArrayList(userId), null,null);
+ Lists.newArrayList(userId), null, null);
System.out.println(result);
}
@@ -111,10 +111,15 @@ public class WxCpUserServiceImplTest {
assertNotNull(result);
}
+
@Test
- public void testGetExternalContact() throws WxErrorException {
- WxCpUserExternalContactInfo result = this.wxCpService.getUserService().getExternalContact(userId);
+ public void testGetUserId() throws WxErrorException {
+ String result = this.wxCpService.getUserService().getUserId("xxx");
System.out.println(result);
assertNotNull(result);
}
+
+ @Test
+ public void testGetExternalContact() {
+ }
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
index 89c0396e..e6efa043 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
@@ -1,9 +1,10 @@
package me.chanjar.weixin.cp.bean;
import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.cp.constant.WxCpConsts;
import org.testng.annotations.Test;
-import static me.chanjar.weixin.cp.WxCpConsts.EventType.TASKCARD_CLICK;
+import static me.chanjar.weixin.cp.constant.WxCpConsts.EventType.TASKCARD_CLICK;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -106,7 +107,7 @@ public class WxCpXmlMessageTest {
"2 " +
"" +
"
+ * 详情请见:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/plugin-management/pluginManager.applyPlugin.html + * 或者:https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Mini_Programs/Plug-ins_Management.html + */ +public interface WxMaPluginService { + + String PLUGIN_URL = "https://api.weixin.qq.com/wxa/plugin"; + + /** + * 向插件开发者发起使用插件的申请 + * + * @param pluginAppId 插件 appId + * @param reason 申请使用理由 + * @throws WxErrorException 异常 + */ + void applyPlugin(String pluginAppId, String reason) throws WxErrorException; + + /** + * 查询已添加的插件 + * + * @return + * @throws WxErrorException + */ + WxMaPluginListResult getPluginList() throws WxErrorException; + + /** + * 删除已添加的插件 + * + * @param pluginAppId 插件 appId + * @throws WxErrorException + */ + void unbindPlugin(String pluginAppId) throws WxErrorException; + + /** + * 快速更新插件版本号(第三方平台代小程序管理插件) + * + * @param pluginAppId 插件 appid + * @param userVersion 升级至版本号,要求此插件版本支持快速更新 + * @throws WxErrorException + */ + void updatePlugin(String pluginAppId, String userVersion) 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 578acc56..52988f36 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 @@ -207,6 +207,13 @@ public interface WxMaService { */ WxMaSecCheckService getSecCheckService(); + /** + * 返回插件相关接口服务对象. + * + * @return WxMaPluginService + */ + WxMaPluginService getPluginService(); + /** * 初始化http请求对象. */ diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java index a4abdc04..3b7abeeb 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java @@ -13,11 +13,14 @@ import java.util.Map; * @author Binary Wang */ public interface WxMaUserService { + String SET_USER_STORAGE = "https://api.weixin.qq.com/wxa/set_user_storage?appid=%s&signature=%s&openid=%s&sig_method=%s"; /** * 获取登录后的session信息. * * @param jsCode 登录时获取的 code + * @return . + * @throws WxErrorException . */ WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException; @@ -34,9 +37,11 @@ public interface WxMaUserService { * 上报用户数据后台接口. *
小游戏可以通过本接口上报key-value数据到用户的CloudStorage。
* 文档参考https://developers.weixin.qq.com/minigame/dev/document/open-api/data/setUserStorage.html - * @param kvMap 要上报的数据 + * + * @param kvMap 要上报的数据 * @param sessionKey 通过wx.login 获得的登录态 - * @param openid + * @param openid . + * @throws WxErrorException . */ void setUserStorage(Map+ * 需要引入依赖jedis-lock,才能使用该类。 + *+ * + * @author winter + */ +public class WxMaRedisConfigImpl implements WxMaConfig { + private static final String ACCESS_TOKEN = "accessToken"; + private static final String JSAPI_TICKET = "jsapiTicket"; + private static final String CARD_API_TICKET = "cardApiTicket"; + + private static final String HASH_VALUE_FIELD = "value"; + private static final String HASH_EXPIRE_FIELD = "expire"; + + private JedisPool jedisPool; + /** + * 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复. + */ + private String maId; + + private volatile String msgDataFormat; + protected volatile String appid; + private volatile String secret; + protected volatile String token; + private volatile String aesKey; + + private volatile String httpProxyHost; + private volatile int httpProxyPort; + private volatile String httpProxyUsername; + private volatile String httpProxyPassword; + + private Lock accessTokenLock; + private Lock jsapiTicketLock; + private Lock cardApiTicketLock; + + /** + * 临时文件目录. + */ + protected volatile File tmpDirFile; + + private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; + + private String getRedisKey(String key) { + StringBuilder redisKey = new StringBuilder("maConfig:"); + if (maId == null) { + return redisKey.append(key).toString(); + } else { + return redisKey.append(maId).append(":").append(key).toString(); + } + } + + private String getValueFromRedis(String key) { + try (Jedis jedis = jedisPool.getResource()) { + return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); + } + } + + private void setValueToRedis(String key, long expiresTime, String value) { + try (Jedis jedis = jedisPool.getResource()) { + Map
- * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker}
- * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker}
- *
- */
- public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker) {
- this.messageDuplicateChecker = messageDuplicateChecker;
- }
-
/**
*
* 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager}
@@ -93,16 +80,16 @@ public class WxMaMessageRouter {
}
/**
- * 开始一个新的Route规则
+ * 开始一个新的Route规则.
*/
public WxMaMessageRouterRule rule() {
return new WxMaMessageRouterRule(this);
}
/**
- * 处理微信消息
+ * 处理微信消息.
*/
- public void route(final WxMaMessage wxMessage, final Map context) {
+ private WxMaXmlOutMessage route(final WxMaMessage wxMessage, final Map context) {
final List matchRules = new ArrayList<>();
// 收集匹配的规则
for (final WxMaMessageRouterRule rule : this.rules) {
@@ -115,10 +102,11 @@ public class WxMaMessageRouter {
}
if (matchRules.size() == 0) {
- return;
+ return null;
}
final List> futures = new ArrayList<>();
+ WxMaXmlOutMessage result = null;
for (final WxMaMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果
if (rule.isAsync()) {
@@ -131,7 +119,7 @@ public class WxMaMessageRouter {
})
);
} else {
- rule.service(wxMessage, context, this.wxMaService, this.sessionManager, this.exceptionHandler);
+ result = rule.service(wxMessage, context, this.wxMaService, this.sessionManager, this.exceptionHandler);
// 在同步操作结束,session访问结束
this.log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUser());
sessionEndAccess(wxMessage);
@@ -155,18 +143,17 @@ public class WxMaMessageRouter {
}
});
}
-
+ return result;
}
- public void route(final WxMaMessage wxMessage) {
- this.route(wxMessage, new HashMap(2));
+ public WxMaXmlOutMessage route(final WxMaMessage wxMessage) {
+ return this.route(wxMessage, new HashMap(2));
}
/**
- * 对session的访问结束
+ * 对session的访问结束.
*/
- protected void sessionEndAccess(WxMaMessage wxMessage) {
-
+ private void sessionEndAccess(WxMaMessage wxMessage) {
InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getFromUser());
if (session != null) {
session.endAccess();
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java
index 2e4906eb..5ea3fb8a 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java
@@ -16,7 +16,6 @@ import java.util.regex.Pattern;
* @author Binary Wang
*/
public class WxMaMessageRouterRule {
-
private final WxMaMessageRouter routerBuilder;
private boolean async = true;
@@ -46,7 +45,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 设置是否异步执行,默认是true
+ * 设置是否异步执行,默认是true.
*/
public WxMaMessageRouterRule async(boolean async) {
this.async = async;
@@ -54,7 +53,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果msgType等于某值
+ * 如果msgType等于某值.
*/
public WxMaMessageRouterRule msgType(String msgType) {
this.msgType = msgType;
@@ -62,7 +61,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果event等于某值
+ * 如果event等于某值.
*/
public WxMaMessageRouterRule event(String event) {
this.event = event;
@@ -70,7 +69,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果eventKey等于某值
+ * 如果eventKey等于某值.
*/
public WxMaMessageRouterRule eventKey(String eventKey) {
this.eventKey = eventKey;
@@ -78,7 +77,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果content等于某值
+ * 如果content等于某值.
*/
public WxMaMessageRouterRule content(String content) {
this.content = content;
@@ -86,7 +85,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果content匹配该正则表达式
+ * 如果content匹配该正则表达式.
*/
public WxMaMessageRouterRule rContent(String regex) {
this.rContent = regex;
@@ -94,7 +93,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果fromUser等于某值
+ * 如果fromUser等于某值.
*/
public WxMaMessageRouterRule fromUser(String fromUser) {
this.fromUser = fromUser;
@@ -102,7 +101,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候
+ * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候.
*/
public WxMaMessageRouterRule matcher(WxMaMessageMatcher matcher) {
this.matcher = matcher;
@@ -110,14 +109,14 @@ public class WxMaMessageRouterRule {
}
/**
- * 设置微信消息拦截器
+ * 设置微信消息拦截器.
*/
public WxMaMessageRouterRule interceptor(WxMaMessageInterceptor interceptor) {
return interceptor(interceptor, (WxMaMessageInterceptor[]) null);
}
/**
- * 设置微信消息拦截器
+ * 设置微信消息拦截器.
*/
public WxMaMessageRouterRule interceptor(WxMaMessageInterceptor interceptor, WxMaMessageInterceptor... otherInterceptors) {
this.interceptors.add(interceptor);
@@ -130,14 +129,14 @@ public class WxMaMessageRouterRule {
}
/**
- * 设置微信消息处理器
+ * 设置微信消息处理器.
*/
public WxMaMessageRouterRule handler(WxMaMessageHandler handler) {
return handler(handler, (WxMaMessageHandler[]) null);
}
/**
- * 设置微信消息处理器
+ * 设置微信消息处理器.
*/
public WxMaMessageRouterRule handler(WxMaMessageHandler handler, WxMaMessageHandler... otherHandlers) {
this.handlers.add(handler);
@@ -150,7 +149,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则
+ * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则.
*/
public WxMaMessageRouter end() {
this.routerBuilder.getRules().add(this);
@@ -158,7 +157,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 规则结束,但是消息还会进入其他规则
+ * 规则结束,但是消息还会进入其他规则.
*/
public WxMaMessageRouter next() {
this.reEnter = true;
@@ -166,7 +165,7 @@ public class WxMaMessageRouterRule {
}
/**
- * 将微信自定义的事件修正为不区分大小写,
+ * 将微信自定义的事件修正为不区分大小写.
* 比如框架定义的事件常量为click,但微信传递过来的却是CLICK
*/
protected boolean test(WxMaMessage wxMessage) {
@@ -188,9 +187,9 @@ public class WxMaMessageRouterRule {
}
/**
- * 处理微信推送过来的消息
+ * 处理微信推送过来的消息.
*/
- protected void service(WxMaMessage wxMessage,
+ protected WxMaXmlOutMessage service(WxMaMessage wxMessage,
Map context,
WxMaService wxMaService,
WxSessionManager sessionManager,
@@ -199,11 +198,12 @@ public class WxMaMessageRouterRule {
context = new HashMap<>(16);
}
+ WxMaXmlOutMessage outMessage = null;
try {
// 如果拦截器不通过
for (WxMaMessageInterceptor interceptor : this.interceptors) {
if (!interceptor.intercept(wxMessage, context, wxMaService, sessionManager)) {
- return;
+ return null;
}
}
@@ -213,11 +213,13 @@ public class WxMaMessageRouterRule {
if (handler == null) {
continue;
}
- handler.handle(wxMessage, context, wxMaService, sessionManager);
+ outMessage = handler.handle(wxMessage, context, wxMaService, sessionManager);
}
} catch (WxErrorException e) {
exceptionHandler.handle(e);
}
+
+ return outMessage;
}
public WxMaMessageRouter getRouterBuilder() {
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaXmlOutMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaXmlOutMessage.java
new file mode 100644
index 00000000..7211e053
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaXmlOutMessage.java
@@ -0,0 +1,60 @@
+package cn.binarywang.wx.miniapp.message;
+
+import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
+import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
+
+import java.io.Serializable;
+
+/**
+ * 微信小程序输出给微信服务器的消息.
+ *
+ * @author Binary Wang
+ * @date 2019-06-22
+ */
+@Data
+@XStreamAlias("xml")
+@Accessors(chain = true)
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class WxMaXmlOutMessage implements Serializable {
+ private static final long serialVersionUID = 4241135225946919153L;
+
+ @XStreamAlias("ToUserName")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String toUserName;
+
+ @XStreamAlias("FromUserName")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String fromUserName;
+
+ @XStreamAlias("CreateTime")
+ protected Long createTime;
+
+ @XStreamAlias("MsgType")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ protected String msgType;
+
+ @SuppressWarnings("unchecked")
+ public String toXml() {
+ return XStreamTransformer.toXml((Class) this.getClass(), this);
+ }
+
+ /**
+ * 转换成加密的xml格式.
+ */
+ public String toEncryptedXml(WxMaConfig config) {
+ String plainXml = toXml();
+ WxMaCryptUtils pc = new WxMaCryptUtils(config);
+ return pc.encrypt(plainXml);
+ }
+}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaPluginServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaPluginServiceImplTest.java
new file mode 100644
index 00000000..ef5882e8
--- /dev/null
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaPluginServiceImplTest.java
@@ -0,0 +1,39 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaPluginListResult;
+import cn.binarywang.wx.miniapp.test.ApiTestModule;
+import com.google.inject.Inject;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertNotNull;
+
+@Test
+@Guice(modules = ApiTestModule.class)
+public class WxMaPluginServiceImplTest {
+ @Inject
+ private WxMaService wxService;
+
+ @Test
+ public void testApplyPlugin() throws Exception {
+ this.wxService.getPluginService().applyPlugin("wx4418e3e031e551be", null);
+ }
+
+ @Test
+ public void testGetPluginList() throws Exception {
+ WxMaPluginListResult result = this.wxService.getPluginService().getPluginList();
+ assertNotNull(result);
+ System.out.println(result.toString());
+ }
+
+ @Test
+ public void testUnbindPlugin() throws Exception {
+ this.wxService.getPluginService().unbindPlugin("wx4418e3e031e551be");
+ }
+
+ @Test
+ public void testUpdatePlugin() throws Exception {
+ this.wxService.getPluginService().updatePlugin("wx4418e3e031e551be", "2.0.2");
+ }
+}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java
index fe886f4b..89df2444 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java
@@ -1,15 +1,5 @@
package cn.binarywang.wx.miniapp.demo;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
@@ -20,11 +10,23 @@ import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
+import cn.binarywang.wx.miniapp.message.WxMaXmlOutMessage;
import cn.binarywang.wx.miniapp.test.TestConfig;
import com.google.common.collect.Lists;
+import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
/**
* @author Binary Wang
@@ -33,29 +35,31 @@ public class WxMaDemoServer {
private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() {
@Override
- public void handle(WxMaMessage wxMessage, Map context,
- WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
+ public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map context,
+ WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
System.out.println("收到消息:" + wxMessage.toString());
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
.toUser(wxMessage.getFromUser()).build());
+ return null;
}
};
private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() {
@Override
- public void handle(WxMaMessage wxMessage, Map context,
- WxMaService service, WxSessionManager sessionManager)
+ public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map context,
+ WxMaService service, WxSessionManager sessionManager)
throws WxErrorException {
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
.toUser(wxMessage.getFromUser()).build());
+ return null;
}
};
private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() {
@Override
- public void handle(WxMaMessage wxMessage, Map context,
- WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
+ public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map context,
+ WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
WxMediaUploadResult uploadResult = service.getMediaService()
.uploadMedia(WxMaConstants.MediaType.IMAGE, "png",
@@ -69,13 +73,14 @@ public class WxMaDemoServer {
} catch (WxErrorException e) {
e.printStackTrace();
}
+ return null;
}
};
private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() {
@Override
- public void handle(WxMaMessage wxMessage, Map context,
- WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
+ public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map context,
+ WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
final File file = service.getQrcodeService().createQrcode("123", 430);
WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file);
@@ -88,13 +93,14 @@ public class WxMaDemoServer {
} catch (WxErrorException e) {
e.printStackTrace();
}
+ return null;
}
};
private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() {
@Override
- public void handle(WxMaMessage wxMessage, Map context,
- WxMaService service, WxSessionManager sessionManager)
+ public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map context,
+ WxMaService service, WxSessionManager sessionManager)
throws WxErrorException {
service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
.templateId(templateId).data(Lists.newArrayList(
@@ -102,10 +108,22 @@ public class WxMaDemoServer {
.toUser(wxMessage.getFromUser())
.formId("自己替换可用的formid")
.build());
+ return null;
}
};
+ private static final WxMaMessageHandler customerServiceMessageHandler = new WxMaMessageHandler() {
+ @Override
+ public WxMaXmlOutMessage handle(WxMaMessage message, Map context, WxMaService service, WxSessionManager sessionManager) {
+ return new WxMaXmlOutMessage()
+ .setMsgType(WxConsts.XmlMsgType.TRANSFER_CUSTOMER_SERVICE)
+ .setFromUserName(message.getToUser())
+ .setCreateTime(Calendar.getInstance().getTimeInMillis() / 1000)
+ .setToUserName(message.getFromUser());
+ }
+ };
+
private static WxMaConfig config;
private static WxMaService service;
private static WxMaMessageRouter router;
@@ -142,7 +160,8 @@ public class WxMaDemoServer {
.rule().async(false).content("模板").handler(templateMsgHandler).end()
.rule().async(false).content("文本").handler(textHandler).end()
.rule().async(false).content("图片").handler(picHandler).end()
- .rule().async(false).content("二维码").handler(qrcodeHandler).end();
+ .rule().async(false).content("二维码").handler(qrcodeHandler).end()
+ .rule().async(false).content("转发客服").handler(customerServiceMessageHandler).end();
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaPortalServlet.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaPortalServlet.java
index 5cadb689..c209082d 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaPortalServlet.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaPortalServlet.java
@@ -5,6 +5,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
+import cn.binarywang.wx.miniapp.message.WxMaXmlOutMessage;
+import lombok.AllArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -18,19 +20,13 @@ import java.util.Objects;
/**
* @author Binary Wang
*/
+@AllArgsConstructor
public class WxMaPortalServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
- private WxMaConfig wxMaConfig;
- private WxMaService wxMaService;
- private WxMaMessageRouter wxMaMessageRouter;
-
- WxMaPortalServlet(WxMaConfig wxMaConfig, WxMaService wxMaService,
- WxMaMessageRouter wxMaMessageRouter) {
- this.wxMaConfig = wxMaConfig;
- this.wxMaService = wxMaService;
- this.wxMaMessageRouter = wxMaMessageRouter;
- }
+ private WxMaConfig config;
+ private WxMaService service;
+ private WxMaMessageRouter messageRouter;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
@@ -42,7 +38,7 @@ public class WxMaPortalServlet extends HttpServlet {
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
- if (!this.wxMaService.checkSignature(timestamp, nonce, signature)) {
+ if (!this.service.checkSignature(timestamp, nonce, signature)) {
// 消息签名不正确,说明不是公众平台发过来的消息
response.getWriter().println("非法请求");
return;
@@ -56,7 +52,7 @@ public class WxMaPortalServlet extends HttpServlet {
}
String encryptType = request.getParameter("encrypt_type");
- final boolean isJson = Objects.equals(this.wxMaConfig.getMsgDataFormat(), WxMaConstants.MsgDataFormat.JSON);
+ final boolean isJson = Objects.equals(this.config.getMsgDataFormat(), WxMaConstants.MsgDataFormat.JSON);
if (StringUtils.isBlank(encryptType)) {
// 明文传输的消息
WxMaMessage inMessage;
@@ -66,7 +62,12 @@ public class WxMaPortalServlet extends HttpServlet {
inMessage = WxMaMessage.fromXml(request.getInputStream());
}
- this.wxMaMessageRouter.route(inMessage);
+ final WxMaXmlOutMessage outMessage = this.messageRouter.route(inMessage);
+ if (outMessage != null) {
+ response.getWriter().write(outMessage.toXml());
+ return;
+ }
+
response.getWriter().write("success");
return;
}
@@ -76,12 +77,16 @@ public class WxMaPortalServlet extends HttpServlet {
String msgSignature = request.getParameter("msg_signature");
WxMaMessage inMessage;
if (isJson) {
- inMessage = WxMaMessage.fromEncryptedJson(request.getInputStream(), this.wxMaConfig);
+ inMessage = WxMaMessage.fromEncryptedJson(request.getInputStream(), this.config);
} else {//xml
- inMessage = WxMaMessage.fromEncryptedXml(request.getInputStream(), this.wxMaConfig, timestamp, nonce, msgSignature);
+ inMessage = WxMaMessage.fromEncryptedXml(request.getInputStream(), this.config, timestamp, nonce, msgSignature);
}
- this.wxMaMessageRouter.route(inMessage);
+ final WxMaXmlOutMessage outMessage = this.messageRouter.route(inMessage);
+ if (outMessage != null) {
+ response.getWriter().write(outMessage.toEncryptedXml(this.config));
+ return;
+ }
response.getWriter().write("success");
return;
}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java
index 6cebdeb2..a9dd4656 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java
@@ -1,6 +1,6 @@
package cn.binarywang.wx.miniapp.test;
-import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
+import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
@@ -13,7 +13,7 @@ import java.util.concurrent.locks.Lock;
* @author Binary Wang
*/
@XStreamAlias("xml")
-public class TestConfig extends WxMaInMemoryConfig {
+public class TestConfig extends WxMaDefaultConfigImpl {
private String openid;
private String kfAccount;
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index ed8c7e75..8792a55e 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 3.4.0
+ 3.5.0
weixin-java-mp
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java
index c57ad9d0..230910e8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java
@@ -15,9 +15,6 @@ import me.chanjar.weixin.mp.enums.AiLangType;
* @author Binary Wang
*/
public interface WxMpAiOpenService {
- String TRANSLATE_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?lfrom=%s<o=%s";
- String VOICE_UPLOAD_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?format=%s&voice_id=%s&lang=%s";
- String VOICE_QUERY_RESULT_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext";
/**
*
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
index 66aeccad..f5131e8f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
@@ -3,51 +3,33 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.card.*;
-import me.chanjar.weixin.mp.bean.card.WxMpCardResult;
/**
- * 卡券相关接口
+ * 卡券相关接口.
*
* @author YuJian(mgcnrx11 @ hotmail.com) on 01/11/2016
* @author yuanqixun 2018-08-29
*/
public interface WxMpCardService {
- String CARD_CREATE = "https://api.weixin.qq.com/card/create";
- String CARD_GET = "https://api.weixin.qq.com/card/get";
- String CARD_GET_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
- String CARD_CODE_DECRYPT = "https://api.weixin.qq.com/card/code/decrypt";
- String CARD_CODE_GET = "https://api.weixin.qq.com/card/code/get";
- String CARD_CODE_CONSUME = "https://api.weixin.qq.com/card/code/consume";
- String CARD_CODE_MARK = "https://api.weixin.qq.com/card/code/mark";
- String CARD_TEST_WHITELIST = "https://api.weixin.qq.com/card/testwhitelist/set";
- String CARD_QRCODE_CREATE = "https://api.weixin.qq.com/card/qrcode/create";
- String CARD_LANDING_PAGE_CREATE = "https://api.weixin.qq.com/card/landingpage/create";
/**
- * 将用户的卡券设置为失效状态
- */
- String CARD_CODE_UNAVAILABLE = "https://api.weixin.qq.com/card/code/unavailable";
-
- /**
- * 卡券删除
- */
- String CARD_DELETE = "https://api.weixin.qq.com/card/delete";
-
- /**
- * 得到WxMpService
+ * 得到WxMpService.
+ *
+ * @return WxMpService
*/
WxMpService getWxMpService();
/**
- * 获得卡券api_ticket,不强制刷新卡券api_ticket
+ * 获得卡券api_ticket,不强制刷新卡券api_ticket.
*
* @return 卡券api_ticket
+ * @throws WxErrorException 异常
* @see #getCardApiTicket(boolean)
*/
String getCardApiTicket() throws WxErrorException;
/**
*
- * 获得卡券api_ticket
+ * 获得卡券api_ticket.
* 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94.9F.E6.88.90.E7.AE.97.E6.B3.95
@@ -55,67 +37,68 @@ public interface WxMpCardService {
*
* @param forceRefresh 强制刷新
* @return 卡券api_ticket
- * @throws WxErrorException
+ * @throws WxErrorException 异常
*/
String getCardApiTicket(boolean forceRefresh) throws WxErrorException;
/**
*
- * 创建调用卡券api时所需要的签名
+ * 创建调用卡券api时所需要的签名.
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
* .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
* .9F.E6.88.90.E7.AE.97.E6.B3.95
*
*
- * @param optionalSignParam 参与签名的参数数组。
- * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
+ * @param optionalSignParam 参与签名的参数数组。可以为下列字段:app_id, card_id, card_type, code, openid, location_id
* 注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空
* @return 卡券Api签名对象
+ * @throws WxErrorException 异常
*/
- WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws
- WxErrorException;
+ WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws WxErrorException;
/**
- * 卡券Code解码
+ * 卡券Code解码.
*
* @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得
* @return 解密后的Code
+ * @throws WxErrorException 异常
*/
String decryptCardCode(String encryptCode) throws WxErrorException;
/**
* 卡券Code查询.
* 文档地址: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=1
+ *
* @param cardId 卡券ID代表一类卡券
* @param code 单张卡券的唯一标准
* @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同
* @return WxMpCardResult对象
+ * @throws WxErrorException 异常
*/
- WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume)
- throws WxErrorException;
+ WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException;
/**
* 卡券Code核销。核销失败会抛出异常
*
* @param code 单张卡券的唯一标准
- * @return 调用返回的JSON字符串。
- *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
+ * @return 调用返回的JSON字符串。可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
+ * @throws WxErrorException 异常
*/
String consumeCardCode(String code) throws WxErrorException;
/**
- * 卡券Code核销。核销失败会抛出异常
+ * 卡券Code核销。核销失败会抛出异常.
*
* @param code 单张卡券的唯一标准
* @param cardId 当自定义Code卡券时需要传入card_id
- * @return 调用返回的JSON字符串。
- *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
+ * @return 调用返回的JSON字符串。可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
+ * @throws WxErrorException 异常
*/
String consumeCardCode(String code, String cardId) throws WxErrorException;
/**
- * 卡券Mark接口。
+ * 卡券Mark接口.
* 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住),
* 才能进一步调用核销接口,否则报错。
*
@@ -123,82 +106,103 @@ public interface WxMpCardService {
* @param cardId 卡券的ID
* @param openId 用券用户的openid
* @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用
+ * @throws WxErrorException 异常
*/
- void markCardCode(String code, String cardId, String openId, boolean isMark) throws
- WxErrorException;
+ void markCardCode(String code, String cardId, String openId, boolean isMark) throws WxErrorException;
/**
- * 查看卡券详情接口
+ * 查看卡券详情接口.
* 详见 https://mp.weixin.qq.com/wiki/14/8dd77aeaee85f922db5f8aa6386d385e.html#.E6.9F.A5.E7.9C.8B.E5.8D.A1.E5.88.B8.E8.AF.A6.E6.83.85
*
* @param cardId 卡券的ID
* @return 返回的卡券详情JSON字符串
*
[注] 由于返回的JSON格式过于复杂,难以定义其对应格式的Bean并且难以维护,因此只返回String格式的JSON串。
*
可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。
+ * @throws WxErrorException 异常
*/
String getCardDetail(String cardId) throws WxErrorException;
/**
- * 添加测试白名单
+ * 添加测试白名单.
*
* @param openid 用户的openid
- * @return
+ * @return string
+ * @throws WxErrorException 异常
*/
String addTestWhiteList(String openid) throws WxErrorException;
/**
+ * 创建卡券.
*
- * @param cardCreateMessage
- * @return
- * @throws WxErrorException
+ * @param cardCreateMessage 请求
+ * @return result
+ * @throws WxErrorException 异常
*/
WxMpCardCreateResult createCard(WxMpCardCreateMessage cardCreateMessage) throws WxErrorException;
/**
- * 创建卡券二维码
+ * 创建卡券二维码.
*
* @param cardId 卡券编号
* @param outerStr 二维码标识
* @return WxMpCardQrcodeCreateResult
+ * @throws WxErrorException 异常
*/
WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException;
/**
- * 创建卡券二维码
+ * 创建卡券二维码.
*
* @param cardId 卡券编号
* @param outerStr 二维码标识
- * @param expiresIn 失效时间,单位秒,不填默认365天
+ * @param expiresIn 指定二维码的有效时间,范围是60 ~ 1800秒。不填默认为365天有效
* @return WxMpCardQrcodeCreateResult
+ * @throws WxErrorException 异常
*/
WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn) throws WxErrorException;
/**
- * 创建卡券货架
+ * 创建卡券二维码.
+ *
+ * @param cardId 卡券编号
+ * @param outerStr 用户首次领卡时,会通过 领取事件推送 给商户; 对于会员卡的二维码,用户每次扫码打开会员卡后点击任何url,会将该值拼入url中,方便开发者定位扫码来源
+ * @param expiresIn 指定二维码的有效时间,范围是60 ~ 1800秒。不填默认为365天有效
+ * @param isUniqueCode 指定下发二维码,生成的二维码随机分配一个code,领取后不可再次扫描。填写true或false。默认false,注意填写该字段时,卡券须通过审核且库存不为0。
+ * @param code 卡券Code码,use_custom_code字段为true的卡券必须填写,非自定义code和导入code模式的卡券不必填写。
+ * @param openid 指定领取者的openid,只有该用户能领取。bind_openid字段为true的卡券必须填写,非指定openid不必填写。
+ * @return WxMpCardQrcodeCreateResult
+ * @throws WxErrorException 异常
+ */
+ WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn, String openid,
+ String code, boolean isUniqueCode) throws WxErrorException;
+
+ /**
+ * 创建卡券货架.
*
* @param createRequest 货架创建参数
- * @return
- * @throws WxErrorException
+ * @return WxMpCardLandingPageCreateResult
+ * @throws WxErrorException 异常
*/
WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest createRequest) throws WxErrorException;
/**
- * 将用户的卡券设置为失效状态
+ * 将用户的卡券设置为失效状态.
* 详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=9
*
* @param cardId 卡券编号
* @param code 用户会员卡号
* @param reason 设置为失效的原因
- * @return
- * @throws WxErrorException
+ * @return result
+ * @throws WxErrorException 异常
*/
String unavailableCardCode(String cardId, String code, String reason) throws WxErrorException;
/**
- * 删除卡券接口
- * @param cardId
- * @return
- * @throws WxErrorException
+ * 删除卡券接口.
+ *
+ * @param cardId 卡券id
+ * @return 删除结果
+ * @throws WxErrorException 异常
*/
WxMpCardDeleteResult deleteCard(String cardId) throws WxErrorException;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java
new file mode 100644
index 00000000..2ba7a092
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.mp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 评论数据管理.
+ *
+ * @author Binary Wang
+ * @date 2019-06-16
+ */
+public interface WxMpCommentService {
+ /**
+ * 打开已群发文章评论.
+ * https://api.weixin.qq.com/cgi-bin/comment/open?access_token=ACCESS_TOKEN
+ * 参数 是否必须 类型 说明
+ *
+ * @param msgDataId 群发返回的msg_data_id
+ * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
+ * @throws WxErrorException 异常
+ */
+ void open(Integer msgDataId, Integer index) throws WxErrorException;
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java
index fecceea4..c1b35bee 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java
@@ -13,24 +13,6 @@ import java.util.List;
* @author binarywang (https://github.com/binarywang)
*/
public interface WxMpDataCubeService {
- String GET_USER_SUMMARY = "https://api.weixin.qq.com/datacube/getusersummary";
- String GET_USER_CUMULATE = "https://api.weixin.qq.com/datacube/getusercumulate";
- String GET_ARTICLE_SUMMARY = "https://api.weixin.qq.com/datacube/getarticlesummary";
- String GET_ARTICLE_TOTAL = "https://api.weixin.qq.com/datacube/getarticletotal";
- String GET_USER_READ = "https://api.weixin.qq.com/datacube/getuserread";
- String GET_USER_READ_HOUR = "https://api.weixin.qq.com/datacube/getuserreadhour";
- String GET_USER_SHARE = "https://api.weixin.qq.com/datacube/getusershare";
- String GET_USER_SHARE_HOUR = "https://api.weixin.qq.com/datacube/getusersharehour";
- String GET_UPSTREAM_MSG = "https://api.weixin.qq.com/datacube/getupstreammsg";
- String GET_UPSTREAM_MSG_HOUR = "https://api.weixin.qq.com/datacube/getupstreammsghour";
- String GET_UPSTREAM_MSG_WEEK = "https://api.weixin.qq.com/datacube/getupstreammsgweek";
- String GET_UPSTREAM_MSG_MONTH = "https://api.weixin.qq.com/datacube/getupstreammsgmonth";
- String GET_UPSTREAM_MSG_DIST = "https://api.weixin.qq.com/datacube/getupstreammsgdist";
- String GET_UPSTREAM_MSG_DIST_WEEK = "https://api.weixin.qq.com/datacube/getupstreammsgdistweek";
- String GET_UPSTREAM_MSG_DIST_MONTH = "https://api.weixin.qq.com/datacube/getupstreammsgdistmonth";
- String GET_INTERFACE_SUMMARY = "https://api.weixin.qq.com/datacube/getinterfacesummary";
- String GET_INTERFACE_SUMMARY_HOUR = "https://api.weixin.qq.com/datacube/getinterfacesummaryhour";
-
//*******************用户分析数据接口***********************//
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java
index 8a0fb6a5..c2ccef5a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java
@@ -5,6 +5,8 @@ import me.chanjar.weixin.mp.bean.device.*;
/**
* Created by keungtung on 10/12/2016.
+ *
+ * @author keungtung
*/
public interface WxMpDeviceService {
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java
index 99dcaba9..3404f5fe 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java
@@ -22,22 +22,6 @@ import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
* @author Binary Wang
*/
public interface WxMpKefuService {
- String MESSAGE_CUSTOM_SEND = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
- String GET_KF_LIST = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
- String GET_ONLINE_KF_LIST = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist";
- String KFACCOUNT_ADD = "https://api.weixin.qq.com/customservice/kfaccount/add";
- String KFACCOUNT_UPDATE = "https://api.weixin.qq.com/customservice/kfaccount/update";
- String KFACCOUNT_INVITE_WORKER = "https://api.weixin.qq.com/customservice/kfaccount/inviteworker";
- String KFACCOUNT_UPLOAD_HEAD_IMG = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account=%s";
- String KFACCOUNT_DEL = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=%s";
- String KFSESSION_CREATE = "https://api.weixin.qq.com/customservice/kfsession/create";
- String KFSESSION_CLOSE = "https://api.weixin.qq.com/customservice/kfsession/close";
- String KFSESSION_GET_SESSION = "https://api.weixin.qq.com/customservice/kfsession/getsession?openid=%s";
- String KFSESSION_GET_SESSION_LIST = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist?kf_account=%s";
- String KFSESSION_GET_WAIT_CASE = "https://api.weixin.qq.com/customservice/kfsession/getwaitcase";
- String MSG_RECORD_LIST = "https://api.weixin.qq.com/customservice/msgrecord/getmsglist";
- String CUSTOM_TYPING = "https://api.weixin.qq.com/cgi-bin/message/custom/typing";
-
/**
*
* 发送客服消息
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
index f59158b2..c7daa1f9 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
@@ -11,18 +11,14 @@ import java.util.Date;
import java.util.List;
/**
- *
- * 微信营销接口
- *
+ * 微信营销接口.
*
* @author 007
*/
public interface WxMpMarketingService {
- String API_URL_PREFIX = "https://api.weixin.qq.com/marketing/";
-
/**
*
- * 创建数据源
+ * 创建数据源.
* 接口调用请求说明
* https://wximg.qq.com/wxp/pdftool/get.html?id=rkalQXDBM&pa=39
*
@@ -35,7 +31,7 @@ public interface WxMpMarketingService {
/**
*
- * 获取数据源信息
+ * 获取数据源信息.
*
*
* @param userActionSetId 数据源唯一ID
@@ -43,7 +39,7 @@ public interface WxMpMarketingService {
List getUserActionSets(Long userActionSetId) throws WxErrorException;
/**
- * 回传数据
+ * 回传数据.
* 接口调用请求说明
* https://wximg.qq.com/wxp/pdftool/get.html?id=rkalQXDBM&pa=39
*
@@ -53,7 +49,7 @@ public interface WxMpMarketingService {
/**
*
- * 获取朋友圈销售线索数据接口
+ * 获取朋友圈销售线索数据接口.
* 接口调用请求说明
*
* http请求方式: POST
@@ -65,7 +61,11 @@ public interface WxMpMarketingService {
* @param endDate 结束日期
* @param filtering 过滤条件
* @param page 页码,获取指定页数据
- * @param page_size 一页获取的数据条数(1-100)
+ * @param pageSize 一页获取的数据条数(1-100)
+ * @return .
+ * @throws WxErrorException .
+ * @throws IOException .
*/
- WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer page_size) throws WxErrorException, IOException;
+ WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer pageSize)
+ throws WxErrorException, IOException;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java
index f3e8db9d..c986e53e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java
@@ -14,31 +14,6 @@ import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
* @author Binary Wang
*/
public interface WxMpMassMessageService {
- /**
- * 上传群发用的图文消息.
- */
- String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews";
- /**
- * 上传群发用的视频.
- */
- String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo";
- /**
- * 分组群发消息.
- */
- String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall";
- /**
- * 按openId列表群发消息.
- */
- String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send";
- /**
- * 群发消息预览接口.
- */
- String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview";
- /**
- * 删除群发接口.
- */
- String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete";
-
/**
*
* 上传群发用的图文消息,上传后才能群发图文消息.
@@ -85,7 +60,8 @@ public interface WxMpMassMessageService {
/**
*
* 群发消息预览接口.
- * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
+ * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,
+ * 在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
* 接口调用请求说明
* http请求方式: POST
* https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
index 6d762f1c..686c86f2 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
@@ -22,19 +22,10 @@ import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult;
* 即以https://api.weixin.qq.com/cgi-bin/material
* 和 https://api.weixin.qq.com/cgi-bin/media开头的接口
*
+ *
+ * @author Binary Wang
*/
public interface WxMpMaterialService {
- String MEDIA_GET_URL = "https://api.weixin.qq.com/cgi-bin/media/get";
- String MEDIA_UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?type=%s";
- String IMG_UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg";
- String MATERIAL_ADD_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=%s";
- String NEWS_ADD_URL = "https://api.weixin.qq.com/cgi-bin/material/add_news";
- String MATERIAL_GET_URL = "https://api.weixin.qq.com/cgi-bin/material/get_material";
- String NEWS_UPDATE_URL = "https://api.weixin.qq.com/cgi-bin/material/update_news";
- String MATERIAL_DEL_URL = "https://api.weixin.qq.com/cgi-bin/material/del_material";
- String MATERIAL_GET_COUNT_URL = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount";
- String MATERIAL_BATCHGET_URL = "https://api.weixin.qq.com/cgi-bin/material/batchget_material";
-
/**
*
* 新增临时素材
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
index 37785365..e551f7d9 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
@@ -17,31 +17,6 @@ import me.chanjar.weixin.mp.bean.membercard.*;
* @date 2018-08-30
*/
public interface WxMpMemberCardService {
- String MEMBER_CARD_CREATE = "https://api.weixin.qq.com/card/create";
- String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate";
- String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get";
- String MEMBER_CARD_UPDATE_USER = "https://api.weixin.qq.com/card/membercard/updateuser";
- /**
- * 会员卡激活之微信开卡接口(wx_activate=true情况调用).
- */
- String MEMBER_CARD_ACTIVATE_USER_FORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set";
-
- /**
- * 获取会员卡开卡插件参数.
- */
- String MEMBER_CARD_ACTIVATE_URL = "https://api.weixin.qq.com/card/membercard/activate/geturl";
-
- /**
- * 会员卡信息更新.
- */
- String MEMBER_CARD_UPDATE = "https://api.weixin.qq.com/card/update";
-
- /**
- * 跳转型会员卡开卡字段.
- * 获取用户提交资料(wx_activate=true情况调用),开发者根据activate_ticket获取到用户填写的信息
- */
- String MEMBER_CARD_ACTIVATE_TEMP_INFO = "https://api.weixin.qq.com/card/membercard/activatetempinfo/get";
-
/**
* 得到WxMpService.
*
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
index f0fe5495..e7cef4eb 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
@@ -6,12 +6,11 @@ import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
import me.chanjar.weixin.mp.bean.menu.WxMpMenu;
/**
- * 菜单相关操作接口
+ * 菜单相关操作接口.
*
* @author Binary Wang
*/
public interface WxMpMenuService {
-
/**
*
* 自定义菜单创建接口
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
index 474e3e69..0c6912c3 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
@@ -8,18 +8,21 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import java.util.Map;
/**
- * 处理微信推送消息的处理器接口
+ * 处理微信推送消息的处理器接口.
*
* @author Daniel Qian
*/
public interface WxMpMessageHandler {
/**
- * @param wxMessage
+ * 处理微信推送消息.
+ *
+ * @param wxMessage 微信推送消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
- * @param wxMpService
- * @param sessionManager
+ * @param wxMpService 服务类
+ * @param sessionManager session管理器
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null
+ * @throws WxErrorException 异常
*/
WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map context,
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
index e85a2b65..86351e5a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
@@ -144,21 +144,21 @@ public class WxMpMessageRouter {
}
/**
- * 开始一个新的Route规则
+ * 开始一个新的Route规则.
*/
public WxMpMessageRouterRule rule() {
return new WxMpMessageRouterRule(this);
}
/**
- * 处理微信消息
+ * 处理微信消息.
*/
public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context) {
return route(wxMessage, context, null);
}
/**
- * 处理微信消息
+ * 处理微信消息.
*/
public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context, WxMpService wxMpService) {
if (wxMpService == null) {
@@ -252,7 +252,7 @@ public class WxMpMessageRouter {
}
/**
- * 对session的访问结束
+ * 对session的访问结束.
*/
protected void sessionEndAccess(WxMpXmlMessage wxMessage) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpOcrService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpOcrService.java
new file mode 100644
index 00000000..1748b553
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpOcrService.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.mp.api;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.ocr.WxMpOcrIdCardResult;
+
+import java.io.File;
+
+/**
+ * 基于小程序或 H5 的身份证、银行卡、行驶证 OCR 识别.
+ * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712284rHWMX
+ *
+ * @author Binary Wang
+ * @date 2019-06-22
+ */
+public interface WxMpOcrService {
+ @AllArgsConstructor
+ @Getter
+ enum ImageType {
+ /**
+ * 拍照模型,带背景的图片.
+ */
+ PHOTO("photo"),
+ /**
+ * 扫描模式,不带背景的图片.
+ */
+ SCAN("scan");
+
+ private String type;
+ }
+
+ /**
+ * 身份证OCR识别接口.
+ *
+ * @param imgType 图片类型
+ * @param imgUrl 图片url地址
+ * @throws WxErrorException .
+ */
+ WxMpOcrIdCardResult idCard(ImageType imgType, String imgUrl) throws WxErrorException;
+
+ /**
+ * 身份证OCR识别接口.
+ *
+ * @param imgType 图片类型
+ * @param imgFile 图片文件对象
+ * @throws WxErrorException .
+ */
+ WxMpOcrIdCardResult idCard(ImageType imgType, File imgFile) throws WxErrorException;
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
index 131ebf63..6622159d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
@@ -14,7 +14,6 @@ import java.io.File;
* @author Binary Wang
*/
public interface WxMpQrcodeService {
-
/**
*
* 换取临时二维码ticket
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
index a0452eba..be8000d3 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
@@ -5,13 +5,14 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
-import me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.enums.TicketType;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import java.util.Map;
@@ -21,61 +22,6 @@ import java.util.Map;
* @author chanjarster
*/
public interface WxMpService {
- /**
- * 获取access_token.
- */
- String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
- /**
- * 获得各种类型的ticket.
- */
- String GET_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=";
- /**
- * 长链接转短链接接口.
- */
- String SHORTURL_API_URL = "https://api.weixin.qq.com/cgi-bin/shorturl";
- /**
- * 语义查询接口.
- */
- String SEMANTIC_SEMPROXY_SEARCH_URL = "https://api.weixin.qq.com/semantic/semproxy/search";
- /**
- * 用code换取oauth2的access token.
- */
- String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
- /**
- * 刷新oauth2的access token.
- */
- String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
- /**
- * 用oauth2获取用户信息.
- */
- String OAUTH2_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=%s";
- /**
- * 验证oauth2的access token是否有效.
- */
- String OAUTH2_VALIDATE_TOKEN_URL = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s";
- /**
- * 获取微信服务器IP地址.
- */
- String GET_CALLBACK_IP_URL = "https://api.weixin.qq.com/cgi-bin/getcallbackip";
- /**
- * 第三方使用网站应用授权登录的url.
- */
- String QRCONNECT_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
- /**
- * oauth2授权的url连接.
- */
- String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&connect_redirect=1#wechat_redirect";
-
- /**
- * 获取公众号的自动回复规则.
- */
- String GET_CURRENT_AUTOREPLY_INFO_URL = "https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info";
-
- /**
- * 公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零.
- */
- String CLEAR_QUOTA_URL = "https://api.weixin.qq.com/cgi-bin/clear_quota";
-
/**
*
* 验证消息的确来自微信服务器.
@@ -158,7 +104,7 @@ public interface WxMpService {
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=长链接转短链接接口
*
*/
- String shortUrl(String long_url) throws WxErrorException;
+ String shortUrl(String longUrl) throws WxErrorException;
/**
*
@@ -264,11 +210,21 @@ public interface WxMpService {
/**
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求.
+ *
+ * @param queryParam 参数
+ * @param url 请求接口地址
+ * @return 接口响应字符串
+ * @throws WxErrorException 异常
*/
String get(String url, String queryParam) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求.
+ *
+ * @param postData 请求参数json值
+ * @param url 请求接口地址
+ * @return 接口响应字符串
+ * @throws WxErrorException 异常
*/
String post(String url, String postData) throws WxErrorException;
@@ -278,14 +234,54 @@ public interface WxMpService {
* 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
* 可以参考,{@link MediaUploadRequestExecutor}的实现方法
*
+ *
+ * @param data 参数数据
+ * @param executor 执行器
+ * @param url 接口地址
+ * @return 结果
+ * @throws WxErrorException 异常
*/
- T execute(RequestExecutor executor, String uri, E data) throws WxErrorException;
+ T execute(RequestExecutor executor, String url, E data) throws WxErrorException;
+
+ /**
+ * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求.
+ *
+ * @param queryParam 参数
+ * @param url 请求接口地址
+ * @return 接口响应字符串
+ * @throws WxErrorException 异常
+ */
+ String get(WxMpApiUrl url, String queryParam) throws WxErrorException;
+
+ /**
+ * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求.
+ *
+ * @param postData 请求参数json值
+ * @param url 请求接口地址
+ * @return 接口响应字符串
+ * @throws WxErrorException 异常
+ */
+ String post(WxMpApiUrl url, String postData) throws WxErrorException;
/**
*
+ * Service没有实现某个API的时候,可以用这个,
+ * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+ * 可以参考,{@link MediaUploadRequestExecutor}的实现方法
+ *
+ *
+ * @param data 参数数据
+ * @param executor 执行器
+ * @param url 接口地址
+ * @return 结果
+ * @throws WxErrorException 异常
+ */
+ T execute(RequestExecutor executor, WxMpApiUrl url, E data) throws WxErrorException;
+
+ /**
* 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试.
+ *
* @param retrySleepMillis 默认:1000ms
- *
*/
void setRetrySleepMillis(int retrySleepMillis);
@@ -311,12 +307,14 @@ public interface WxMpService {
/**
* {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信公众号配置
+ *
* @param configStorage 新的微信配置
*/
void addConfigStorage(String mpId, WxMpConfigStorage configStorage);
/**
* 从{@link Map} 移除 {@link String mpId} 所对应的 {@link WxMpConfigStorage},适用于动态移除微信公众号配置
+ *
* @param mpId 对应公众号的标识
*/
void removeConfigStorage(String mpId);
@@ -324,19 +322,22 @@ public interface WxMpService {
/**
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String mpId} 值
* 随机采用一个{@link String mpId}进行Http初始化操作
+ *
* @param configStorages WxMpConfigStorage map
*/
void setMultiConfigStorages(Map configStorages);
/**
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值
+ *
* @param configStorages WxMpConfigStorage map
- * @param defaultMpId 设置一个{@link WxMpConfigStorage} 所对应的{@link String mpId}进行Http初始化
+ * @param defaultMpId 设置一个{@link WxMpConfigStorage} 所对应的{@link String mpId}进行Http初始化
*/
void setMultiConfigStorages(Map configStorages, String defaultMpId);
/**
* 进行相应的公众号切换
+ *
* @param mpId 公众号标识
* @return 切换是否成功
*/
@@ -344,6 +345,7 @@ public interface WxMpService {
/**
* 进行相应的公众号切换
+ *
* @param mpId 公众号标识
* @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常
*/
@@ -492,6 +494,13 @@ public interface WxMpService {
*/
WxMpWifiService getWifiService();
+ /**
+ * 返回WIFI接口方法的实现类对象,以方便调用其各个接口.
+ *
+ * @return WxMpWifiService
+ */
+ WxMpOcrService getOcrService();
+
void setKefuService(WxMpKefuService kefuService);
void setMaterialService(WxMpMaterialService materialService);
@@ -525,4 +534,15 @@ public interface WxMpService {
void setAiOpenService(WxMpAiOpenService aiOpenService);
void setMarketingService(WxMpMarketingService marketingService);
+
+ void setOcrService(WxMpOcrService ocrService);
+
+ /**
+ * 返回评论数据管理接口方法的实现类对象,以方便调用其各个接口.
+ *
+ * @return WxMpWifiService
+ */
+ WxMpCommentService getCommentService();
+
+ void setCommentService(WxMpCommentService commentService);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java
index 1f6c3052..8c45dade 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java
@@ -7,12 +7,11 @@ import me.chanjar.weixin.mp.bean.WxMpShakeQuery;
import me.chanjar.weixin.mp.bean.shake.*;
/**
- * 摇一摇周边的相关接口
+ * 摇一摇周边的相关接口.
*
* @author rememberber
*/
public interface WxMpShakeService {
-
/**
*
* 获取设备及用户信息
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java
index 7b0913e6..82eaa5ee 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java
@@ -8,20 +8,12 @@ import me.chanjar.weixin.mp.bean.store.WxMpStoreListResult;
import java.util.List;
/**
- * 门店管理的相关接口代码
- *
+ * 门店管理的相关接口代码.
* Created by Binary Wang on 2016-09-23.
*
* @author Binary Wang
*/
public interface WxMpStoreService {
- String POI_GET_WX_CATEGORY_URL = "https://api.weixin.qq.com/cgi-bin/poi/getwxcategory";
- String POI_UPDATE_URL = "https://api.weixin.qq.com/cgi-bin/poi/updatepoi";
- String POI_LIST_URL = "https://api.weixin.qq.com/cgi-bin/poi/getpoilist";
- String POI_DEL_URL = "https://api.weixin.qq.com/cgi-bin/poi/delpoi";
- String POI_GET_URL = "https://api.weixin.qq.com/cgi-bin/poi/getpoi";
- String POI_ADD_URL = "https://api.weixin.qq.com/cgi-bin/poi/addpoi";
-
/**
*
* 创建门店
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java
index 1e91d9a2..549018e6 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java
@@ -13,7 +13,6 @@ import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;
* @date 2018-01-22 上午11:07
*/
public interface WxMpSubscribeMsgService {
-
/**
*
* 构造用户订阅一条模板消息授权的url连接
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java
index f57c469c..656840cb 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java
@@ -17,7 +17,6 @@ import java.util.List;
*
*/
public interface WxMpTemplateMsgService {
-
/**
*
* 设置所属行业
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
index 71b6b170..00eea89e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
@@ -1,25 +1,19 @@
package me.chanjar.weixin.mp.api;
-import java.util.List;
-
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpUserQuery;
import me.chanjar.weixin.mp.bean.result.WxMpChangeOpenid;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
+import java.util.List;
+
/**
* 用户管理相关操作接口.
*
* @author Binary Wang
*/
public interface WxMpUserService {
- String USER_INFO_BATCH_GET_URL = "https://api.weixin.qq.com/cgi-bin/user/info/batchget";
- String USER_GET_URL = "https://api.weixin.qq.com/cgi-bin/user/get";
- String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info";
- String USER_INFO_UPDATE_REMARK_URL = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark";
- String USER_CHANGE_OPENID_URL = "http://api.weixin.qq.com/cgi-bin/changeopenid";
-
/**
*
* 设置用户备注名
@@ -87,7 +81,9 @@ public interface WxMpUserService {
/**
*
* 获取用户列表
- * 公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
+ * 公众号可通过本接口来获取帐号的关注者列表,
+ * 关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。
+ * 一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
* 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140840&token=&lang=zh_CN
* http请求方式: GET(请使用https协议)
* 接口地址:https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
@@ -101,11 +97,12 @@ public interface WxMpUserService {
*
* 微信公众号主体变更迁移用户 openid
* 详情请见: http://kf.qq.com/faq/170221aUnmmU170221eUZJNf.html
+ * http://kf.qq.com/faq/1901177NrqMr190117nqYJze.html
* http请求方式: POST
* 接口地址:https://api.weixin.qq.com/cgi-bin/changeopenid?access_token=ACCESS_TOKEN
*
*
- * @param fromAppid 原公众号的 appid
+ * @param fromAppid 原公众号的 appid
* @param openidList 需要转换的openid,这些必须是旧账号目前关注的才行,否则会出错;一次最多100个
*/
List changeOpenid(String fromAppid, List openidList) throws WxErrorException;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java
index 03158505..c1549aff 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java
@@ -13,7 +13,6 @@ import java.util.List;
* @author Binary Wang
*/
public interface WxMpUserTagService {
-
/**
*
* 创建标签
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java
index 9cda53bb..b0876c76 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java
@@ -1,6 +1,7 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopDataResult;
import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult;
/**
@@ -21,8 +22,45 @@ public interface WxMpWifiService {
* http请求方式: POST
* 请求URL:https://api.weixin.qq.com/bizwifi/shop/list?access_token=ACCESS_TOKEN
*
- * @param pageIndex 分页下标,默认从1开始
+ *
+ * @param pageIndex 分页下标,默认从1开始
* @param pageSize 每页的个数,默认10个,最大20个
+ * @return 结果
+ * @throws WxErrorException 异常
*/
WxMpWifiShopListResult listShop(int pageIndex, int pageSize) throws WxErrorException;
+
+ /**
+ *
+ * 查询门店Wi-Fi信息
+ * 通过此接口查询某一门店的详细Wi-Fi信息,包括门店内的设备类型、ssid、密码、设备数量、商家主页URL、顶部常驻入口文案。
+ *
+ * http请求方式: POST
+ * 请求URL:https://api.weixin.qq.com/bizwifi/shop/get?access_token=ACCESS_TOKEN
+ * POST数据格式:JSON
+ *
+ *
+ * @param shopId 门店ID
+ * @return 结果
+ * @throws WxErrorException 异常
+ */
+ WxMpWifiShopDataResult getShopWifiInfo(int shopId) throws WxErrorException;
+
+ /**
+ *
+ * 修改门店网络信息.
+ * 通过此接口修改门店的网络信息,包括网络名称(ssid)或密码。需注意:
+ * 只有门店下已添加Wi-Fi网络信息,才能调用此接口修改网络信息;添加方式请参考“添加密码型设备”和"添加portal型设备”接口文档。
+ * 网络信息修改后,密码型设备需同步修改所有设备的ssid或密码;portal型设备需修改所有设备的ssid,并按照《硬件鉴权协议接口》修改“第二步:改造移动端portal页面”中的ssid参数,否则将无法正常连网。
+ * 文档地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1457435413
+ *
+ *
+ * @param shopId 门店ID
+ * @param oldSsid 旧的ssid
+ * @param ssid 无线网络设备的ssid。32个字符以内;ssid支持中文,但可能因设备兼容性问题导致显示乱码,或无法连接等问题,相关风险自行承担! 当门店下是portal型设备时,ssid必填;当门店下是密码型设备时,ssid选填,且ssid和密码必须有一个以大写字母“WX”开头
+ * @param password 无线网络设备的密码。8-24个字符;不能包含中文字符; 当门店下是密码型设备时,才可填写password,且ssid和密码必须有一个以大写字母“WX”开头
+ * @return 是否更新成功
+ * @throws WxErrorException .
+ */
+ boolean updateShopWifiInfo(int shopId, String oldSsid, String ssid, String password) throws WxErrorException;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
index 534ea139..f7969eae 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
@@ -6,6 +6,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -21,26 +22,27 @@ import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.enums.TicketType;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.locks.Lock;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*;
+
/**
* 基础实现类.
*
* @author someone
*/
+@Slf4j
public abstract class BaseWxMpServiceImpl implements WxMpService, RequestHttp {
private static final JsonParser JSON_PARSER = new JsonParser();
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
-
protected WxSessionManager sessionManager = new StandardSessionManager();
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this);
@@ -61,6 +63,8 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
private WxMpAiOpenService aiOpenService = new WxMpAiOpenServiceImpl(this);
private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this);
private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this);
+ private WxMpCommentService commentService = new WxMpCommentServiceImpl(this);
+ private WxMpOcrService ocrService = new WxMpOcrServiceImpl(this);
private Map configStorageMap;
@@ -73,7 +77,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce)
.equals(signature);
} catch (Exception e) {
- this.log.error("Checking signature failed, and the reason is :" + e.getMessage());
+ log.error("Checking signature failed, and the reason is :" + e.getMessage());
return false;
}
}
@@ -94,7 +98,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
if (this.getWxMpConfigStorage().isTicketExpired(type)) {
String responseContent = execute(SimpleGetRequestExecutor.create(this),
- WxMpService.GET_TICKET_URL + type.getCode(), null);
+ GET_TICKET_URL.getUrl(this.getWxMpConfigStorage()) + type.getCode(), null);
JsonObject tmpJsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
@@ -143,27 +147,27 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
JsonObject o = new JsonObject();
o.addProperty("action", "long2short");
o.addProperty("long_url", longUrl);
- String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString());
+ String responseContent = this.post(SHORTURL_API_URL, o.toString());
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("short_url").getAsString();
}
@Override
public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException {
- String responseContent = this.post(WxMpService.SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson());
+ String responseContent = this.post(SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson());
return WxMpSemanticQueryResult.fromJson(responseContent);
}
@Override
public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) {
- return String.format(WxMpService.CONNECT_OAUTH2_AUTHORIZE_URL,
+ return String.format(CONNECT_OAUTH2_AUTHORIZE_URL.getUrl(this.getWxMpConfigStorage()),
this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state));
}
@Override
public String buildQrConnectUrl(String redirectURI, String scope, String state) {
- return String.format(WxMpService.QRCONNECT_URL,
- this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state));
+ return String.format(QRCONNECT_URL.getUrl(this.getWxMpConfigStorage()), this.getWxMpConfigStorage().getAppId(),
+ URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state));
}
private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException {
@@ -178,13 +182,14 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
@Override
public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException {
- String url = String.format(WxMpService.OAUTH2_ACCESS_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret(), code);
+ String url = String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(this.getWxMpConfigStorage()), this.getWxMpConfigStorage().getAppId(),
+ this.getWxMpConfigStorage().getSecret(), code);
return this.getOAuth2AccessToken(url);
}
@Override
public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException {
- String url = String.format(WxMpService.OAUTH2_REFRESH_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), refreshToken);
+ String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(this.getWxMpConfigStorage()), this.getWxMpConfigStorage().getAppId(), refreshToken);
return this.getOAuth2AccessToken(url);
}
@@ -194,7 +199,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
lang = "zh_CN";
}
- String url = String.format(WxMpService.OAUTH2_USERINFO_URL, token.getAccessToken(), token.getOpenId(), lang);
+ String url = String.format(OAUTH2_USERINFO_URL.getUrl(this.getWxMpConfigStorage()), token.getAccessToken(), token.getOpenId(), lang);
try {
RequestExecutor executor = SimpleGetRequestExecutor.create(this);
@@ -207,7 +212,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
@Override
public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken token) {
- String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, token.getAccessToken(), token.getOpenId());
+ String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(this.getWxMpConfigStorage()), token.getAccessToken(), token.getOpenId());
try {
SimpleGetRequestExecutor.create(this).execute(url, null);
@@ -221,7 +226,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
@Override
public String[] getCallbackIP() throws WxErrorException {
- String responseContent = this.get(WxMpService.GET_CALLBACK_IP_URL, null);
+ String responseContent = this.get(GET_CALLBACK_IP_URL, null);
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray();
String[] ipArray = new String[ipList.size()];
@@ -248,11 +253,26 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
}
+ @Override
+ public String get(WxMpApiUrl url, String queryParam) throws WxErrorException {
+ return this.get(url.getUrl(this.getWxMpConfigStorage()), queryParam);
+ }
+
@Override
public String post(String url, String postData) throws WxErrorException {
return execute(SimplePostRequestExecutor.create(this), url, postData);
}
+ @Override
+ public String post(WxMpApiUrl url, String postData) throws WxErrorException {
+ return this.post(url.getUrl(this.getWxMpConfigStorage()), postData);
+ }
+
+ @Override
+ public T execute(RequestExecutor executor, WxMpApiUrl url, E data) throws WxErrorException {
+ return this.execute(executor, url.getUrl(this.getWxMpConfigStorage()), data);
+ }
+
/**
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求.
*/
@@ -264,7 +284,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
return this.executeInternal(executor, uri, data);
} catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) {
- this.log.warn("重试达到最大次数【{}】", maxRetryTimes);
+ log.warn("重试达到最大次数【{}】", maxRetryTimes);
//最后一次重试失败后,直接抛出异常,不再等待
throw new RuntimeException("微信服务端异常,超出重试次数");
}
@@ -274,7 +294,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
if (error.getErrorCode() == -1) {
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
- this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
+ log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
@@ -285,11 +305,11 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
}
} while (retryTimes++ < this.maxRetryTimes);
- this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
throw new RuntimeException("微信服务端异常,超出重试次数");
}
- public T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ protected T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
E dataForLog = DataUtils.handleDataWithSecret(data);
if (uri.contains("access_token=")) {
@@ -302,7 +322,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
try {
T result = executor.execute(uriWithAccessToken, data);
- this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
+ log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
@@ -321,12 +341,12 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
}
if (error.getErrorCode() != 0) {
- this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
throw new WxErrorException(error, e);
}
return null;
} catch (IOException e) {
- this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
}
}
@@ -582,6 +602,11 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
return this.wifiService;
}
+ @Override
+ public WxMpOcrService getOcrService() {
+ return this.ocrService;
+ }
+
@Override
public WxMpMarketingService getMarketingService() {
return this.marketingService;
@@ -591,4 +616,19 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
public void setMarketingService(WxMpMarketingService marketingService) {
this.marketingService = marketingService;
}
+
+ @Override
+ public void setOcrService(WxMpOcrService ocrService) {
+ this.ocrService = ocrService;
+ }
+
+ @Override
+ public WxMpCommentService getCommentService() {
+ return this.commentService;
+ }
+
+ @Override
+ public void setCommentService(WxMpCommentService commentService) {
+ this.commentService = commentService;
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java
index 628b6c55..5ac3be31 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java
@@ -1,8 +1,7 @@
package me.chanjar.weixin.mp.api.impl;
-import java.io.File;
-
import com.google.gson.JsonParser;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -11,6 +10,10 @@ import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.enums.AiLangType;
import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecutor;
+import java.io.File;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.AiOpen.*;
+
/**
*
* Created by BinaryWang on 2018/6/9.
@@ -18,13 +21,10 @@ import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecuto
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
private static final JsonParser JSON_PARSER = new JsonParser();
- private WxMpService wxMpService;
-
- public WxMpAiOpenServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public void uploadVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException {
@@ -33,7 +33,7 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
}
this.wxMpService.execute(VoiceUploadRequestExecutor.create(this.wxMpService.getRequestHttp()),
- String.format(VOICE_UPLOAD_URL, "mp3", voiceId, lang.getCode()),
+ String.format(VOICE_UPLOAD_URL.getUrl(this.wxMpService.getWxMpConfigStorage()), "mp3", voiceId, lang.getCode()),
voiceFile);
}
@@ -45,7 +45,8 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
@Override
public String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException {
- String response = this.wxMpService.post(String.format(TRANSLATE_URL, langFrom.getCode(), langTo.getCode()), content);
+ String response = this.wxMpService.post(String.format(TRANSLATE_URL.getUrl(this.wxMpService.getWxMpConfigStorage()),
+ langFrom.getCode(), langTo.getCode()), content);
WxError error = WxError.fromJson(response, WxType.MP);
if (error.getErrorCode() != 0) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
index bdd19904..ec523f9a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
@@ -2,20 +2,21 @@ package me.chanjar.weixin.mp.api.impl;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.RandomUtils;
-import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpCardService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.card.*;
import me.chanjar.weixin.mp.enums.TicketType;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.concurrent.locks.Lock;
@@ -25,46 +26,22 @@ import java.util.concurrent.locks.Lock;
*
* @author BinaryWang
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpCardServiceImpl implements WxMpCardService {
- private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class);
-
- private WxMpService wxMpService;
-
private static final Gson GSON = WxMpGsonBuilder.create();
-
- public WxMpCardServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMpService getWxMpService() {
return this.wxMpService;
}
- /**
- * 获得卡券api_ticket,不强制刷新卡券api_ticket.
- *
- * @return 卡券api_ticket
- * @see #getCardApiTicket(boolean)
- */
@Override
public String getCardApiTicket() throws WxErrorException {
return getCardApiTicket(false);
}
- /**
- *
- * 获得卡券api_ticket.
- * 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
- *
- * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
- * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
- * .9F.E6.88.90.E7.AE.97.E6.B3.95
- *
- *
- * @param forceRefresh 强制刷新
- * @return 卡券api_ticket
- */
@Override
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
final TicketType type = TicketType.WX_CARD;
@@ -78,7 +55,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
if (this.getWxMpService().getWxMpConfigStorage().isTicketExpired(type)) {
String responseContent = this.wxMpService.execute(SimpleGetRequestExecutor
- .create(this.getWxMpService().getRequestHttp()), CARD_GET_TICKET, null);
+ .create(this.getWxMpService().getRequestHttp()), WxMpApiUrl.Card.CARD_GET_TICKET, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
@@ -91,32 +68,22 @@ public class WxMpCardServiceImpl implements WxMpCardService {
return this.getWxMpService().getWxMpConfigStorage().getTicket(type);
}
- /**
- *
- * 创建调用卡券api时所需要的签名
- *
- * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
- * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
- * .9F.E6.88.90.E7.AE.97.E6.B3.95
- *
- *
- * @param optionalSignParam 参与签名的参数数组。
- * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
- * 注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空
- * @return 卡券Api签名对象
- */
@Override
- public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws
- WxErrorException {
+ public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws WxErrorException {
long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = RandomUtils.getRandomStr();
String cardApiTicket = getCardApiTicket(false);
- String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3);
- signParam[optionalSignParam.length] = String.valueOf(timestamp);
- signParam[optionalSignParam.length + 1] = nonceStr;
- signParam[optionalSignParam.length + 2] = cardApiTicket;
- String signature = SHA1.gen(signParam);
+ String[] signParams = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3);
+ signParams[optionalSignParam.length] = String.valueOf(timestamp);
+ signParams[optionalSignParam.length + 1] = nonceStr;
+ signParams[optionalSignParam.length + 2] = cardApiTicket;
+ StringBuilder sb = new StringBuilder();
+ for (String a : signParams) {
+ sb.append(a);
+ }
+ String signature = DigestUtils.sha1Hex(sb.toString());
+
WxCardApiSignature cardApiSignature = new WxCardApiSignature();
cardApiSignature.setTimestamp(timestamp);
cardApiSignature.setNonceStr(nonceStr);
@@ -124,17 +91,11 @@ public class WxMpCardServiceImpl implements WxMpCardService {
return cardApiSignature;
}
- /**
- * 卡券Code解码
- *
- * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得
- * @return 解密后的Code
- */
@Override
public String decryptCardCode(String encryptCode) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("encrypt_code", encryptCode);
- String responseContent = this.wxMpService.post(CARD_CODE_DECRYPT, param.toString());
+ String responseContent = this.wxMpService.post(WxMpApiUrl.Card.CARD_CODE_DECRYPT, param.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code");
@@ -147,33 +108,18 @@ public class WxMpCardServiceImpl implements WxMpCardService {
param.addProperty("card_id", cardId);
param.addProperty("code", code);
param.addProperty("check_consume", checkConsume);
- String responseContent = this.wxMpService.post(CARD_CODE_GET, param.toString());
+ String responseContent = this.wxMpService.post(WxMpApiUrl.Card.CARD_CODE_GET, param.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxMpGsonBuilder.create().fromJson(tmpJsonElement,
new TypeToken() {
}.getType());
}
- /**
- * 卡券Code核销。核销失败会抛出异常
- *
- * @param code 单张卡券的唯一标准
- * @return 调用返回的JSON字符串。
- *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
- */
@Override
public String consumeCardCode(String code) throws WxErrorException {
return consumeCardCode(code, null);
}
- /**
- * 卡券Code核销。核销失败会抛出异常
- *
- * @param code 单张卡券的唯一标准
- * @param cardId 当自定义Code卡券时需要传入card_id
- * @return 调用返回的JSON字符串。
- *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
- */
@Override
public String consumeCardCode(String code, String cardId) throws WxErrorException {
JsonObject param = new JsonObject();
@@ -183,34 +129,23 @@ public class WxMpCardServiceImpl implements WxMpCardService {
param.addProperty("card_id", cardId);
}
- return this.wxMpService.post(CARD_CODE_CONSUME, param.toString());
+ return this.wxMpService.post(WxMpApiUrl.Card.CARD_CODE_CONSUME, param.toString());
}
- /**
- * 卡券Mark接口。
- * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住),
- * 才能进一步调用核销接口,否则报错。
- *
- * @param code 卡券的code码
- * @param cardId 卡券的ID
- * @param openId 用券用户的openid
- * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用
- */
@Override
- public void markCardCode(String code, String cardId, String openId, boolean isMark) throws
- WxErrorException {
+ public void markCardCode(String code, String cardId, String openId, boolean isMark) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("code", code);
param.addProperty("card_id", cardId);
param.addProperty("openid", openId);
param.addProperty("is_mark", isMark);
- String responseContent = this.getWxMpService().post(CARD_CODE_MARK, param.toString());
+ String responseContent = this.getWxMpService().post(WxMpApiUrl.Card.CARD_CODE_MARK, param.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
WxMpCardResult cardResult = WxMpGsonBuilder.create().fromJson(tmpJsonElement,
new TypeToken() {
}.getType());
if (!"0".equals(cardResult.getErrorCode())) {
- this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg());
+ log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg());
}
}
@@ -218,7 +153,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
public String getCardDetail(String cardId) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("card_id", cardId);
- String responseContent = this.wxMpService.post(CARD_GET, param.toString());
+ String responseContent = this.wxMpService.post(WxMpApiUrl.Card.CARD_GET, param.toString());
// 判断返回值
JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject();
@@ -233,76 +168,65 @@ public class WxMpCardServiceImpl implements WxMpCardService {
return responseContent;
}
- /**
- * 添加测试白名单.
- *
- * @param openid 用户的openid
- */
@Override
public String addTestWhiteList(String openid) throws WxErrorException {
JsonArray array = new JsonArray();
array.add(openid);
JsonObject jsonObject = new JsonObject();
jsonObject.add("openid", array);
- String respone = this.wxMpService.post(CARD_TEST_WHITELIST, GSON.toJson(jsonObject));
- return respone;
+ return this.wxMpService.post(WxMpApiUrl.Card.CARD_TEST_WHITELIST, GSON.toJson(jsonObject));
}
@Override
public WxMpCardCreateResult createCard(WxMpCardCreateMessage cardCreateMessage) throws WxErrorException {
-
- String response = this.wxMpService.post(CARD_CREATE, GSON.toJson(cardCreateMessage));
+ String response = this.wxMpService.post(WxMpApiUrl.Card.CARD_CREATE, GSON.toJson(cardCreateMessage));
return WxMpCardCreateResult.fromJson(response);
}
- /**
- * 创建卡券二维码.
- */
@Override
public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException {
- return createQrcodeCard(cardId, outerStr, 0);
+ return this.createQrcodeCard(cardId, outerStr, 0);
}
- /**
- * 创建卡券二维码.
- *
- * @param cardId 卡券编号
- * @param outerStr 二维码标识
- * @param expiresIn 失效时间,单位秒,不填默认365天
- */
@Override
public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn) throws WxErrorException {
+ return this.createQrcodeCard(cardId, outerStr, expiresIn, null, null, false);
+ }
+
+ @Override
+ public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn, String openid,
+ String code, boolean isUniqueCode) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("action_name", "QR_CARD");
if (expiresIn > 0) {
jsonObject.addProperty("expire_seconds", expiresIn);
}
+
JsonObject actionInfoJson = new JsonObject();
JsonObject cardJson = new JsonObject();
+ if (openid != null) {
+ cardJson.addProperty("openid", openid);
+ }
+
+ if (code != null) {
+ cardJson.addProperty("code", code);
+ }
+
+ cardJson.addProperty("is_unique_code", isUniqueCode);
cardJson.addProperty("card_id", cardId);
cardJson.addProperty("outer_str", outerStr);
actionInfoJson.add("card", cardJson);
jsonObject.add("action_info", actionInfoJson);
- return WxMpCardQrcodeCreateResult.fromJson(this.wxMpService.post(CARD_QRCODE_CREATE, GSON.toJson(jsonObject)));
+
+ return WxMpCardQrcodeCreateResult.fromJson(this.wxMpService.post(WxMpApiUrl.Card.CARD_QRCODE_CREATE, GSON.toJson(jsonObject)));
}
- /**
- * 创建卡券货架接口.
- */
@Override
public WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest request) throws WxErrorException {
- String response = this.wxMpService.post(CARD_LANDING_PAGE_CREATE, GSON.toJson(request));
+ String response = this.wxMpService.post(WxMpApiUrl.Card.CARD_LANDING_PAGE_CREATE, GSON.toJson(request));
return WxMpCardLandingPageCreateResult.fromJson(response);
}
- /**
- * 将用户的卡券设置为失效状态.
- * 详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=9
- *
- * @param cardId 卡券编号
- * @param code 用户会员卡号
- * @param reason 设置为失效的原因
- */
@Override
public String unavailableCardCode(String cardId, String code, String reason) throws WxErrorException {
if (StringUtils.isAnyBlank(cardId, code, reason)) {
@@ -312,7 +236,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
jsonRequest.addProperty("card_id", cardId);
jsonRequest.addProperty("code", code);
jsonRequest.addProperty("reason", reason);
- return this.wxMpService.post(CARD_CODE_UNAVAILABLE, GSON.toJson(jsonRequest));
+ return this.wxMpService.post(WxMpApiUrl.Card.CARD_CODE_UNAVAILABLE, GSON.toJson(jsonRequest));
}
@Override
@@ -322,7 +246,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
}
JsonObject param = new JsonObject();
param.addProperty("card_id", cardId);
- String response = this.wxMpService.post(CARD_DELETE, param.toString());
+ String response = this.wxMpService.post(WxMpApiUrl.Card.CARD_DELETE, param.toString());
return WxMpCardDeleteResult.fromJson(response);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java
new file mode 100644
index 00000000..f58280ae
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.mp.api.impl;
+
+import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpCommentService;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
+
+/**
+ * @author Binary Wang
+ * @date 2019-06-16
+ */
+@RequiredArgsConstructor
+public class WxMpCommentServiceImpl implements WxMpCommentService {
+ private final WxMpService wxMpService;
+
+ @Override
+ public void open(Integer msgDataId, Integer index) throws WxErrorException {
+ JsonObject json = new JsonObject();
+ json.addProperty("msg_data_id", msgDataId);
+ if (index != null) {
+ json.addProperty("index", index);
+ }
+ this.wxMpService.post(WxMpApiUrl.Comment.OPEN, json.toString());
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java
index bf60892a..a3523c0d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java
@@ -1,30 +1,30 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpDataCubeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.datacube.*;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import org.apache.commons.lang3.time.FastDateFormat;
import java.text.Format;
import java.util.Date;
import java.util.List;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.DataCube.*;
+
/**
* Created by Binary Wang on 2016/8/23.
*
* @author binarywang (https://github.com/binarywang)
*/
+@RequiredArgsConstructor
public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
-
private final Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd");
- private WxMpService wxMpService;
-
- public WxMpDataCubeServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public List getUserSummary(Date beginDate, Date endDate) throws WxErrorException {
@@ -69,7 +69,7 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
return this.getArticleResults(GET_USER_SHARE_HOUR, beginDate, endDate);
}
- private List getArticleResults(String url, Date beginDate, Date endDate) throws WxErrorException {
+ private List getArticleResults(WxMpApiUrl url, Date beginDate, Date endDate) throws WxErrorException {
String responseContent = this.wxMpService.post(url, buildParams(beginDate, endDate));
return WxDataCubeArticleResult.fromJson(responseContent);
}
@@ -109,13 +109,13 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
return this.getUpstreamMsg(GET_UPSTREAM_MSG_DIST_MONTH, beginDate, endDate);
}
- private List getUpstreamMsg(String url, Date beginDate, Date endDate) throws WxErrorException {
+ private List getUpstreamMsg(WxMpApiUrl url, Date beginDate, Date endDate) throws WxErrorException {
String responseContent = this.wxMpService.post(url, buildParams(beginDate, endDate));
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
- public List getInterfaceSummary(Date beginDate, Date endDate) throws WxErrorException {
+ public List getInterfaceSummary(Date beginDate, Date endDate) throws WxErrorException {
String responseContent = this.wxMpService.post(GET_INTERFACE_SUMMARY, buildParams(beginDate, endDate));
return WxDataCubeInterfaceResult.fromJson(responseContent);
}
@@ -128,7 +128,7 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
}
@Override
- public List getInterfaceSummaryHour(Date beginDate, Date endDate) throws WxErrorException {
+ public List getInterfaceSummaryHour(Date beginDate, Date endDate) throws WxErrorException {
String responseContent = this.wxMpService.post(GET_INTERFACE_SUMMARY_HOUR, buildParams(beginDate, endDate));
return WxDataCubeInterfaceResult.fromJson(responseContent);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
index 3fe464a8..3aa122a5 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
@@ -1,86 +1,76 @@
package me.chanjar.weixin.mp.api.impl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpDeviceService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.device.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Device.*;
/**
* Created by keungtung on 10/12/2016.
+ *
+ * @author keungtung
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpDeviceServiceImpl implements WxMpDeviceService {
- private static final String API_URL_PREFIX = "https://api.weixin.qq.com/device";
- private static Logger log = LoggerFactory.getLogger(WxMpMenuServiceImpl.class);
-
- private WxMpService wxMpService;
-
- public WxMpDeviceServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public TransMsgResp transMsg(WxDeviceMsg msg) throws WxErrorException {
- String url = API_URL_PREFIX + "/transmsg";
- String response = this.wxMpService.post(url, msg.toJson());
+ String response = this.wxMpService.post(DEVICE_TRANSMSG, msg.toJson());
return TransMsgResp.fromJson(response);
}
@Override
public WxDeviceQrCodeResult getQrCode(String productId) throws WxErrorException {
- String url = API_URL_PREFIX + "/getqrcode";
- String response = this.wxMpService.get(url, "product_id=" + productId);
+ String response = this.wxMpService.get(DEVICE_GETQRCODE, "product_id=" + productId);
return WxDeviceQrCodeResult.fromJson(response);
}
@Override
public WxDeviceAuthorizeResult authorize(WxDeviceAuthorize wxDeviceAuthorize) throws WxErrorException {
- String url = API_URL_PREFIX + "/authorize_device";
- String response = this.wxMpService.post(url, wxDeviceAuthorize.toJson());
+ String response = this.wxMpService.post(DEVICE_AUTHORIZE_DEVICE, wxDeviceAuthorize.toJson());
return WxDeviceAuthorizeResult.fromJson(response);
}
@Override
public WxDeviceBindResult bind(WxDeviceBind wxDeviceBind) throws WxErrorException {
- String url = API_URL_PREFIX + "/bind";
- String response = this.wxMpService.post(url, wxDeviceBind.toJson());
+ String response = this.wxMpService.post(DEVICE_BIND, wxDeviceBind.toJson());
return WxDeviceBindResult.fromJson(response);
}
@Override
public WxDeviceBindResult compelBind(WxDeviceBind wxDeviceBind) throws WxErrorException {
- String url = API_URL_PREFIX + "/compel_bind";
- String response = this.wxMpService.post(url, wxDeviceBind.toJson());
+ String response = this.wxMpService.post(DEVICE_COMPEL_BIND, wxDeviceBind.toJson());
return WxDeviceBindResult.fromJson(response);
}
@Override
public WxDeviceBindResult unbind(WxDeviceBind wxDeviceBind) throws WxErrorException {
- String url = API_URL_PREFIX + "/unbind?";
- String response = this.wxMpService.post(url, wxDeviceBind.toJson());
+ String response = this.wxMpService.post(DEVICE_UNBIND, wxDeviceBind.toJson());
return WxDeviceBindResult.fromJson(response);
}
@Override
public WxDeviceBindResult compelUnbind(WxDeviceBind wxDeviceBind) throws WxErrorException {
- String url = API_URL_PREFIX + "/compel_unbind?";
- String response = this.wxMpService.post(url, wxDeviceBind.toJson());
+ String response = this.wxMpService.post(DEVICE_COMPEL_UNBIND, wxDeviceBind.toJson());
return WxDeviceBindResult.fromJson(response);
}
@Override
public WxDeviceOpenIdResult getOpenId(String deviceType, String deviceId) throws WxErrorException {
- String url = API_URL_PREFIX + "/get_openid";
- String response = this.wxMpService.get(url, "device_type=" + deviceType + "&device_id=" + deviceId);
+ String response = this.wxMpService.get(DEVICE_GET_OPENID, "device_type=" + deviceType + "&device_id=" + deviceId);
return WxDeviceOpenIdResult.fromJson(response);
}
@Override
public WxDeviceBindDeviceResult getBindDevice(String openId) throws WxErrorException {
- String url = API_URL_PREFIX + "/get_bind_device";
- String response = this.wxMpService.get(url, "openid=" + openId);
+ String response = this.wxMpService.get(DEVICE_GET_BIND_DEVICE, "openid=" + openId);
return WxDeviceBindDeviceResult.fromJson(response);
}
}
-
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
index 7707c567..a131e3a9 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
@@ -1,12 +1,8 @@
package me.chanjar.weixin.mp.api.impl;
-import java.io.File;
-import java.util.Date;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -16,23 +12,20 @@ import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
+import me.chanjar.weixin.mp.bean.kefu.result.*;
+
+import java.io.File;
+import java.util.Date;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Kefu.*;
/**
* @author Binary Wang
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpKefuServiceImpl implements WxMpKefuService {
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
- private WxMpService wxMpService;
-
- public WxMpKefuServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException {
@@ -73,13 +66,15 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
@Override
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException {
WxMediaUploadResult responseContent = this.wxMpService
- .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(KFACCOUNT_UPLOAD_HEAD_IMG, kfAccount), imgFile);
+ .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()),
+ String.format(KFACCOUNT_UPLOAD_HEAD_IMG.getUrl(this.wxMpService.getWxMpConfigStorage()), kfAccount), imgFile);
return responseContent != null;
}
@Override
public boolean kfAccountDel(String kfAccount) throws WxErrorException {
- String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL, kfAccount), null);
+ String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL.getUrl(this.wxMpService.getWxMpConfigStorage()),
+ kfAccount), null);
return responseContent != null;
}
@@ -99,13 +94,15 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
@Override
public WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException {
- String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION, openid), null);
+ String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION
+ .getUrl(this.wxMpService.getWxMpConfigStorage()), openid), null);
return WxMpKfSessionGetResult.fromJson(responseContent);
}
@Override
public WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException {
- String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST, kfAccount), null);
+ String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST
+ .getUrl(this.wxMpService.getWxMpConfigStorage()), kfAccount), null);
return WxMpKfSessionList.fromJson(responseContent);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java
index 91e7d4c1..6ec51e74 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java
@@ -4,6 +4,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
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.mp.api.WxMpMarketingService;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -12,8 +14,6 @@ import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadResult;
import me.chanjar.weixin.mp.bean.marketing.WxMpUserAction;
import me.chanjar.weixin.mp.bean.marketing.WxMpUserActionSet;
import org.apache.commons.lang3.time.DateFormatUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URLEncoder;
@@ -21,48 +21,41 @@ import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Marketing.*;
+
/**
* @author 007
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpMarketingServiceImpl implements WxMpMarketingService {
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
- private WxMpService wxMpService;
-
- public WxMpMarketingServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public long addUserActionSets(String type, String name, String description) throws WxErrorException {
- String url = API_URL_PREFIX + "user_action_sets/add?version=v1.0";
JsonObject json = new JsonObject();
json.addProperty("type", type);
json.addProperty("name", name);
json.addProperty("description", description);
- String responseContent = wxMpService.post(url, json.toString());
+ String responseContent = wxMpService.post(USER_ACTION_SETS_ADD, json.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("data").getAsJsonObject().get("user_action_set_id").getAsLong();
}
@Override
public List getUserActionSets(Long userActionSetId) throws WxErrorException {
- String url = API_URL_PREFIX + "user_action_sets/get";
- String responseContent = wxMpService.get(url, "version=v1.0&user_action_set_id=" + userActionSetId);
+ String responseContent = wxMpService.get(USER_ACTION_SETS_GET, "version=v1.0&user_action_set_id=" + userActionSetId);
return WxMpUserActionSet.fromJson(responseContent);
}
@Override
public void addUserAction(List actions) throws WxErrorException {
- String url = API_URL_PREFIX + "user_actions/add?version=v1.0";
- JsonArray json = new JsonArray();
- for (WxMpUserAction action : actions) {
- json.add(action.toJsonObject());
- }
- wxMpService.post(url, json.toString());
+ wxMpService.post(USER_ACTIONS_ADD, WxMpUserAction.listToJson(actions));
}
@Override
- public WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer page_size) throws WxErrorException, IOException {
+ public WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer pageSize)
+ throws WxErrorException, IOException {
Date today = new Date();
if (beginDate == null) {
beginDate = today;
@@ -70,23 +63,21 @@ public class WxMpMarketingServiceImpl implements WxMpMarketingService {
if (endDate == null) {
endDate = today;
}
- String url = API_URL_PREFIX + "wechat_ad_leads/get";
String params = "version=v1.0";
JsonObject dateRange = new JsonObject();
dateRange.addProperty("begin_date", DateFormatUtils.format(beginDate, "yyyy-MM-dd"));
dateRange.addProperty("end_date", DateFormatUtils.format(endDate, "yyyy-MM-dd"));
params += "&date_range=" + URLEncoder.encode(dateRange.toString(), StandardCharsets.UTF_8.name());
params += "&page=" + page;
- params += "&page_size=" + page_size;
+ params += "&page_size=" + pageSize;
if (filtering != null) {
JsonArray filterJson = new JsonArray();
for (WxMpAdLeadFilter filter : filtering) {
filterJson.add(filter.toJsonObject());
}
params += "&filtering=" + URLEncoder.encode(filterJson.toString(), StandardCharsets.UTF_8.name());
- ;
}
- String responseContent = wxMpService.get(url, params);
+ String responseContent = wxMpService.get(WECHAT_AD_LEADS_GET, params);
return WxMpAdLeadResult.fromJson(responseContent);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java
index 31aa043e..caca3cd0 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java
@@ -1,14 +1,17 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMassMessageService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.*;
/**
*
@@ -18,41 +21,38 @@ import org.slf4j.LoggerFactory;
*
* @author Binary Wang
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpMassMessageServiceImpl implements WxMpMassMessageService {
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
- private WxMpService wxMpService;
-
- public WxMpMassMessageServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException {
- String responseContent = this.wxMpService.post(MEDIA_UPLOAD_NEWS_URL, news.toJson());
+ String responseContent = this.wxMpService.post(MassMessage.MEDIA_UPLOAD_NEWS_URL, news.toJson());
return WxMpMassUploadResult.fromJson(responseContent);
}
@Override
public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException {
- String responseContent = this.wxMpService.post(MEDIA_UPLOAD_VIDEO_URL, video.toJson());
+ String responseContent = this.wxMpService.post(MassMessage.MEDIA_UPLOAD_VIDEO_URL, video.toJson());
return WxMpMassUploadResult.fromJson(responseContent);
}
@Override
public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException {
- String responseContent = this.wxMpService.post(WxMpMassMessageService.MESSAGE_MASS_SENDALL_URL, message.toJson());
+ String responseContent = this.wxMpService.post(MassMessage.MESSAGE_MASS_SENDALL_URL, message.toJson());
return WxMpMassSendResult.fromJson(responseContent);
}
@Override
public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException {
- String responseContent = this.wxMpService.post(MESSAGE_MASS_SEND_URL, message.toJson());
+ String responseContent = this.wxMpService.post(MassMessage.MESSAGE_MASS_SEND_URL, message.toJson());
return WxMpMassSendResult.fromJson(responseContent);
}
@Override
public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException {
- String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson());
+ String responseContent = this.wxMpService.post(MassMessage.MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson());
return WxMpMassSendResult.fromJson(responseContent);
}
@@ -61,7 +61,7 @@ public class WxMpMassMessageServiceImpl implements WxMpMassMessageService {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("msg_id", msgId);
jsonObject.addProperty("article_idx", articleIndex);
- this.wxMpService.post(MESSAGE_MASS_DELETE_URL, jsonObject.toString());
+ this.wxMpService.post(MassMessage.MESSAGE_MASS_DELETE_URL, jsonObject.toString());
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
index 7929aced..2ceec219 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
@@ -1,12 +1,6 @@
package me.chanjar.weixin.mp.api.impl;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
@@ -18,33 +12,29 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialCountResult;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialNewsBatchGetResult;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult;
+import me.chanjar.weixin.mp.bean.material.*;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialDeleteRequestExecutor;
-import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialNewsInfoRequestExecutor;
-import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialUploadRequestExecutor;
-import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialVideoInfoRequestExecutor;
-import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialVoiceAndImageDownloadRequestExecutor;
+import me.chanjar.weixin.mp.util.requestexecuter.material.*;
import me.chanjar.weixin.mp.util.requestexecuter.media.MediaImgUploadRequestExecutor;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Material.*;
+
/**
* Created by Binary Wang on 2016/7/21.
+ *
+ * @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpMaterialServiceImpl implements WxMpMaterialService {
-
- private WxMpService wxMpService;
-
- public WxMpMaterialServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException {
@@ -63,7 +53,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException {
- String url = String.format(MEDIA_UPLOAD_URL, mediaType);
+ String url = String.format(MEDIA_UPLOAD_URL.getUrl(this.wxMpService.getWxMpConfigStorage()), mediaType);
return this.wxMpService.execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, file);
}
@@ -82,7 +72,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException {
- String url = String.format(MATERIAL_ADD_URL, mediaType);
+ String url = String.format(MATERIAL_ADD_URL.getUrl(this.wxMpService.getWxMpConfigStorage()), mediaType);
return this.wxMpService.execute(MaterialUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, material);
}
@@ -98,17 +88,20 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException {
return this.wxMpService.execute(MaterialVoiceAndImageDownloadRequestExecutor
- .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MATERIAL_GET_URL, mediaId);
+ .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()),
+ MATERIAL_GET_URL, mediaId);
}
@Override
public WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException {
- return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId);
+ return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()),
+ MATERIAL_GET_URL, mediaId);
}
@Override
public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException {
- return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId);
+ return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()),
+ MATERIAL_GET_URL, mediaId);
}
@Override
@@ -124,7 +117,8 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public boolean materialDelete(String mediaId) throws WxErrorException {
- return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_DEL_URL, mediaId);
+ return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()),
+ MATERIAL_DEL_URL, mediaId);
}
@Override
@@ -140,7 +134,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException {
- Map params = new HashMap<>();
+ Map params = new HashMap<>(4);
params.put("type", WxConsts.MaterialType.NEWS);
params.put("offset", offset);
params.put("count", count);
@@ -155,7 +149,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
@Override
public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException {
- Map params = new HashMap<>();
+ Map params = new HashMap<>(4);
params.put("type", type);
params.put("offset", offset);
params.put("count", count);
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java
index 3eaf6141..31d9bcf3 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java
@@ -5,7 +5,9 @@ import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.mp.bean.membercard.*;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import org.apache.commons.lang3.StringUtils;
import com.google.gson.Gson;
@@ -40,15 +42,12 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
* @version 2017/7/8
*/
@Slf4j
+@RequiredArgsConstructor
public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
- private WxMpService wxMpService;
+ private final WxMpService wxMpService;
private static final Gson GSON = WxMpGsonBuilder.create();
- public WxMpMemberCardServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
-
@Override
public WxMpService getWxMpService() {
return this.wxMpService;
@@ -70,7 +69,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
return validResult;
}
- String response = this.wxMpService.post(MEMBER_CARD_CREATE, GSON.toJson(createMessageMessage));
+ String response = this.wxMpService.post(WxMpApiUrl.MemberCard.MEMBER_CARD_CREATE, GSON.toJson(createMessageMessage));
return WxMpCardCreateResult.fromJson(response);
}
@@ -212,7 +211,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
@Override
public String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException {
- return this.wxMpService.post(MEMBER_CARD_ACTIVATE, GSON.toJson(activatedMessage));
+ return this.wxMpService.post(WxMpApiUrl.MemberCard.MEMBER_CARD_ACTIVATE, GSON.toJson(activatedMessage));
}
@Override
@@ -221,7 +220,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
jsonObject.addProperty("card_id", cardId);
jsonObject.addProperty("code", code);
- String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString());
+ String responseContent = this.getWxMpService().post(WxMpApiUrl.MemberCard.MEMBER_CARD_USER_INFO_GET, jsonObject.toString());
log.debug("{}", responseContent);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxMpGsonBuilder.create().fromJson(tmpJsonElement,
@@ -233,7 +232,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
public WxMpMemberCardUpdateResult updateUserMemberCard(WxMpMemberCardUpdateMessage updateUserMessage)
throws WxErrorException {
- String responseContent = this.getWxMpService().post(MEMBER_CARD_UPDATE_USER, GSON.toJson(updateUserMessage));
+ String responseContent = this.getWxMpService().post(WxMpApiUrl.MemberCard.MEMBER_CARD_UPDATE_USER, GSON.toJson(updateUserMessage));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxMpGsonBuilder.create().fromJson(tmpJsonElement,
@@ -243,7 +242,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
@Override
public MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException {
- String responseContent = this.getWxMpService().post(MEMBER_CARD_ACTIVATE_USER_FORM, GSON.toJson(userFormRequest));
+ String responseContent = this.getWxMpService().post(WxMpApiUrl.MemberCard.MEMBER_CARD_ACTIVATE_USER_FORM, GSON.toJson(userFormRequest));
return MemberCardActivateUserFormResult.fromJson(responseContent);
}
@@ -252,7 +251,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
JsonObject params = new JsonObject();
params.addProperty("card_id", cardId);
params.addProperty("outer_str", outStr);
- String response = this.wxMpService.post(MEMBER_CARD_ACTIVATE_URL, GSON.toJson(params));
+ String response = this.wxMpService.post(WxMpApiUrl.MemberCard.MEMBER_CARD_ACTIVATE_URL, GSON.toJson(params));
ActivatePluginParamResult result = GSON.fromJson(response, ActivatePluginParamResult.class);
if (0 == result.getErrcode()) {
String url = result.getUrl();
@@ -273,18 +272,16 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
@Override
public CardUpdateResult updateCardInfo(MemberCardUpdateRequest memberCardUpdateRequest) throws WxErrorException {
- String response = this.wxMpService.post(MEMBER_CARD_UPDATE, GSON.toJson(memberCardUpdateRequest));
- CardUpdateResult result = GSON.fromJson(response, CardUpdateResult.class);
- return result;
+ String response = this.wxMpService.post(WxMpApiUrl.MemberCard.MEMBER_CARD_UPDATE, GSON.toJson(memberCardUpdateRequest));
+ return GSON.fromJson(response, CardUpdateResult.class);
}
@Override
public WxMpMemberCardActivateTempInfoResult getActivateTempInfo(String activateTicket) throws WxErrorException {
JsonObject params = new JsonObject();
params.addProperty("activate_ticket", activateTicket);
- String response = this.wxMpService.post(MEMBER_CARD_ACTIVATE_TEMP_INFO, GSON.toJson(params));
- WxMpMemberCardActivateTempInfoResult result = GSON.fromJson(response, WxMpMemberCardActivateTempInfoResult.class);
- return result;
+ String response = this.wxMpService.post(WxMpApiUrl.MemberCard.MEMBER_CARD_ACTIVATE_TEMP_INFO, GSON.toJson(params));
+ return GSON.fromJson(response, WxMpMemberCardActivateTempInfoResult.class);
}
private static String truncateUrlPage(String strURL) {
@@ -302,7 +299,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
return strAllParam;
}
- public static Map parseRequestUrl(String url) {
+ private static Map parseRequestUrl(String url) {
Map mapRequest = new HashMap<>(16);
String[] arrSplit;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
index e8dc8476..2a42a0a5 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
@@ -2,34 +2,34 @@ package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
import me.chanjar.weixin.mp.bean.menu.WxMpMenu;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Menu.*;
/**
* Created by Binary Wang on 2016/7/21.
+ *
+ * @author Binary Wang
*/
+@Slf4j
+@RequiredArgsConstructor
public class WxMpMenuServiceImpl implements WxMpMenuService {
- private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/menu";
- private static Logger log = LoggerFactory.getLogger(WxMpMenuServiceImpl.class);
-
- private WxMpService wxMpService;
-
- public WxMpMenuServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public String menuCreate(WxMenu menu) throws WxErrorException {
String menuJson = menu.toJson();
- String url = API_URL_PREFIX + "/create";
+ WxMpApiUrl.Menu url = MENU_CREATE;
if (menu.getMatchRule() != null) {
- url = API_URL_PREFIX + "/addconditional";
+ url = MENU_ADDCONDITIONAL;
}
log.debug("开始创建菜单:{}", menuJson);
@@ -48,9 +48,9 @@ public class WxMpMenuServiceImpl implements WxMpMenuService {
public String menuCreate(String json) throws WxErrorException {
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = jsonParser.parse(json).getAsJsonObject();
- String url = API_URL_PREFIX + "/create";
+ WxMpApiUrl.Menu url = MENU_CREATE;
if (jsonObject.get("matchrule") != null) {
- url = API_URL_PREFIX + "/addconditional";
+ url = MENU_ADDCONDITIONAL;
}
String result = this.wxMpService.post(url, json);
@@ -63,25 +63,22 @@ public class WxMpMenuServiceImpl implements WxMpMenuService {
@Override
public void menuDelete() throws WxErrorException {
- String url = API_URL_PREFIX + "/delete";
- String result = this.wxMpService.get(url, null);
+ String result = this.wxMpService.get(MENU_DELETE, null);
log.debug("删除菜单结果:{}", result);
}
@Override
public void menuDelete(String menuId) throws WxErrorException {
- String url = API_URL_PREFIX + "/delconditional";
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("menuid", menuId);
- String result = this.wxMpService.post(url, jsonObject.toString());
+ String result = this.wxMpService.post(MENU_DELCONDITIONAL, jsonObject.toString());
log.debug("根据MeunId({})删除个性化菜单结果:{}", menuId, result);
}
@Override
public WxMpMenu menuGet() throws WxErrorException {
- String url = API_URL_PREFIX + "/get";
try {
- String resultContent = this.wxMpService.get(url, null);
+ String resultContent = this.wxMpService.get(MENU_GET, null);
return WxMpMenu.fromJson(resultContent);
} catch (WxErrorException e) {
// 46003 不存在的菜单数据
@@ -94,11 +91,10 @@ public class WxMpMenuServiceImpl implements WxMpMenuService {
@Override
public WxMenu menuTryMatch(String userid) throws WxErrorException {
- String url = API_URL_PREFIX + "/trymatch";
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("user_id", userid);
try {
- String resultContent = this.wxMpService.post(url, jsonObject.toString());
+ String resultContent = this.wxMpService.post(MENU_TRYMATCH, jsonObject.toString());
return WxMenu.fromJson(resultContent);
} catch (WxErrorException e) {
// 46003 不存在的菜单数据;46002 不存在的菜单版本
@@ -112,8 +108,7 @@ public class WxMpMenuServiceImpl implements WxMpMenuService {
@Override
public WxMpGetSelfMenuInfoResult getSelfMenuInfo() throws WxErrorException {
- String url = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info";
- String resultContent = this.wxMpService.get(url, null);
+ String resultContent = this.wxMpService.get(GET_CURRENT_SELFMENU_INFO, null);
return WxMpGetSelfMenuInfoResult.fromJson(resultContent);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java
new file mode 100644
index 00000000..4d3c434e
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.mp.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpOcrService;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.ocr.WxMpOcrIdCardResult;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.IDCARD;
+
+/**
+ * ocr 接口实现.
+ *
+ * @author Binary Wang
+ * @date 2019-06-22
+ */
+@RequiredArgsConstructor
+public class WxMpOcrServiceImpl implements WxMpOcrService {
+ private final WxMpService wxMpService;
+
+ @Override
+ public WxMpOcrIdCardResult idCard(ImageType imgType, String imgUrl) throws WxErrorException {
+ try {
+ imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
+ } catch (UnsupportedEncodingException e) {
+ // ignore cannot happen
+ }
+
+ final String result = this.wxMpService.get(String.format(IDCARD.getUrl(this.wxMpService.getWxMpConfigStorage()),
+ imgType.getType(), imgUrl), null);
+ return WxMpOcrIdCardResult.fromJson(result);
+ }
+
+ @Override
+ public WxMpOcrIdCardResult idCard(ImageType imgType, File imgFile) {
+ return null;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java
index 5783ce79..a654afb7 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java
@@ -1,6 +1,7 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
@@ -14,16 +15,16 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Qrcode.*;
+
/**
* Created by Binary Wang on 2016/7/21.
+ *
+ * @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpQrcodeServiceImpl implements WxMpQrcodeService {
- private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode";
- private WxMpService wxMpService;
-
- public WxMpQrcodeServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException {
@@ -31,37 +32,20 @@ public class WxMpQrcodeServiceImpl implements WxMpQrcodeService {
throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build());
}
- //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
- if (expireSeconds != null && expireSeconds > 2592000) {
- throw new WxErrorException(WxError.builder().errorCode(-1)
- .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build());
- }
-
- if (expireSeconds == null) {
- expireSeconds = 30;
- }
-
- String url = API_URL_PREFIX + "/create";
- JsonObject json = new JsonObject();
- json.addProperty("action_name", "QR_SCENE");
- json.addProperty("expire_seconds", expireSeconds);
-
- JsonObject actionInfo = new JsonObject();
- JsonObject scene = new JsonObject();
- scene.addProperty("scene_id", sceneId);
- actionInfo.add("scene", scene);
- json.add("action_info", actionInfo);
- String responseContent = this.wxMpService.post(url, json.toString());
- return WxMpQrCodeTicket.fromJson(responseContent);
+ return this.createQrCode("QR_SCENE", null, sceneId, expireSeconds);
}
-
@Override
public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException {
if (StringUtils.isBlank(sceneStr)) {
throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build());
}
+ return this.createQrCode("QR_STR_SCENE", sceneStr, null, expireSeconds);
+ }
+
+ private WxMpQrCodeTicket createQrCode(String actionName, String sceneStr, Integer sceneId, Integer expireSeconds)
+ throws WxErrorException {
//expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
if (expireSeconds != null && expireSeconds > 2592000) {
throw new WxErrorException(WxError.builder().errorCode(-1)
@@ -72,21 +56,31 @@ public class WxMpQrcodeServiceImpl implements WxMpQrcodeService {
expireSeconds = 30;
}
- String url = API_URL_PREFIX + "/create";
+ return this.getQrCodeTicket(actionName, sceneStr, sceneId, expireSeconds);
+ }
+
+ private WxMpQrCodeTicket getQrCodeTicket(String actionName, String sceneStr, Integer sceneId, Integer expireSeconds)
+ throws WxErrorException {
JsonObject json = new JsonObject();
- json.addProperty("action_name", "QR_STR_SCENE");
- json.addProperty("expire_seconds", expireSeconds);
+ json.addProperty("action_name", actionName);
+ if (expireSeconds != null) {
+ json.addProperty("expire_seconds", expireSeconds);
+ }
JsonObject actionInfo = new JsonObject();
JsonObject scene = new JsonObject();
- scene.addProperty("scene_str", sceneStr);
+ if (sceneStr != null) {
+ scene.addProperty("scene_str", sceneStr);
+ } else if (sceneId != null) {
+ scene.addProperty("scene_id", sceneId);
+ }
+
actionInfo.add("scene", scene);
json.add("action_info", actionInfo);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(QRCODE_CREATE, json.toString());
return WxMpQrCodeTicket.fromJson(responseContent);
}
-
@Override
public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException {
if (sceneId < 1 || sceneId > 100000) {
@@ -95,43 +89,23 @@ public class WxMpQrcodeServiceImpl implements WxMpQrcodeService {
.build());
}
- String url = API_URL_PREFIX + "/create";
- JsonObject json = new JsonObject();
- json.addProperty("action_name", "QR_LIMIT_SCENE");
- JsonObject actionInfo = new JsonObject();
- JsonObject scene = new JsonObject();
- scene.addProperty("scene_id", sceneId);
- actionInfo.add("scene", scene);
- json.add("action_info", actionInfo);
- String responseContent = this.wxMpService.post(url, json.toString());
- return WxMpQrCodeTicket.fromJson(responseContent);
+ return this.getQrCodeTicket("QR_LIMIT_SCENE", null, sceneId, null);
}
@Override
public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException {
- String url = API_URL_PREFIX + "/create";
- JsonObject json = new JsonObject();
- json.addProperty("action_name", "QR_LIMIT_STR_SCENE");
- JsonObject actionInfo = new JsonObject();
- JsonObject scene = new JsonObject();
- scene.addProperty("scene_str", sceneStr);
- actionInfo.add("scene", scene);
- json.add("action_info", actionInfo);
- String responseContent = this.wxMpService.post(url, json.toString());
- return WxMpQrCodeTicket.fromJson(responseContent);
+ return this.getQrCodeTicket("QR_LIMIT_STR_SCENE", sceneStr, null, null);
}
@Override
public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException {
- String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
- return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), url, ticket);
+ return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), SHOW_QRCODE, ticket);
}
@Override
public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException {
- String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s";
try {
- String resultUrl = String.format(url,
+ String resultUrl = String.format(SHOW_QRCODE_WITH_TICKET.getUrl(this.wxMpService.getWxMpConfigStorage()),
URLEncoder.encode(ticket, StandardCharsets.UTF_8.name()));
if (needShortUrl) {
return this.wxMpService.shortUrl(resultUrl);
@@ -145,7 +119,7 @@ public class WxMpQrcodeServiceImpl implements WxMpQrcodeService {
@Override
public String qrCodePictureUrl(String ticket) throws WxErrorException {
- return qrCodePictureUrl(ticket, false);
+ return this.qrCodePictureUrl(ticket, false);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
index 10e2a5b7..d13a95b1 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
@@ -7,8 +7,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.HttpType;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
-import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -19,8 +18,12 @@ import org.apache.http.impl.client.CloseableHttpClient;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_ACCESS_TOKEN_URL;
+
/**
* apache http client方式实现.
+ *
+ * @author someone
*/
public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl {
private CloseableHttpClient httpClient;
@@ -63,20 +66,20 @@ public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl {
private HttpConnectionProvider httpClient;
@@ -48,15 +51,15 @@ public class WxMpServiceJoddHttpImpl extends BaseWxMpServiceImpl {
private OkHttpClient httpClient;
@@ -37,15 +40,15 @@ public class WxMpServiceOkHttpImpl extends BaseWxMpServiceImpl
- * 获取设备及用户信息
- * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。
- * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963
- * http请求方式: POST(请使用https协议)
- * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE
- *
- *
- * @param wxMpShakeQuery 查询参数
- */
@Override
public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException {
- String url = "https://api.weixin.qq.com/shakearound/user/getshakeinfo";
String postData = wxMpShakeQuery.toJsonString();
- String responseContent = this.wxMpService.post(url, postData);
+ String responseContent = this.wxMpService.post(SHAKEAROUND_USER_GETSHAKEINFO, postData);
return WxMpShakeInfoResult.fromJson(responseContent);
}
@Override
- public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException {
- String url = "https://api.weixin.qq.com/shakearound/page/add";
+ public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery)
+ throws WxErrorException {
String postData = shakeAroundPageAddQuery.toJsonString();
- String responseContent = this.wxMpService.post(url, postData);
+ String responseContent = this.wxMpService.post(SHAKEAROUND_PAGE_ADD, postData);
return WxMpShakeAroundPageAddResult.fromJson(responseContent);
}
@Override
- public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException {
- String url = "https://api.weixin.qq.com/shakearound/device/bindpage";
+ public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery)
+ throws WxErrorException {
String postData = shakeAroundDeviceBindPageQuery.toJsonString();
- String responseContent = this.wxMpService.post(url, postData);
+ String responseContent = this.wxMpService.post(SHAKEAROUND_DEVICE_BINDPAGE, postData);
return WxError.fromJson(responseContent, WxType.MP);
}
@Override
- public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException {
- String url = "https://api.weixin.qq.com/shakearound/relation/search";
- String postData = shakeAroundRelationSearchQuery.toJsonString();
- String responseContent = this.wxMpService.post(url, postData);
+ public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery searchQuery)
+ throws WxErrorException {
+ String postData = searchQuery.toJsonString();
+ String responseContent = this.wxMpService.post(SHAKEAROUND_RELATION_SEARCH, postData);
return WxMpShakeAroundRelationSearchResult.fromJson(responseContent);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java
index 40210206..91381659 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java
@@ -3,6 +3,7 @@ package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -12,6 +13,7 @@ import me.chanjar.weixin.mp.api.WxMpStoreService;
import me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo;
import me.chanjar.weixin.mp.bean.store.WxMpStoreInfo;
import me.chanjar.weixin.mp.bean.store.WxMpStoreListResult;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.util.List;
@@ -21,18 +23,15 @@ import java.util.List;
*
* @author binarywang (https://github.com/binarywang)
*/
+@RequiredArgsConstructor
public class WxMpStoreServiceImpl implements WxMpStoreService {
- private WxMpService wxMpService;
-
- public WxMpStoreServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public void add(WxMpStoreBaseInfo request) throws WxErrorException {
BeanUtils.checkRequiredFields(request);
- String response = this.wxMpService.post(POI_ADD_URL, request.toJson());
+ String response = this.wxMpService.post(WxMpApiUrl.Store.POI_ADD_URL, request.toJson());
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
@@ -43,7 +42,7 @@ public class WxMpStoreServiceImpl implements WxMpStoreService {
public WxMpStoreBaseInfo get(String poiId) throws WxErrorException {
JsonObject paramObject = new JsonObject();
paramObject.addProperty("poi_id", poiId);
- String response = this.wxMpService.post(POI_GET_URL, paramObject.toString());
+ String response = this.wxMpService.post(WxMpApiUrl.Store.POI_GET_URL, paramObject.toString());
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
@@ -56,7 +55,7 @@ public class WxMpStoreServiceImpl implements WxMpStoreService {
public void delete(String poiId) throws WxErrorException {
JsonObject paramObject = new JsonObject();
paramObject.addProperty("poi_id", poiId);
- String response = this.wxMpService.post(POI_DEL_URL, paramObject.toString());
+ String response = this.wxMpService.post(WxMpApiUrl.Store.POI_DEL_URL, paramObject.toString());
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
@@ -69,7 +68,7 @@ public class WxMpStoreServiceImpl implements WxMpStoreService {
JsonObject params = new JsonObject();
params.addProperty("begin", begin);
params.addProperty("limit", limit);
- String response = this.wxMpService.post(POI_LIST_URL, params.toString());
+ String response = this.wxMpService.post(WxMpApiUrl.Store.POI_LIST_URL, params.toString());
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
@@ -102,7 +101,7 @@ public class WxMpStoreServiceImpl implements WxMpStoreService {
@Override
public void update(WxMpStoreBaseInfo request) throws WxErrorException {
- String response = this.wxMpService.post(POI_UPDATE_URL, request.toJson());
+ String response = this.wxMpService.post(WxMpApiUrl.Store.POI_UPDATE_URL, request.toJson());
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
@@ -111,7 +110,7 @@ public class WxMpStoreServiceImpl implements WxMpStoreService {
@Override
public List listCategories() throws WxErrorException {
- String response = this.wxMpService.get(POI_GET_WX_CATEGORY_URL, null);
+ String response = this.wxMpService.get(WxMpApiUrl.Store.POI_GET_WX_CATEGORY_URL, null);
WxError wxError = WxError.fromJson(response, WxType.MP);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java
index fe1cfb30..ff99b12c 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java
@@ -1,33 +1,31 @@
package me.chanjar.weixin.mp.api.impl;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService;
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.SubscribeMsg.SEND_MESSAGE_URL;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.SubscribeMsg.SUBSCRIBE_MESSAGE_AUTHORIZE_URL;
+
/**
+ * 一次性订阅消息接口.
+ *
* @author Mklaus
* @date 2018-01-22 上午11:19
*/
+@RequiredArgsConstructor
public class WxMpSubscribeMsgServiceImpl implements WxMpSubscribeMsgService {
- private static final String SUBSCRIBE_MESSAGE_AUTHORIZE_URL =
- "https://mp.weixin.qq.com/mp/subscribemsg?action=get_confirm&appid=%s&scene=%d&template_id=%s&redirect_url=%s&reserved=%s#wechat_redirect";
- private static final String SEND_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/subscribe";
-
-
- private WxMpService wxMpService;
-
- public WxMpSubscribeMsgServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public String subscribeMsgAuthorizationUrl(String redirectURI, int scene, String reserved) {
WxMpConfigStorage storage = this.wxMpService.getWxMpConfigStorage();
- return String.format(SUBSCRIBE_MESSAGE_AUTHORIZE_URL,
- storage.getAppId(), scene, storage.getTemplateId(), URIUtil.encodeURIComponent(redirectURI), reserved);
+ return String.format(SUBSCRIBE_MESSAGE_AUTHORIZE_URL.getUrl(storage), storage.getAppId(), scene, storage.getTemplateId(),
+ URIUtil.encodeURIComponent(redirectURI), reserved);
}
@Override
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java
index 472cd0fe..4cab8d71 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java
@@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -10,9 +11,12 @@ import me.chanjar.weixin.mp.api.WxMpTemplateMsgService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplate;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import java.util.List;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.TemplateMsg.*;
+
/**
*
* Created by Binary Wang on 2016-10-14.
@@ -20,20 +24,15 @@ import java.util.List;
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService {
- public static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/template";
private static final JsonParser JSON_PARSER = new JsonParser();
- private WxMpService wxMpService;
-
- public WxMpTemplateMsgServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException {
- String url = "https://api.weixin.qq.com/cgi-bin/message/template/send";
- String responseContent = this.wxMpService.post(url, templateMessage.toJson());
+ String responseContent = this.wxMpService.post(MESSAGE_TEMPLATE_SEND, templateMessage.toJson());
final JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (jsonObject.get("errcode").getAsInt() == 0) {
return jsonObject.get("msgid").getAsString();
@@ -48,24 +47,21 @@ public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService {
throw new IllegalArgumentException("行业Id不能为空,请核实");
}
- String url = API_URL_PREFIX + "/api_set_industry";
- this.wxMpService.post(url, wxMpIndustry.toJson());
+ this.wxMpService.post(TEMPLATE_API_SET_INDUSTRY, wxMpIndustry.toJson());
return true;
}
@Override
public WxMpTemplateIndustry getIndustry() throws WxErrorException {
- String url = API_URL_PREFIX + "/get_industry";
- String responseContent = this.wxMpService.get(url, null);
+ String responseContent = this.wxMpService.get(TEMPLATE_GET_INDUSTRY, null);
return WxMpTemplateIndustry.fromJson(responseContent);
}
@Override
public String addTemplate(String shortTemplateId) throws WxErrorException {
- String url = API_URL_PREFIX + "/api_add_template";
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("template_id_short", shortTemplateId);
- String responseContent = this.wxMpService.post(url, jsonObject.toString());
+ String responseContent = this.wxMpService.post(TEMPLATE_API_ADD_TEMPLATE, jsonObject.toString());
final JsonObject result = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (result.get("errcode").getAsInt() == 0) {
return result.get("template_id").getAsString();
@@ -76,16 +72,14 @@ public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService {
@Override
public List getAllPrivateTemplate() throws WxErrorException {
- String url = API_URL_PREFIX + "/get_all_private_template";
- return WxMpTemplate.fromJson(this.wxMpService.get(url, null));
+ return WxMpTemplate.fromJson(this.wxMpService.get(TEMPLATE_GET_ALL_PRIVATE_TEMPLATE, null));
}
@Override
public boolean delPrivateTemplate(String templateId) throws WxErrorException {
- String url = API_URL_PREFIX + "/del_private_template";
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("template_id", templateId);
- String responseContent = this.wxMpService.post(url, jsonObject.toString());
+ String responseContent = this.wxMpService.post(TEMPLATE_DEL_PRIVATE_TEMPLATE, jsonObject.toString());
WxError error = WxError.fromJson(responseContent, WxType.MP);
if (error.getErrorCode() == 0) {
return true;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java
index a6ba958e..cd7ac541 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java
@@ -1,43 +1,42 @@
package me.chanjar.weixin.mp.api.impl;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService;
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.UserBlacklist.*;
+
/**
* @author miller
*/
+@RequiredArgsConstructor
public class WxMpUserBlacklistServiceImpl implements WxMpUserBlacklistService {
- private static final String API_BLACKLIST_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags/members";
- private WxMpService wxMpService;
-
- public WxMpUserBlacklistServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMpUserBlacklistGetResult getBlacklist(String nextOpenid) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("begin_openid", nextOpenid);
- String url = API_BLACKLIST_PREFIX + "/getblacklist";
- String responseContent = this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()), url, jsonObject.toString());
+ String responseContent = this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()),
+ GETBLACKLIST, jsonObject.toString());
return WxMpUserBlacklistGetResult.fromJson(responseContent);
}
@Override
public void pushToBlacklist(List openidList) throws WxErrorException {
- Map map = new HashMap<>();
+ Map map = new HashMap<>(2);
map.put("openid_list", openidList);
- String url = API_BLACKLIST_PREFIX + "/batchblacklist";
- this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()), url,
+ this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()), BATCHBLACKLIST,
WxMpGsonBuilder.create().toJson(map));
}
@@ -45,7 +44,7 @@ public class WxMpUserBlacklistServiceImpl implements WxMpUserBlacklistService {
public void pullFromBlacklist(List openidList) throws WxErrorException {
Map map = new HashMap<>(2);
map.put("openid_list", openidList);
- String url = API_BLACKLIST_PREFIX + "/batchunblacklist";
- this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()), url, WxMpGsonBuilder.create().toJson(map));
+ this.wxMpService.execute(SimplePostRequestExecutor.create(this.wxMpService.getRequestHttp()), BATCHUNBLACKLIST,
+ WxMpGsonBuilder.create().toJson(map));
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java
index d8c8943d..0c77a93f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java
@@ -1,11 +1,7 @@
package me.chanjar.weixin.mp.api.impl;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserService;
@@ -13,19 +9,23 @@ import me.chanjar.weixin.mp.bean.WxMpUserQuery;
import me.chanjar.weixin.mp.bean.result.WxMpChangeOpenid;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.User.*;
+
/**
* Created by Binary Wang on 2016/7/21.
*
* @author BinaryWang
*/
+@RequiredArgsConstructor
public class WxMpUserServiceImpl implements WxMpUserService {
- private WxMpService wxMpService;
-
- public WxMpUserServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public void userUpdateRemark(String openid, String remark) throws WxErrorException {
@@ -43,21 +43,19 @@ public class WxMpUserServiceImpl implements WxMpUserService {
@Override
public WxMpUser userInfo(String openid, String lang) throws WxErrorException {
lang = lang == null ? "zh_CN" : lang;
- String responseContent = this.wxMpService.get(USER_INFO_URL,
- "openid=" + openid + "&lang=" + lang);
+ String responseContent = this.wxMpService.get(USER_INFO_URL, "openid=" + openid + "&lang=" + lang);
return WxMpUser.fromJson(responseContent);
}
@Override
public WxMpUserList userList(String nextOpenid) throws WxErrorException {
- String responseContent = this.wxMpService.get(USER_GET_URL,
- nextOpenid == null ? null : "next_openid=" + nextOpenid);
+ String responseContent = this.wxMpService.get(USER_GET_URL, nextOpenid == null ? null : "next_openid=" + nextOpenid);
return WxMpUserList.fromJson(responseContent);
}
@Override
public List changeOpenid(String fromAppid, List openidList) throws WxErrorException {
- Map map = new HashMap<>();
+ Map map = new HashMap<>(2);
map.put("from_appid", fromAppid);
map.put("openid_list", openidList);
String responseContent = this.wxMpService.post(USER_CHANGE_OPENID_URL, WxMpGsonBuilder.create().toJson(map));
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
index 6a37741b..bf4696e4 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
@@ -4,6 +4,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -16,51 +17,43 @@ import org.apache.commons.lang3.StringUtils;
import java.util.List;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.UserTag.*;
+
/**
* Created by Binary Wang on 2016/9/2.
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpUserTagServiceImpl implements WxMpUserTagService {
- private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags";
-
- private WxMpService wxMpService;
-
- public WxMpUserTagServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxUserTag tagCreate(String name) throws WxErrorException {
- String url = API_URL_PREFIX + "/create";
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("name", name);
json.add("tag", tagJson);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_CREATE, json.toString());
return WxUserTag.fromJson(responseContent);
}
@Override
public List tagGet() throws WxErrorException {
- String url = API_URL_PREFIX + "/get";
-
- String responseContent = this.wxMpService.get(url, null);
+ String responseContent = this.wxMpService.get(TAGS_GET, null);
return WxUserTag.listFromJson(responseContent);
}
@Override
public Boolean tagUpdate(Long id, String name) throws WxErrorException {
- String url = API_URL_PREFIX + "/update";
-
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("id", id);
tagJson.addProperty("name", name);
json.add("tag", tagJson);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_UPDATE, json.toString());
WxError wxError = WxError.fromJson(responseContent, WxType.MP);
if (wxError.getErrorCode() == 0) {
return true;
@@ -71,14 +64,12 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
@Override
public Boolean tagDelete(Long id) throws WxErrorException {
- String url = API_URL_PREFIX + "/delete";
-
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("id", id);
json.add("tag", tagJson);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_DELETE, json.toString());
WxError wxError = WxError.fromJson(responseContent, WxType.MP);
if (wxError.getErrorCode() == 0) {
return true;
@@ -88,23 +79,17 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
}
@Override
- public WxTagListUser tagListUser(Long tagId, String nextOpenid)
- throws WxErrorException {
- String url = "https://api.weixin.qq.com/cgi-bin/user/tag/get";
-
+ public WxTagListUser tagListUser(Long tagId, String nextOpenid) throws WxErrorException {
JsonObject json = new JsonObject();
json.addProperty("tagid", tagId);
json.addProperty("next_openid", StringUtils.trimToEmpty(nextOpenid));
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAG_GET, json.toString());
return WxTagListUser.fromJson(responseContent);
}
@Override
- public boolean batchTagging(Long tagId, String[] openids)
- throws WxErrorException {
- String url = API_URL_PREFIX + "/members/batchtagging";
-
+ public boolean batchTagging(Long tagId, String[] openids) throws WxErrorException {
JsonObject json = new JsonObject();
json.addProperty("tagid", tagId);
JsonArray openidArrayJson = new JsonArray();
@@ -113,7 +98,7 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
}
json.add("openid_list", openidArrayJson);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_MEMBERS_BATCHTAGGING, json.toString());
WxError wxError = WxError.fromJson(responseContent, WxType.MP);
if (wxError.getErrorCode() == 0) {
return true;
@@ -123,10 +108,7 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
}
@Override
- public boolean batchUntagging(Long tagId, String[] openids)
- throws WxErrorException {
- String url = API_URL_PREFIX + "/members/batchuntagging";
-
+ public boolean batchUntagging(Long tagId, String[] openids) throws WxErrorException {
JsonObject json = new JsonObject();
json.addProperty("tagid", tagId);
JsonArray openidArrayJson = new JsonArray();
@@ -135,7 +117,7 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
}
json.add("openid_list", openidArrayJson);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_MEMBERS_BATCHUNTAGGING, json.toString());
WxError wxError = WxError.fromJson(responseContent, WxType.MP);
if (wxError.getErrorCode() == 0) {
return true;
@@ -146,12 +128,10 @@ public class WxMpUserTagServiceImpl implements WxMpUserTagService {
@Override
public List userTagList(String openid) throws WxErrorException {
- String url = API_URL_PREFIX + "/getidlist";
-
JsonObject json = new JsonObject();
json.addProperty("openid", openid);
- String responseContent = this.wxMpService.post(url, json.toString());
+ String responseContent = this.wxMpService.post(TAGS_GETIDLIST, json.toString());
return WxMpGsonBuilder.create().fromJson(
new JsonParser().parse(responseContent).getAsJsonObject().get("tagid_list"),
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java
index f87c784b..0b75bb99 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java
@@ -1,11 +1,15 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpWifiService;
+import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopDataResult;
import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Wifi.*;
+
/**
*
* Created by BinaryWang on 2018/6/10.
@@ -13,19 +17,40 @@ import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult;
*
* @author Binary Wang
*/
+@RequiredArgsConstructor
public class WxMpWifiServiceImpl implements WxMpWifiService {
- private WxMpService wxMpService;
-
- public WxMpWifiServiceImpl(WxMpService wxMpService) {
- this.wxMpService = wxMpService;
- }
+ private final WxMpService wxMpService;
@Override
public WxMpWifiShopListResult listShop(int pageIndex, int pageSize) throws WxErrorException {
JsonObject json = new JsonObject();
json.addProperty("pageindex", pageIndex);
json.addProperty("pagesize", pageSize);
- final String result = this.wxMpService.post("https://api.weixin.qq.com/bizwifi/shop/list", json.toString());
+ final String result = this.wxMpService.post(BIZWIFI_SHOP_LIST, json.toString());
return WxMpWifiShopListResult.fromJson(result);
}
+
+ @Override
+ public WxMpWifiShopDataResult getShopWifiInfo(int shopId) throws WxErrorException {
+ JsonObject json = new JsonObject();
+ json.addProperty("shop_id", shopId);
+ return WxMpWifiShopDataResult.fromJson(this.wxMpService.post(BIZWIFI_SHOP_GET, json.toString()));
+ }
+
+ @Override
+ public boolean updateShopWifiInfo(int shopId, String oldSsid, String ssid, String password) throws WxErrorException {
+ JsonObject json = new JsonObject();
+ json.addProperty("shop_id", shopId);
+ json.addProperty("old_ssid", oldSsid);
+ json.addProperty("ssid", ssid);
+ if (password != null) {
+ json.addProperty("password", password);
+ }
+ try {
+ this.wxMpService.post(BIZWIFI_SHOP_UPDATE, json.toString());
+ return true;
+ } catch (WxErrorException e) {
+ throw e;
+ }
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpHostConfig.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpHostConfig.java
new file mode 100644
index 00000000..9fff434e
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpHostConfig.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.mp.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 微信接口地址域名部分的自定义设置信息.
+ *
+ * @author Binary Wang
+ * @date 2019-06-09
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMpHostConfig {
+ public static final String API_DEFAULT_HOST_URL = "https://api.weixin.qq.com";
+ public static final String MP_DEFAULT_HOST_URL = "https://mp.weixin.qq.com";
+ public static final String OPEN_DEFAULT_HOST_URL = "https://open.weixin.qq.com";
+
+ /**
+ * 对应于:https://api.weixin.qq.com
+ */
+ private String apiHost;
+
+ /**
+ * 对应于:https://open.weixin.qq.com
+ */
+ private String openHost;
+ /**
+ * 对应于:https://mp.weixin.qq.com
+ */
+ private String mpHost;
+
+ public static String buildUrl(WxMpHostConfig hostConfig, String prefix, String path) {
+ if (hostConfig == null) {
+ return prefix + path;
+ }
+
+ if (hostConfig.getApiHost() != null && prefix.equals(API_DEFAULT_HOST_URL)) {
+ return hostConfig.getApiHost() + path;
+ }
+
+ if (hostConfig.getMpHost() != null && prefix.equals(MP_DEFAULT_HOST_URL)) {
+ return hostConfig.getMpHost() + path;
+ }
+
+ if (hostConfig.getOpenHost() != null && prefix.equals(OPEN_DEFAULT_HOST_URL)) {
+ return hostConfig.getOpenHost() + path;
+ }
+
+ return prefix + path;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java
index 0a72814a..5e0b638e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java
@@ -7,7 +7,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable;
/**
- * 按标签群发的消息
+ * 按标签群发的消息.
*
* @author chanjarster
*/
@@ -16,12 +16,12 @@ public class WxMpMassTagMessage implements Serializable {
private static final long serialVersionUID = -6625914040986749286L;
/**
- * 标签id,如果不设置则就意味着发给所有用户
+ * 标签id,如果不设置则就意味着发给所有用户.
*/
private Long tagId;
/**
*
- * 消息类型
+ * 消息类型.
* 请使用
* {@link WxConsts.MassMsgType#IMAGE}
* {@link WxConsts.MassMsgType#MPNEWS}
@@ -35,17 +35,17 @@ public class WxMpMassTagMessage implements Serializable {
private String content;
private String mediaId;
/**
- * 是否群发给所有用户
+ * 是否群发给所有用户.
*/
private boolean isSendAll = false;
/**
- * 文章被判定为转载时,是否继续进行群发操作。
+ * 文章被判定为转载时,是否继续进行群发操作.
*/
private boolean sendIgnoreReprint = false;
/**
- * 开发者侧群发msgid,长度限制64字节,如不填,则后台默认以群发范围和群发内容的摘要值做为clientmsgid
+ * 开发者侧群发msgid,长度限制64字节,如不填,则后台默认以群发范围和群发内容的摘要值做为clientmsgid.
*/
private String clientMsgId;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
index c97f88f2..50610108 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
@@ -9,11 +9,10 @@ import java.io.Serializable;
/**
* .
* @author leeis
- * @Date 2018/12/29
+ * @date 2018/12/29
*/
@Data
public class Card implements Serializable {
-
private static final long serialVersionUID = -3697110761983756780L;
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java
index 3dcbc353..8eedbebf 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java
@@ -3,11 +3,13 @@ package me.chanjar.weixin.mp.bean.card;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
- * @description 删除卡券结果
- * @author: fanxl
- * @date: 2019/1/22 0022 10:24
+ * 删除卡券结果.
+ *
+ * @author fanxl
+ * @date 2019/1/22 0022 10:24
*/
public class WxMpCardDeleteResult extends BaseWxMpCardResult {
+ private static final long serialVersionUID = -4367717540650523290L;
public static WxMpCardDeleteResult fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(json, WxMpCardDeleteResult.class);
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java
index 560add60..37beb77e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java
@@ -1,6 +1,8 @@
package me.chanjar.weixin.mp.bean.kefu;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.builder.kefu.*;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
@@ -10,7 +12,7 @@ import java.util.ArrayList;
import java.util.List;
/**
- * 客服消息
+ * 客服消息.
*
* @author chanjarster
*/
@@ -32,66 +34,80 @@ public class WxMpKefuMessage implements Serializable {
private String mpNewsMediaId;
private String miniProgramAppId;
private String miniProgramPagePath;
+ private String headContent;
+ private String tailContent;
private List articles = new ArrayList<>();
/**
- * 获得文本消息builder
+ * 菜单消息里的菜单内容.
+ */
+ private List msgMenus = new ArrayList<>();
+
+ /**
+ * 获得文本消息builder.
*/
public static TextBuilder TEXT() {
return new TextBuilder();
}
/**
- * 获得图片消息builder
+ * 获得图片消息builder.
*/
public static ImageBuilder IMAGE() {
return new ImageBuilder();
}
/**
- * 获得语音消息builder
+ * 获得语音消息builder.
*/
public static VoiceBuilder VOICE() {
return new VoiceBuilder();
}
/**
- * 获得视频消息builder
+ * 获得视频消息builder.
*/
public static VideoBuilder VIDEO() {
return new VideoBuilder();
}
/**
- * 获得音乐消息builder
+ * 获得音乐消息builder.
*/
public static MusicBuilder MUSIC() {
return new MusicBuilder();
}
/**
- * 获得图文消息(点击跳转到外链)builder
+ * 获得图文消息(点击跳转到外链)builder.
*/
public static NewsBuilder NEWS() {
return new NewsBuilder();
}
/**
- * 获得图文消息(点击跳转到图文消息页面)builder
+ * 获得图文消息(点击跳转到图文消息页面)builder.
*/
public static MpNewsBuilder MPNEWS() {
return new MpNewsBuilder();
}
/**
- * 获得卡券消息builder
+ * 获得卡券消息builder.
*/
public static WxCardBuilder WXCARD() {
return new WxCardBuilder();
}
/**
- * 小程序卡片
+ * 获得菜单消息builder.
+ */
+ public static WxMsgMenuBuilder MSGMENU() {
+ return new WxMsgMenuBuilder();
+ }
+
+ /**
+ * 小程序卡片.
*/
public static MiniProgramPageBuilder MINIPROGRAMPAGE() {
return new MiniProgramPageBuilder();
@@ -110,8 +126,8 @@ public class WxMpKefuMessage implements Serializable {
* {@link WxConsts.KefuMsgType#WXCARD}
* {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE}
* {@link WxConsts.KefuMsgType#TASKCARD}
+ * {@link WxConsts.KefuMsgType#MSGMENU}
*
- *
*/
public void setMsgType(String msgType) {
this.msgType = msgType;
@@ -122,6 +138,8 @@ public class WxMpKefuMessage implements Serializable {
}
@Data
+ @AllArgsConstructor
+ @NoArgsConstructor
public static class WxArticle implements Serializable {
private static final long serialVersionUID = 5145137235440507379L;
@@ -130,4 +148,14 @@ public class WxMpKefuMessage implements Serializable {
private String url;
private String picUrl;
}
+
+ @Data
+ @AllArgsConstructor
+ @NoArgsConstructor
+ public static class MsgMenu implements Serializable {
+ private static final long serialVersionUID = 7020769047598378839L;
+
+ private String id;
+ private String content;
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java
index 69fced90..ad5f723e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java
@@ -1,39 +1,71 @@
package me.chanjar.weixin.mp.bean.marketing;
+import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
import java.io.Serializable;
+import java.util.List;
/**
* @author 007
*/
@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
public class WxMpUserAction implements Serializable {
private static final long serialVersionUID = 7042393762652152209L;
+
private Long userActionSetId;
private String url;
- private Boolean actionTime;
+ private Integer actionTime;
private String actionType;
+ private String leadsType;
private String clickId;
private Integer actionParam;
- public JsonObject toJsonObject() {
+ private JsonObject toJsonObject() {
JsonObject json = new JsonObject();
json.addProperty("user_action_set_id", this.userActionSetId);
json.addProperty("url", this.url);
json.addProperty("action_time", this.actionTime);
+ json.addProperty("action_type", this.actionType);
+
if (this.clickId != null) {
JsonObject traceJson = new JsonObject();
traceJson.addProperty("click_id", this.clickId);
json.add("trace", traceJson);
}
+
if (this.actionParam != null) {
JsonObject actionParamJson = new JsonObject();
actionParamJson.addProperty("value", actionParam);
+ actionParamJson.addProperty("leads_type", leadsType);
json.add("action_param", actionParamJson);
}
+
return json;
}
+
+ /**
+ * list对象转换为json字符串
+ *
+ * @param actions .
+ * @return .
+ */
+ public static String listToJson(List actions) {
+ JsonArray array = new JsonArray();
+ for (WxMpUserAction action : actions) {
+ array.add(action.toJsonObject());
+ }
+
+ JsonObject result = new JsonObject();
+ result.add("actions", array);
+ return result.toString();
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java
index 4789b470..f0e0a104 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java
@@ -43,13 +43,13 @@ public class WxMpSelfMenuInfo implements Serializable {
@SerializedName("type")
private String type;
/**
- * 菜单名称
+ * 菜单名称.
*/
@SerializedName("name")
private String name;
/**
*
- * 对于不同的菜单类型,value的值意义不同。
+ * 对于不同的菜单类型,value的值意义不同.
* 官网上设置的自定义菜单:
* Text:保存文字到value;
* Img、voice:保存mediaID到value;
@@ -58,29 +58,52 @@ public class WxMpSelfMenuInfo implements Serializable {
* View:保存链接到url。
*
* 使用API设置的自定义菜单:
- * click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、 pic_weixin、location_select:保存值到key;
+ * click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、pic_weixin、location_select:保存值到key;
* view:保存链接到url
*
*/
@SerializedName("key")
private String key;
/**
+ * .
+ *
* @see #key
*/
@SerializedName("url")
private String url;
+
/**
+ * .
+ *
* @see #key
*/
@SerializedName("value")
private String value;
+
+ /**
+ *
+ * 小程序的appid.
+ * miniprogram类型必须
+ *
+ */
+ @SerializedName("appid")
+ private String appId;
+
/**
- * 子菜单信息
+ *
+ * 小程序的页面路径.
+ * miniprogram类型必须
+ *
+ */
+ @SerializedName("pagepath")
+ private String pagePath;
+ /**
+ * 子菜单信息.
*/
@SerializedName("sub_button")
private SubButtons subButtons;
/**
- * 图文消息的信息
+ * 图文消息的信息.
*/
@SerializedName("news_info")
private NewsInfo newsInfo;
@@ -116,42 +139,41 @@ public class WxMpSelfMenuInfo implements Serializable {
}
@Data
- public static class NewsInButton implements Serializable {
+ public static class NewsInButton implements Serializable {
private static final long serialVersionUID = 8701455967664912972L;
/**
- * 图文消息的标题
+ * 图文消息的标题.
*/
@SerializedName("title")
private String title;
/**
- * 摘要
+ * 摘要.
*/
@SerializedName("digest")
private String digest;
/**
- * 作者
+ * 作者.
*/
@SerializedName("author")
private String author;
/**
- * show_cover
- * 是否显示封面,0为不显示,1为显示
+ * 是否显示封面,0为不显示,1为显示.
*/
@SerializedName("show_cover")
private Integer showCover;
/**
- * 封面图片的URL
+ * 封面图片的URL.
*/
@SerializedName("cover_url")
private String coverUrl;
/**
- * 正文的URL
+ * 正文的URL.
*/
@SerializedName("content_url")
private String contentUrl;
/**
- * 原文的URL,若置空则无查看原文入口
+ * 原文的URL,若置空则无查看原文入口.
*/
@SerializedName("source_url")
private String sourceUrl;
@@ -160,7 +182,6 @@ public class WxMpSelfMenuInfo implements Serializable {
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
-
}
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
index 368f70e3..bb93976f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
@@ -15,7 +15,7 @@ import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.XmlUtils;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import me.chanjar.weixin.mp.util.xml.XStreamTransformer;
@@ -528,6 +528,14 @@ public class WxMpXmlMessage implements Serializable {
@XStreamConverter(value = XStreamCDataConverter.class)
private String deviceId;
+ /**
+ * 微信客户端生成的session id,用于request和response对应,
+ * 因此响应中该字段第三方需要原封不变的带回
+ */
+ @XStreamAlias("SessionID")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String sessionId;
+
/**
* 微信用户账号的OpenID.
*/
@@ -626,11 +634,17 @@ public class WxMpXmlMessage implements Serializable {
private String regionCode;
/**
- * 审核未通过的原因。
+ * 审核未通过的原因.
*/
@XStreamAlias("ReasonMsg")
private String reasonMsg;
+ /**
+ * 给用户发菜单消息类型的客服消息后,用户所点击的菜单ID.
+ */
+ @XStreamAlias("bizmsgmenuid")
+ private String bizMsgMenuId;
+
public static WxMpXmlMessage fromXml(String xml) {
//修改微信变态的消息内容格式,方便解析
xml = xml.replace("
+ * 用法: + * WxMpKefuMessage m = WxMpKefuMessage.MSGMENU().addMenus(lists).headContent(headContent).tailContent(tailContent).toUser(...).build(); + *+ * + * @author billytomato + */ +public final class WxMsgMenuBuilder extends BaseBuilder
+ * 公众号接口api地址 + * Created by BinaryWang on 2019-06-03. + *+ * + * @author Binary Wang + */ +public interface WxMpApiUrl { + + /** + * 得到api完整地址. + * + * @param config 微信公众号配置 + * @return api地址 + */ + String getUrl(WxMpConfigStorage config); + + @AllArgsConstructor + enum Device implements WxMpApiUrl { + /** + * get_bind_device. + */ + DEVICE_GET_BIND_DEVICE(API_DEFAULT_HOST_URL, "/device/get_bind_device"), + /** + * get_openid. + */ + DEVICE_GET_OPENID(API_DEFAULT_HOST_URL, "/device/get_openid"), + /** + * compel_unbind. + */ + DEVICE_COMPEL_UNBIND(API_DEFAULT_HOST_URL, "/device/compel_unbind?"), + /** + * unbind. + */ + DEVICE_UNBIND(API_DEFAULT_HOST_URL, "/device/unbind?"), + /** + * compel_bind. + */ + DEVICE_COMPEL_BIND(API_DEFAULT_HOST_URL, "/device/compel_bind"), + /** + * bind. + */ + DEVICE_BIND(API_DEFAULT_HOST_URL, "/device/bind"), + /** + * authorize_device. + */ + DEVICE_AUTHORIZE_DEVICE(API_DEFAULT_HOST_URL, "/device/authorize_device"), + /** + * getqrcode. + */ + DEVICE_GETQRCODE(API_DEFAULT_HOST_URL, "/device/getqrcode"), + /** + * transmsg. + */ + DEVICE_TRANSMSG(API_DEFAULT_HOST_URL, "/device/transmsg"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + + } + + @AllArgsConstructor + enum Other implements WxMpApiUrl { + /** + * 获取access_token. + */ + GET_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"), + /** + * 获得各种类型的ticket. + */ + GET_TICKET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/ticket/getticket?type="), + /** + * 长链接转短链接接口. + */ + SHORTURL_API_URL(API_DEFAULT_HOST_URL, "/cgi-bin/shorturl"), + /** + * 语义查询接口. + */ + SEMANTIC_SEMPROXY_SEARCH_URL(API_DEFAULT_HOST_URL, "/semantic/semproxy/search"), + /** + * 用code换取oauth2的access token. + */ + OAUTH2_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"), + /** + * 刷新oauth2的access token. + */ + OAUTH2_REFRESH_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"), + /** + * 用oauth2获取用户信息. + */ + OAUTH2_USERINFO_URL(API_DEFAULT_HOST_URL, "/sns/userinfo?access_token=%s&openid=%s&lang=%s"), + /** + * 验证oauth2的access token是否有效. + */ + OAUTH2_VALIDATE_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/auth?access_token=%s&openid=%s"), + /** + * 获取微信服务器IP地址. + */ + GET_CALLBACK_IP_URL(API_DEFAULT_HOST_URL, "/cgi-bin/getcallbackip"), + /** + * 第三方使用网站应用授权登录的url. + */ + QRCONNECT_URL(OPEN_DEFAULT_HOST_URL, "/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"), + /** + * oauth2授权的url连接. + */ + CONNECT_OAUTH2_AUTHORIZE_URL(OPEN_DEFAULT_HOST_URL, "/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&connect_redirect=1#wechat_redirect"), + /** + * 获取公众号的自动回复规则. + */ + GET_CURRENT_AUTOREPLY_INFO_URL(API_DEFAULT_HOST_URL, "/cgi-bin/get_current_autoreply_info"), + /** + * 公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零. + */ + CLEAR_QUOTA_URL(API_DEFAULT_HOST_URL, "/cgi-bin/clear_quota"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Marketing implements WxMpApiUrl { + /** + * sets add. + */ + USER_ACTION_SETS_ADD(API_DEFAULT_HOST_URL, "/marketing/user_action_sets/add?version=v1.0"), + /** + * get. + */ + USER_ACTION_SETS_GET(API_DEFAULT_HOST_URL, "/marketing/user_action_sets/get"), + /** + * add. + */ + USER_ACTIONS_ADD(API_DEFAULT_HOST_URL, "/marketing/user_actions/add?version=v1.0"), + /** + * get. + */ + WECHAT_AD_LEADS_GET(API_DEFAULT_HOST_URL, "/marketing/wechat_ad_leads/get"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Menu implements WxMpApiUrl { + /** + * get_current_selfmenu_info. + */ + GET_CURRENT_SELFMENU_INFO(API_DEFAULT_HOST_URL, "/cgi-bin/get_current_selfmenu_info"), + /** + * trymatch. + */ + MENU_TRYMATCH(API_DEFAULT_HOST_URL, "/cgi-bin/menu/trymatch"), + /** + * get. + */ + MENU_GET(API_DEFAULT_HOST_URL, "/cgi-bin/menu/get"), + /** + * delconditional. + */ + MENU_DELCONDITIONAL(API_DEFAULT_HOST_URL, "/cgi-bin/menu/delconditional"), + /** + * delete. + */ + MENU_DELETE(API_DEFAULT_HOST_URL, "/cgi-bin/menu/delete"), + /** + * create. + */ + MENU_CREATE(API_DEFAULT_HOST_URL, "/cgi-bin/menu/create"), + /** + * addconditional. + */ + MENU_ADDCONDITIONAL(API_DEFAULT_HOST_URL, "/cgi-bin/menu/addconditional"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + + @AllArgsConstructor + enum Qrcode implements WxMpApiUrl { + /** + * create. + */ + QRCODE_CREATE(API_DEFAULT_HOST_URL, "/cgi-bin/qrcode/create"), + /** + * showqrcode. + */ + SHOW_QRCODE(MP_DEFAULT_HOST_URL, "/cgi-bin/showqrcode"), + /** + * showqrcode. + */ + SHOW_QRCODE_WITH_TICKET(MP_DEFAULT_HOST_URL, "/cgi-bin/showqrcode?ticket=%s"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum ShakeAround implements WxMpApiUrl { + /** + * getshakeinfo. + */ + SHAKEAROUND_USER_GETSHAKEINFO(API_DEFAULT_HOST_URL, "/shakearound/user/getshakeinfo"), + /** + * add. + */ + SHAKEAROUND_PAGE_ADD(API_DEFAULT_HOST_URL, "/shakearound/page/add"), + /** + * bindpage. + */ + SHAKEAROUND_DEVICE_BINDPAGE(API_DEFAULT_HOST_URL, "/shakearound/device/bindpage"), + /** + * search. + */ + SHAKEAROUND_RELATION_SEARCH(API_DEFAULT_HOST_URL, "/shakearound/relation/search"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum SubscribeMsg implements WxMpApiUrl { + /** + * subscribemsg. + */ + SUBSCRIBE_MESSAGE_AUTHORIZE_URL(MP_DEFAULT_HOST_URL, "/mp/subscribemsg?action=get_confirm&appid=%s&scene=%d&template_id=%s&redirect_url=%s&reserved=%s#wechat_redirect"), + /** + * subscribe. + */ + SEND_MESSAGE_URL(API_DEFAULT_HOST_URL, "/cgi-bin/message/template/subscribe"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum TemplateMsg implements WxMpApiUrl { + /** + * send. + */ + MESSAGE_TEMPLATE_SEND(API_DEFAULT_HOST_URL, "/cgi-bin/message/template/send"), + /** + * api_set_industry. + */ + TEMPLATE_API_SET_INDUSTRY(API_DEFAULT_HOST_URL, "/cgi-bin/template/api_set_industry"), + /** + * get_industry. + */ + TEMPLATE_GET_INDUSTRY(API_DEFAULT_HOST_URL, "/cgi-bin/template/get_industry"), + /** + * api_add_template. + */ + TEMPLATE_API_ADD_TEMPLATE(API_DEFAULT_HOST_URL, "/cgi-bin/template/api_add_template"), + /** + * get_all_private_template. + */ + TEMPLATE_GET_ALL_PRIVATE_TEMPLATE(API_DEFAULT_HOST_URL, "/cgi-bin/template/get_all_private_template"), + /** + * del_private_template. + */ + TEMPLATE_DEL_PRIVATE_TEMPLATE(API_DEFAULT_HOST_URL, "/cgi-bin/template/del_private_template"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum UserBlacklist implements WxMpApiUrl { + /** + * getblacklist. + */ + GETBLACKLIST(API_DEFAULT_HOST_URL, "/cgi-bin/tags/members/getblacklist"), + /** + * batchblacklist. + */ + BATCHBLACKLIST(API_DEFAULT_HOST_URL, "/cgi-bin/tags/members/batchblacklist"), + /** + * batchunblacklist. + */ + BATCHUNBLACKLIST(API_DEFAULT_HOST_URL, "/cgi-bin/tags/members/batchunblacklist"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum UserTag implements WxMpApiUrl { + /** + * create. + */ + TAGS_CREATE(API_DEFAULT_HOST_URL, "/cgi-bin/tags/create"), + /** + * get. + */ + TAGS_GET(API_DEFAULT_HOST_URL, "/cgi-bin/tags/get"), + /** + * update. + */ + TAGS_UPDATE(API_DEFAULT_HOST_URL, "/cgi-bin/tags/update"), + /** + * delete. + */ + TAGS_DELETE(API_DEFAULT_HOST_URL, "/cgi-bin/tags/delete"), + /** + * get. + */ + TAG_GET(API_DEFAULT_HOST_URL, "/cgi-bin/user/tag/get"), + /** + * batchtagging. + */ + TAGS_MEMBERS_BATCHTAGGING(API_DEFAULT_HOST_URL, "/cgi-bin/tags/members/batchtagging"), + /** + * batchuntagging. + */ + TAGS_MEMBERS_BATCHUNTAGGING(API_DEFAULT_HOST_URL, "/cgi-bin/tags/members/batchuntagging"), + /** + * getidlist. + */ + TAGS_GETIDLIST(API_DEFAULT_HOST_URL, "/cgi-bin/tags/getidlist"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Wifi implements WxMpApiUrl { + /** + * list. + */ + BIZWIFI_SHOP_LIST(API_DEFAULT_HOST_URL, "/bizwifi/shop/list"), + + /** + * get. + */ + BIZWIFI_SHOP_GET(API_DEFAULT_HOST_URL, "/bizwifi/shop/get"), + + /** + * upadte. + */ + BIZWIFI_SHOP_UPDATE(API_DEFAULT_HOST_URL, "/bizwifi/shop/update"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum AiOpen implements WxMpApiUrl { + /** + * translatecontent. + */ + TRANSLATE_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/voice/translatecontent?lfrom=%s<o=%s"), + /** + * addvoicetorecofortext. + */ + VOICE_UPLOAD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/voice/addvoicetorecofortext?format=%s&voice_id=%s&lang=%s"), + /** + * queryrecoresultfortext. + */ + VOICE_QUERY_RESULT_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/voice/queryrecoresultfortext"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Ocr implements WxMpApiUrl { + /** + * 身份证识别. + */ + IDCARD(API_DEFAULT_HOST_URL, "/cv/ocr/idcard?type=%s&img_url=%s"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + if (config == null) { + return buildUrl(null, prefix, path); + } + + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Card implements WxMpApiUrl { + /** + * create. + */ + CARD_CREATE(API_DEFAULT_HOST_URL, "/card/create"), + /** + * get. + */ + CARD_GET(API_DEFAULT_HOST_URL, "/card/get"), + /** + * wx_card. + */ + CARD_GET_TICKET(API_DEFAULT_HOST_URL, "/cgi-bin/ticket/getticket?type=wx_card"), + /** + * decrypt. + */ + CARD_CODE_DECRYPT(API_DEFAULT_HOST_URL, "/card/code/decrypt"), + /** + * get. + */ + CARD_CODE_GET(API_DEFAULT_HOST_URL, "/card/code/get"), + /** + * consume. + */ + CARD_CODE_CONSUME(API_DEFAULT_HOST_URL, "/card/code/consume"), + /** + * mark. + */ + CARD_CODE_MARK(API_DEFAULT_HOST_URL, "/card/code/mark"), + /** + * set. + */ + CARD_TEST_WHITELIST(API_DEFAULT_HOST_URL, "/card/testwhitelist/set"), + /** + * create. + */ + CARD_QRCODE_CREATE(API_DEFAULT_HOST_URL, "/card/qrcode/create"), + /** + * create. + */ + CARD_LANDING_PAGE_CREATE(API_DEFAULT_HOST_URL, "/card/landingpage/create"), + /** + * 将用户的卡券设置为失效状态. + */ + CARD_CODE_UNAVAILABLE(API_DEFAULT_HOST_URL, "/card/code/unavailable"), + /** + * 卡券删除. + */ + CARD_DELETE(API_DEFAULT_HOST_URL, "/card/delete"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum DataCube implements WxMpApiUrl { + /** + * getusersummary. + */ + GET_USER_SUMMARY(API_DEFAULT_HOST_URL, "/datacube/getusersummary"), + /** + * getusercumulate. + */ + GET_USER_CUMULATE(API_DEFAULT_HOST_URL, "/datacube/getusercumulate"), + /** + * getarticlesummary. + */ + GET_ARTICLE_SUMMARY(API_DEFAULT_HOST_URL, "/datacube/getarticlesummary"), + /** + * getarticletotal. + */ + GET_ARTICLE_TOTAL(API_DEFAULT_HOST_URL, "/datacube/getarticletotal"), + /** + * getuserread. + */ + GET_USER_READ(API_DEFAULT_HOST_URL, "/datacube/getuserread"), + /** + * getuserreadhour. + */ + GET_USER_READ_HOUR(API_DEFAULT_HOST_URL, "/datacube/getuserreadhour"), + /** + * getusershare. + */ + GET_USER_SHARE(API_DEFAULT_HOST_URL, "/datacube/getusershare"), + /** + * getusersharehour. + */ + GET_USER_SHARE_HOUR(API_DEFAULT_HOST_URL, "/datacube/getusersharehour"), + /** + * getupstreammsg. + */ + GET_UPSTREAM_MSG(API_DEFAULT_HOST_URL, "/datacube/getupstreammsg"), + /** + * getupstreammsghour. + */ + GET_UPSTREAM_MSG_HOUR(API_DEFAULT_HOST_URL, "/datacube/getupstreammsghour"), + /** + * getupstreammsgweek. + */ + GET_UPSTREAM_MSG_WEEK(API_DEFAULT_HOST_URL, "/datacube/getupstreammsgweek"), + /** + * getupstreammsgmonth. + */ + GET_UPSTREAM_MSG_MONTH(API_DEFAULT_HOST_URL, "/datacube/getupstreammsgmonth"), + /** + * getupstreammsgdist. + */ + GET_UPSTREAM_MSG_DIST(API_DEFAULT_HOST_URL, "/datacube/getupstreammsgdist"), + /** + * getupstreammsgdistweek. + */ + GET_UPSTREAM_MSG_DIST_WEEK(API_DEFAULT_HOST_URL, "/datacube/getupstreammsgdistweek"), + /** + * getupstreammsgdistmonth. + */ + GET_UPSTREAM_MSG_DIST_MONTH(API_DEFAULT_HOST_URL, "/datacube/getupstreammsgdistmonth"), + /** + * getinterfacesummary. + */ + GET_INTERFACE_SUMMARY(API_DEFAULT_HOST_URL, "/datacube/getinterfacesummary"), + /** + * getinterfacesummaryhour. + */ + GET_INTERFACE_SUMMARY_HOUR(API_DEFAULT_HOST_URL, "/datacube/getinterfacesummaryhour"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Kefu implements WxMpApiUrl { + /** + * send. + */ + MESSAGE_CUSTOM_SEND(API_DEFAULT_HOST_URL, "/cgi-bin/message/custom/send"), + /** + * getkflist. + */ + GET_KF_LIST(API_DEFAULT_HOST_URL, "/cgi-bin/customservice/getkflist"), + /** + * getonlinekflist. + */ + GET_ONLINE_KF_LIST(API_DEFAULT_HOST_URL, "/cgi-bin/customservice/getonlinekflist"), + /** + * add. + */ + KFACCOUNT_ADD(API_DEFAULT_HOST_URL, "/customservice/kfaccount/add"), + /** + * update. + */ + KFACCOUNT_UPDATE(API_DEFAULT_HOST_URL, "/customservice/kfaccount/update"), + /** + * inviteworker. + */ + KFACCOUNT_INVITE_WORKER(API_DEFAULT_HOST_URL, "/customservice/kfaccount/inviteworker"), + /** + * uploadheadimg. + */ + KFACCOUNT_UPLOAD_HEAD_IMG(API_DEFAULT_HOST_URL, "/customservice/kfaccount/uploadheadimg?kf_account=%s"), + /** + * del kfaccount. + */ + KFACCOUNT_DEL(API_DEFAULT_HOST_URL, "/customservice/kfaccount/del?kf_account=%s"), + /** + * create. + */ + KFSESSION_CREATE(API_DEFAULT_HOST_URL, "/customservice/kfsession/create"), + /** + * close. + */ + KFSESSION_CLOSE(API_DEFAULT_HOST_URL, "/customservice/kfsession/close"), + /** + * getsession. + */ + KFSESSION_GET_SESSION(API_DEFAULT_HOST_URL, "/customservice/kfsession/getsession?openid=%s"), + /** + * getsessionlist. + */ + KFSESSION_GET_SESSION_LIST(API_DEFAULT_HOST_URL, "/customservice/kfsession/getsessionlist?kf_account=%s"), + /** + * getwaitcase. + */ + KFSESSION_GET_WAIT_CASE(API_DEFAULT_HOST_URL, "/customservice/kfsession/getwaitcase"), + /** + * getmsglist. + */ + MSG_RECORD_LIST(API_DEFAULT_HOST_URL, "/customservice/msgrecord/getmsglist"), + /** + * typing. + */ + CUSTOM_TYPING(API_DEFAULT_HOST_URL, "/cgi-bin/message/custom/typing"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum MassMessage implements WxMpApiUrl { + /** + * 上传群发用的图文消息. + */ + MEDIA_UPLOAD_NEWS_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/uploadnews"), + /** + * 上传群发用的视频. + */ + MEDIA_UPLOAD_VIDEO_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/uploadvideo"), + /** + * 分组群发消息. + */ + MESSAGE_MASS_SENDALL_URL(API_DEFAULT_HOST_URL, "/cgi-bin/message/mass/sendall"), + /** + * 按openId列表群发消息. + */ + MESSAGE_MASS_SEND_URL(API_DEFAULT_HOST_URL, "/cgi-bin/message/mass/send"), + /** + * 群发消息预览接口. + */ + MESSAGE_MASS_PREVIEW_URL(API_DEFAULT_HOST_URL, "/cgi-bin/message/mass/preview"), + /** + * 删除群发接口. + */ + MESSAGE_MASS_DELETE_URL(API_DEFAULT_HOST_URL, "/cgi-bin/message/mass/delete"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Material implements WxMpApiUrl { + /** + * get. + */ + MEDIA_GET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/get"), + /** + * upload. + */ + MEDIA_UPLOAD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/upload?type=%s"), + /** + * uploadimg. + */ + IMG_UPLOAD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/uploadimg"), + /** + * add_material. + */ + MATERIAL_ADD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/add_material?type=%s"), + /** + * add_news. + */ + NEWS_ADD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/add_news"), + /** + * get_material. + */ + MATERIAL_GET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/get_material"), + /** + * update_news. + */ + NEWS_UPDATE_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/update_news"), + /** + * del_material. + */ + MATERIAL_DEL_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/del_material"), + /** + * get_materialcount. + */ + MATERIAL_GET_COUNT_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/get_materialcount"), + /** + * batchget_material. + */ + MATERIAL_BATCHGET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/material/batchget_material"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum MemberCard implements WxMpApiUrl { + /** + * create. + */ + MEMBER_CARD_CREATE(API_DEFAULT_HOST_URL, "/card/create"), + /** + * activate. + */ + MEMBER_CARD_ACTIVATE(API_DEFAULT_HOST_URL, "/card/membercard/activate"), + /** + * get userinfo. + */ + MEMBER_CARD_USER_INFO_GET(API_DEFAULT_HOST_URL, "/card/membercard/userinfo/get"), + /** + * updateuser. + */ + MEMBER_CARD_UPDATE_USER(API_DEFAULT_HOST_URL, "/card/membercard/updateuser"), + /** + * 会员卡激活之微信开卡接口(wx_activate=true情况调用). + */ + MEMBER_CARD_ACTIVATE_USER_FORM(API_DEFAULT_HOST_URL, "/card/membercard/activateuserform/set"), + /** + * 获取会员卡开卡插件参数. + */ + MEMBER_CARD_ACTIVATE_URL(API_DEFAULT_HOST_URL, "/card/membercard/activate/geturl"), + /** + * 会员卡信息更新. + */ + MEMBER_CARD_UPDATE(API_DEFAULT_HOST_URL, "/card/update"), + /** + * 跳转型会员卡开卡字段. + * 获取用户提交资料(wx_activate=true情况调用),开发者根据activate_ticket获取到用户填写的信息 + */ + MEMBER_CARD_ACTIVATE_TEMP_INFO(API_DEFAULT_HOST_URL, "/card/membercard/activatetempinfo/get"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Store implements WxMpApiUrl { + /** + * getwxcategory. + */ + POI_GET_WX_CATEGORY_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/getwxcategory"), + /** + * updatepoi. + */ + POI_UPDATE_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/updatepoi"), + /** + * getpoilist. + */ + POI_LIST_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/getpoilist"), + /** + * delpoi. + */ + POI_DEL_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/delpoi"), + /** + * getpoi. + */ + POI_GET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/getpoi"), + /** + * addpoi. + */ + POI_ADD_URL(API_DEFAULT_HOST_URL, "/cgi-bin/poi/addpoi"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum User implements WxMpApiUrl { + /** + * batchget. + */ + USER_INFO_BATCH_GET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/user/info/batchget"), + /** + * get. + */ + USER_GET_URL(API_DEFAULT_HOST_URL, "/cgi-bin/user/get"), + /** + * info. + */ + USER_INFO_URL(API_DEFAULT_HOST_URL, "/cgi-bin/user/info"), + /** + * updateremark. + */ + USER_INFO_UPDATE_REMARK_URL(API_DEFAULT_HOST_URL, "/cgi-bin/user/info/updateremark"), + /** + * changeopenid. + */ + USER_CHANGE_OPENID_URL(API_DEFAULT_HOST_URL, "/cgi-bin/changeopenid"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } + + @AllArgsConstructor + enum Comment implements WxMpApiUrl { + /** + * 打开已群发文章评论. + */ + OPEN(API_DEFAULT_HOST_URL, "/cgi-bin/comment/open"); + + private String prefix; + private String path; + + @Override + public String getUrl(WxMpConfigStorage config) { + return buildUrl(config.getHostConfig(), prefix, path); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java index d95e8f8f..945219ac 100755 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/crypto/WxMpCryptUtil.java @@ -17,7 +17,7 @@ */ package me.chanjar.weixin.mp.util.crypto; -import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; import org.apache.commons.codec.binary.Base64; public class WxMpCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index b16775b4..1d1ae909 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -17,6 +17,9 @@ import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; +/** + * @author someone + */ public class WxMpGsonBuilder { private static final GsonBuilder INSTANCE = new GsonBuilder(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java index 63389866..e9e5112d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java @@ -1,7 +1,6 @@ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; -import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; import org.apache.commons.lang3.StringUtils; @@ -16,77 +15,89 @@ public class WxMpKefuMessageGsonAdapter implements JsonSerializer
@@ -26,6 +32,66 @@ public class WxMpWifiServiceImplTest {
@Test
public void testListShop() throws WxErrorException {
final WxMpWifiShopListResult result = this.wxService.getWifiService().listShop(1, 2);
+ assertThat(result).isNotNull();
System.out.println(result);
}
+
+ @Test
+ public void testGetShopWifiInfo() throws WxErrorException {
+ final WxMpWifiShopDataResult wifiInfo = this.wxService.getWifiService().getShopWifiInfo(123);
+ assertThat(wifiInfo).isNotNull();
+ System.out.println(wifiInfo);
+ }
+
+ @Test
+ public void testUpdateShopWifiInfo() throws WxErrorException {
+ final boolean result = this.wxService.getWifiService()
+ .updateShopWifiInfo(123, "123", "345", null);
+ assertThat(result).isTrue();
+ }
+
+ public static class MockTest {
+ private WxMpService wxService = mock(WxMpService.class);
+
+ @Test
+ public void testGetShopWifiInfo() throws Exception {
+ String returnJson = "{\n" +
+ " \"errcode\": 0,\n" +
+ " \"data\": {\n" +
+ " \"shop_name\": \"南山店\",\n" +
+ " \"ssid\": \" WX123\",\n" +
+ " \"ssid_list\": [\n" +
+ " \"WX123\",\n" +
+ " \"WX456\"\n" +
+ " ],\n" +
+ " \"ssid_password_list\": [\n" +
+ " {\n" +
+ " \"ssid\": \"WX123\",\n" +
+ " \"password\": \"123456789\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"ssid\": \"WX456\",\n" +
+ " \"password\": \"21332465dge\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"password\": \"123456789\",\n" +
+ " \"protocol_type\": 4,\n" +
+ " \"ap_count\": 2,\n" +
+ " \"template_id\": 1,\n" +
+ " \"homepage_url\": \"http://www.weixin.qq.com/\",\n" +
+ " \"bar_type\": 1,\n" +
+ " \"sid\":\"\",\n" +
+ " \"poi_id\":\"285633617\"\n" +
+ " }\n" +
+ "}";
+
+ when(wxService.post(eq(BIZWIFI_SHOP_GET), anyString())).thenReturn(returnJson);
+ when(wxService.getWifiService()).thenReturn(new WxMpWifiServiceImpl(wxService));
+
+ final WxMpWifiShopDataResult wifiInfo = this.wxService.getWifiService().getShopWifiInfo(123);
+ assertThat(wifiInfo).isNotNull();
+ System.out.println(wifiInfo);
+
+ }
+ }
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
index 29c8d2e2..cc964e80 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
@@ -12,7 +12,7 @@ import com.google.inject.Binder;
import com.google.inject.Module;
import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
public class ApiTestModule implements Module {
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java
index ed6c5cb1..5266beb2 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java
@@ -1,13 +1,13 @@
package me.chanjar.weixin.mp.api.test;
import com.thoughtworks.xstream.annotations.XStreamAlias;
-import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.concurrent.locks.Lock;
@XStreamAlias("xml")
-public class TestConfigStorage extends WxMpInMemoryConfigStorage {
+public class TestConfigStorage extends WxMpDefaultConfigImpl {
private String openid;
private String kfAccount;
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java
index 4f983dde..ec754875 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java
@@ -141,7 +141,6 @@ public class WxMpKefuMessageTest {
}
public void testMiniProgramPageBuild() {
-
WxMpKefuMessage reply = WxMpKefuMessage.MINIPROGRAMPAGE()
.toUser("OPENID")
.title("title")
@@ -154,4 +153,17 @@ public class WxMpKefuMessageTest {
"{\"touser\":\"OPENID\",\"msgtype\":\"miniprogrampage\",\"miniprogrampage\":{\"title\":\"title\",\"appid\":\"appid\",\"pagepath\":\"pagepath\",\"thumb_media_id\":\"thumb_media_id\"}}");
}
+ public void testMsgMenuBuild() {
+ WxMpKefuMessage reply = WxMpKefuMessage.MSGMENU()
+ .toUser("OPENID")
+ .addMenus(new WxMpKefuMessage.MsgMenu("101", "msgmenu1"),
+ new WxMpKefuMessage.MsgMenu("102", "msgmenu2"))
+ .headContent("head_content")
+ .tailContent("tail_content")
+ .build();
+
+ Assert.assertEquals(reply.toJson(),
+ "{\"touser\":\"OPENID\",\"msgtype\":\"msgmenu\",\"msgmenu\":{\"head_content\":\"head_content\",\"list\":[{\"id\":\"101\",\"content\":\"msgmenu1\"},{\"id\":\"102\",\"content\":\"msgmenu2\"}],\"tail_content\":\"tail_content\"}}");
+ }
+
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionTest.java
new file mode 100644
index 00000000..3d18b1eb
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionTest.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.mp.bean.marketing;
+
+import com.google.common.collect.Lists;
+import org.testng.annotations.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * 老板加点注释吧.
+ *
+ * @author Binary Wang
+ * @date 2019-07-14
+ */
+public class WxMpUserActionTest {
+
+ @Test
+ public void testListToJson() {
+ assertThat(WxMpUserAction.listToJson(Lists.newArrayList(WxMpUserAction.builder()
+ .actionParam(1)
+ .actionTime(122)
+ .actionType("haha")
+ .clickId("111")
+ .url("1222")
+ .userActionSetId(111L)
+ .build()
+ ))).isEqualTo("{\"actions\":[{\"user_action_set_id\":111,\"url\":\"1222\",\"action_time\":122,\"action_type\":\"haha\",\"trace\":{\"click_id\":\"111\"},\"action_param\":{\"value\":1}}]}");
+ }
+}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResultTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResultTest.java
new file mode 100644
index 00000000..3df57427
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResultTest.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.mp.bean.menu;
+
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.testng.Assert.*;
+
+/**
+ * @author Binary Wang
+ * @date 2019-08-05
+ */
+public class WxMpGetSelfMenuInfoResultTest {
+
+ @Test
+ public void testFromJson() {
+ String json = "{\"is_menu_open\":1,\"selfmenu_info\":{\"button\":[{\"name\":\"学院\",\"sub_button\":{\"list\":[{\"type\":\"miniprogram\",\"name\":\"成语答题王\",\"url\":\"http:\\/\\/host\",\"appid\":\"wxf4dc5b4e7b35dcd1\",\"pagepath\":\"pages\\/index\\/index\"},{\"type\":\"miniprogram\",\"name\":\"大师课程\",\"url\":\"https:\\/\\/host\\/course\\/tutorial\",\"appid\":\"wxfd6acd566482c6cb\",\"pagepath\":\"pages\\/tutorialDetail\\/tutorialDetail\"}]}},{\"type\":\"miniprogram\",\"name\":\"学科商城\",\"url\":\"https:\\/\\/host\\/-dAEuY\",\"appid\":\"wx720f9f1301595564\",\"pagepath\":\"pages\\/home\\/dashboard\\/index\"}]}}";
+ final WxMpGetSelfMenuInfoResult selfMenuInfoResult = WxMpGetSelfMenuInfoResult.fromJson(json);
+ assertThat(selfMenuInfoResult).isNotNull();
+ assertThat(selfMenuInfoResult.getIsMenuOpen()).isEqualTo(1);
+ assertThat(selfMenuInfoResult.getSelfMenuInfo()).isNotNull();
+ final List buttons = selfMenuInfoResult.getSelfMenuInfo().getButtons();
+ assertThat(buttons.size()).isEqualTo(2);
+ assertThat(buttons.get(1).getAppId()).isEqualTo("wx720f9f1301595564");
+ assertThat(buttons.get(1).getPagePath()).isEqualTo("pages/home/dashboard/index");
+ }
+}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
index 30d36920..535123bd 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
@@ -6,13 +6,13 @@ import java.util.concurrent.locks.ReentrantLock;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
/**
* @author Daniel Qian
*/
@XStreamAlias("xml")
-class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
+class WxMpDemoInMemoryConfigStorage extends WxMpDefaultConfigImpl {
private static final long serialVersionUID = -3706236839197109704L;
public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) {
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
index d2f4fde8..36f81ae4 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.mp.demo;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -27,13 +27,11 @@ public class WxMpDemoServer {
ServletHandler servletHandler = new ServletHandler();
server.setHandler(servletHandler);
- ServletHolder endpointServletHolder = new ServletHolder(
- new WxMpEndpointServlet(wxMpConfigStorage, wxMpService,
- wxMpMessageRouter));
+ ServletHolder endpointServletHolder = new ServletHolder(new WxMpEndpointServlet(wxMpConfigStorage, wxMpService,
+ wxMpMessageRouter));
servletHandler.addServletWithMapping(endpointServletHolder, "/*");
- ServletHolder oauthServletHolder = new ServletHolder(
- new WxMpOAuth2Servlet(wxMpService));
+ ServletHolder oauthServletHolder = new ServletHolder(new WxMpOAuth2Servlet(wxMpService));
servletHandler.addServletWithMapping(oauthServletHolder, "/oauth2/*");
server.start();
@@ -41,10 +39,8 @@ public class WxMpDemoServer {
}
private static void initWeixin() {
- try (InputStream is1 = ClassLoader
- .getSystemResourceAsStream("test-config.xml")) {
- WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage
- .fromXml(is1);
+ try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) {
+ WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1);
wxMpConfigStorage = config;
wxMpService = new WxMpServiceHttpClientImpl();
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java
index 3f32d9c9..e835e637 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.mp.demo;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index a624a38c..7a2c2457 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 3.4.0
+ 3.5.0
weixin-java-open
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
index 4b2ddbc4..2beec638 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
@@ -7,10 +7,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.open.bean.WxOpenCreateResult;
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
-import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
-import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult;
-import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
-import me.chanjar.weixin.open.bean.result.WxOpenResult;
+import me.chanjar.weixin.open.bean.result.*;
import java.util.List;
@@ -25,6 +22,7 @@ public interface WxOpenComponentService {
String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info";
String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option";
String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option";
+ String API_GET_AUTHORIZER_LIST = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_list?component_access_token=%s";
String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=xxx&biz_appid=xxx";
@@ -126,6 +124,11 @@ public interface WxOpenComponentService {
*/
WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException;
+ /**
+ * 获取所有授权方列表
+ */
+ WxOpenAuthorizerListResult getAuthorizerList(int begin, int len) throws WxErrorException;
+
/**
* 设置授权方的选项信息
*/
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
index 066cf8c0..40833c1b 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
@@ -2,7 +2,7 @@ package me.chanjar.weixin.open.api;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken;
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
index 64db79b9..c6fd7671 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
@@ -52,7 +52,7 @@ public interface WxOpenFastMaService extends WxMaService {
/**
* 7 换绑小程序管理员接口
*/
- String OPEN_COMPONENT_REBIND_ADMIN = "https://api.weixin.qq.com/cgi- bin/account/componentrebindadmin";
+ String OPEN_COMPONENT_REBIND_ADMIN = "https://api.weixin.qq.com/cgi-bin/account/componentrebindadmin";
/**
* 8.1 获取账号可以设置的所有类目
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
index 319e12ff..03d072cd 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
@@ -18,10 +18,7 @@ import me.chanjar.weixin.open.bean.WxOpenCreateResult;
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
-import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
-import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult;
-import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
-import me.chanjar.weixin.open.bean.result.WxOpenResult;
+import me.chanjar.weixin.open.bean.result.*;
import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -304,6 +301,31 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerInfoResult.class);
}
+ @Override
+ public WxOpenAuthorizerListResult getAuthorizerList(int begin, int len) throws WxErrorException {
+
+ String url = String.format(API_GET_AUTHORIZER_LIST, getComponentAccessToken(false));
+ begin = begin < 0 ? 0 : begin;
+ len = len == 0 ? 10 : len;
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId());
+ jsonObject.addProperty("offset", begin);
+ jsonObject.addProperty("count", len);
+ String responseContent = post(url, jsonObject.toString());
+ WxOpenAuthorizerListResult ret = WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerListResult.class);
+ if(ret != null && ret.getList() != null){
+ for(Map data : ret.getList()){
+ String authorizerAppid = data.get("authorizer_appid");
+ String refreshToken = data.get("refresh_token");
+ if(authorizerAppid != null && refreshToken != null){
+ this.getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizerAppid, refreshToken);
+ }
+ }
+ }
+ return ret;
+ }
+
@Override
public WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java
index 1314f37f..e72fb02b 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java
@@ -208,7 +208,7 @@ public class WxOpenFastMaServiceImpl extends WxMaServiceImpl implements WxOpenFa
public WxOpenResult deleteCategory (int first, int second) throws WxErrorException {
JsonObject params = new JsonObject ();
params.addProperty ("first", first);
- params.addProperty ("Second", second);
+ params.addProperty ("second", second);
String response = post (OPEN_DELETE_CATEGORY, GSON.toJson (params));
return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class);
}
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
index da34e808..80882b0c 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
@@ -10,7 +10,8 @@ import java.util.concurrent.locks.ReentrantLock;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import me.chanjar.weixin.mp.bean.WxMpHostConfig;
import me.chanjar.weixin.mp.enums.TicketType;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
@@ -543,10 +544,14 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
return wxOpenConfigStorage.getApacheHttpClientBuilder();
}
-
@Override
public boolean autoRefreshToken() {
return true;
}
+
+ @Override
+ public WxMpHostConfig getHostConfig() {
+ return null;
+ }
}
}
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java
index a946fb70..aa845fb2 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.open.api.impl;
import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.open.api.WxOpenComponentService;
@@ -9,7 +9,7 @@ import me.chanjar.weixin.open.api.WxOpenComponentService;
/**
* @author 007
*/
-/* package */ class WxOpenMpServiceImpl extends WxMpServiceImpl {
+public class WxOpenMpServiceImpl extends WxMpServiceImpl {
private WxOpenComponentService wxOpenComponentService;
private WxMpConfigStorage wxMpConfigStorage;
private String appId;
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java
index d9b7b495..24ee39cc 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java
@@ -6,7 +6,6 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
-import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerListResult.java
new file mode 100644
index 00000000..afe9ea94
--- /dev/null
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerListResult.java
@@ -0,0 +1,15 @@
+package me.chanjar.weixin.open.bean.result;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author robgao
+ */
+@Data
+public class WxOpenAuthorizerListResult {
+ private int totalCount;
+ private List