diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGroupService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGroupService.java new file mode 100644 index 00000000..80cadd55 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGroupService.java @@ -0,0 +1,69 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.WxMpGroup; + +import java.util.List; + +/** + * 用户分组相关操作接口 + * @author Binary Wang + * + */ +public interface WxMpGroupService { + + + /** + *
+   * 分组管理接口 - 创建分组
+   * 最多支持创建500个分组
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
+   * 
+ * + * @param name 分组名字(30个字符以内) + */ + public WxMpGroup groupCreate(String name) throws WxErrorException; + + /** + *
+   * 分组管理接口 - 查询所有分组
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
+   * 
+ */ + public List groupGet() throws WxErrorException; + + /** + *
+   * 分组管理接口 - 查询用户所在分组
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
+   * 
+ * + * @param openid 微信用户的openid + */ + public long userGetGroup(String openid) throws WxErrorException; + + /** + *
+   * 分组管理接口 - 修改分组名
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
+   *
+   * 如果id为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
+   * 
+ * + * @param group 要更新的group,group的id,name必须设置 + */ + public void groupUpdate(WxMpGroup group) throws WxErrorException; + + /** + *
+   * 分组管理接口 - 移动用户分组
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
+   *
+   * 如果to_groupid为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
+   * 
+ * + * @param openid 用户openid + * @param to_groupid 移动到的分组id + */ + public void userUpdateGroup(String openid, long to_groupid) throws WxErrorException; +} 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 7e14cb8f..c4731cb5 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 @@ -1,23 +1,24 @@ package me.chanjar.weixin.mp.api; -import java.io.File; -import java.util.Date; - import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; import me.chanjar.weixin.mp.bean.kefu.result.*; +import java.io.File; +import java.util.Date; + /** * 客服接口 , * 命名采用kefu拼音的原因是: * 其英文CustomerService如果再加上Service后缀显得有点啰嗦, * 如果不加又显得表意不完整 - * @author Binary Wang * + * @author Binary Wang */ public interface WxMpKefuService { //*******************客服管理接口***********************// + /** *
    * 获取客服基本信息
@@ -71,7 +72,7 @@ public interface WxMpKefuService {
    * 
*/ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) - throws WxErrorException; + throws WxErrorException; /** *
@@ -83,6 +84,7 @@ public interface WxMpKefuService {
   boolean kfAccountDel(String kfAccount) throws WxErrorException;
 
   //*******************客服会话控制接口***********************//
+
   /**
    * 
    * 创建会话
@@ -134,6 +136,7 @@ public interface WxMpKefuService {
   WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException;
 
   //*******************获取聊天记录的接口***********************//
+
   /**
    * 
    * 获取聊天记录(原始接口)
@@ -143,9 +146,9 @@ public interface WxMpKefuService {
    * 
* * @param startTime 起始时间 - * @param endTime 结束时间 - * @param msgId 消息id顺序从小到大,从1开始 - * @param number 每次获取条数,最多10000条 + * @param endTime 结束时间 + * @param msgId 消息id顺序从小到大,从1开始 + * @param number 每次获取条数,最多10000条 * @return 聊天记录对象 * @throws WxErrorException */ @@ -160,7 +163,7 @@ public interface WxMpKefuService { *
* * @param startTime 起始时间 - * @param endTime 结束时间 + * @param endTime 结束时间 * @return 聊天记录对象 * @throws WxErrorException */ 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 a4b18643..7254a008 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 @@ -19,10 +19,11 @@ public interface WxMpMaterialService { /** * 新增临时素材 - * @see #mediaUpload(String, String, InputStream) + * * @param mediaType * @param file * @throws WxErrorException + * @see #mediaUpload(String, String, InputStream) */ public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException; @@ -33,6 +34,7 @@ public interface WxMpMaterialService { * 根据微信文档,视频文件下载不了,会返回null * 详情请见: 获取临时素材 *
+ * * @param media_id * @return 保存到本地的临时文件 * @throws WxErrorException @@ -44,6 +46,7 @@ public interface WxMpMaterialService { * 上传图文消息内的图片获取URL * 详情请见:http://mp.weixin.qq.com/wiki/15/40b6865b893947b764e2de8e4a1fb55f.html#.E4.B8.8A.E4.BC.A0.E5.9B.BE.E6.96.87.E6.B6.88.E6.81.AF.E5.86.85.E7.9A.84.E5.9B.BE.E7.89.87.E8.8E.B7.E5.8F.96URL.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91 * + * * @param file * @return WxMediaImgUploadResult 返回图片url * @throws WxErrorException @@ -63,9 +66,10 @@ public interface WxMpMaterialService { * * 详情请见: 新增临时素材 * - * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} - * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} - * @param inputStream 输入流 + * + * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} + * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} + * @param inputStream 输入流 * @throws WxErrorException */ public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException; @@ -82,8 +86,9 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html * - * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} - * @param material 上传的素材, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterial} + * + * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} + * @param material 上传的素材, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterial} */ public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException; @@ -93,7 +98,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html * - * @param news 上传的图文消息, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialNews} + * + * @param news 上传的图文消息, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialNews} */ public WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException; @@ -103,7 +109,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html * - * @param media_id 永久素材的id + * + * @param media_id 永久素材的id */ public InputStream materialImageOrVoiceDownload(String media_id) throws WxErrorException; @@ -113,7 +120,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html * - * @param media_id 永久素材的id + * + * @param media_id 永久素材的id */ public WxMpMaterialVideoInfoResult materialVideoInfo(String media_id) throws WxErrorException; @@ -123,7 +131,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html * - * @param media_id 永久素材的id + * + * @param media_id 永久素材的id */ public WxMpMaterialNews materialNewsInfo(String media_id) throws WxErrorException; @@ -133,7 +142,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/4/19a59cba020d506e767360ca1be29450.html * - * @param wxMpMaterialArticleUpdate 用来更新图文素材的bean, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate} + * + * @param wxMpMaterialArticleUpdate 用来更新图文素材的bean, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate} */ public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException; @@ -143,7 +153,8 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/5/e66f61c303db51a6c0f90f46b15af5f5.html * - * @param media_id 永久素材的id + * + * @param media_id 永久素材的id */ public boolean materialDelete(String media_id) throws WxErrorException; @@ -162,8 +173,9 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/12/2108cd7aafff7f388f41f37efa710204.html * - * @param offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回 - * @param count 返回素材的数量,取值在1到20之间 + * + * @param offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回 + * @param count 返回素材的数量,取值在1到20之间 */ public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException; @@ -173,9 +185,10 @@ public interface WxMpMaterialService { * * 详情请见: http://mp.weixin.qq.com/wiki/12/2108cd7aafff7f388f41f37efa710204.html * - * @param type 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} - * @param offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回 - * @param count 返回素材的数量,取值在1到20之间 + * + * @param type 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} + * @param offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回 + * @param count 返回素材的数量,取值在1到20之间 */ public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException; 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 865bfb00..670921db 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 @@ -2,16 +2,11 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; - -import java.io.File; -import java.util.Date; /** * 菜单相关操作接口 - * @author Binary Wang * + * @author Binary Wang */ public interface WxMpMenuService { @@ -38,6 +33,7 @@ public interface WxMpMenuService { * 删除个性化菜单接口 * 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html * + * * @param menuid */ public void menuDelete(String menuid) throws WxErrorException; @@ -55,6 +51,7 @@ public interface WxMpMenuService { * 测试个性化菜单匹配结果 * 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html * + * * @param userid 可以是粉丝的OpenID,也可以是粉丝的微信号。 */ public WxMenu menuTryMatch(String userid) 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 new file mode 100644 index 00000000..2015ae1b --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java @@ -0,0 +1,77 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; + +import java.io.File; + +/** + * 二维码相关操作接口 + * + * @author Binary Wang + */ +public interface WxMpQrcodeService { + + /** + *
+   * 换取临时二维码ticket
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param scene_id 参数。 + * @param expire_seconds 过期秒数,默认60秒,最小60秒,最大1800秒 + */ + public WxMpQrCodeTicket qrCodeCreateTmpTicket(int scene_id, Integer expire_seconds) throws WxErrorException; + + /** + *
+   * 换取永久二维码ticket
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param scene_id 参数。永久二维码时最大值为100000(目前参数只支持1--100000) + */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; + + /** + *
+   * 换取永久字符串二维码ticket
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param scene_str 参数。字符串类型长度现在为1到64 + */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException; + + /** + *
+   * 换取二维码图片文件,jpg格式
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param ticket 二维码ticket + */ + public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException; + + /** + *
+   * 换取二维码图片url地址(可以选择是否生成压缩的网址)
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param ticket 二维码ticket + * @param needShortUrl 是否需要压缩的二维码地址 + */ + public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException; + + /** + *
+   * 换取二维码图片url地址
+   * 详情请见: 生成带参数的二维码
+   * 
+ * + * @param ticket 二维码ticket + */ + public String qrCodePictureUrl(String ticket) throws WxErrorException; + +} 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 2dc94260..7bff3027 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 @@ -1,40 +1,14 @@ package me.chanjar.weixin.mp.api; -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.Map; - import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.mp.bean.WxMpCustomMessage; -import me.chanjar.weixin.mp.bean.WxMpGroup; -import me.chanjar.weixin.mp.bean.WxMpIndustry; -import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; -import me.chanjar.weixin.mp.bean.WxMpMassNews; -import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; -import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; -import me.chanjar.weixin.mp.bean.WxMpMassVideo; -import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; -import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; -import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; -import me.chanjar.weixin.mp.bean.result.WxMpPayResult; -import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; -import me.chanjar.weixin.mp.bean.result.WxMpUserList; -import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; -import me.chanjar.weixin.mp.bean.result.WxRedpackResult; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.*; + +import java.text.SimpleDateFormat; +import java.util.Map; /** * 微信API的Service @@ -42,6 +16,7 @@ import me.chanjar.weixin.mp.bean.result.WxRedpackResult; public interface WxMpService { public static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + /** *
    * 验证推送过来的消息的正确性
@@ -52,6 +27,7 @@ public interface WxMpService {
 
   /**
    * 获取access_token, 不强制刷新access_token
+   *
    * @see #getAccessToken(boolean)
    */
   public String getAccessToken() throws WxErrorException;
@@ -64,15 +40,17 @@ public interface WxMpService {
    * 另:本service的所有方法都会在access_token过期是调用此方法
    *
    * 程序员在非必要情况下尽量不要主动调用此方法
-
+   *
    * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取access_token
    * 
+ * * @param forceRefresh 强制刷新 */ public String getAccessToken(boolean forceRefresh) throws WxErrorException; /** * 获得jsapi_ticket,不强制刷新jsapi_ticket + * * @see #getJsapiTicket(boolean) */ public String getJsapiTicket() throws WxErrorException; @@ -84,6 +62,7 @@ public interface WxMpService { * * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95 * + * * @param forceRefresh 强制刷新 */ public String getJsapiTicket(boolean forceRefresh) throws WxErrorException; @@ -111,6 +90,7 @@ public interface WxMpService { * * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口 * + * * @param news * @throws WxErrorException * @see #massGroupMessageSend(me.chanjar.weixin.mp.bean.WxMpMassGroupMessage) @@ -123,6 +103,7 @@ public interface WxMpService { * 上传群发用的视频,上传后才能群发视频消息 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口 * + * * @see #massGroupMessageSend(me.chanjar.weixin.mp.bean.WxMpMassGroupMessage) * @see #massOpenIdsMessageSend(me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage) */ @@ -148,146 +129,12 @@ public interface WxMpService { */ public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; - /** - *
-   * 分组管理接口 - 创建分组
-   * 最多支持创建500个分组
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
-   * 
- * @param name 分组名字(30个字符以内) - */ - public WxMpGroup groupCreate(String name) throws WxErrorException; - - /** - *
-   * 分组管理接口 - 查询所有分组
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
-   * 
- */ - public List groupGet() throws WxErrorException; - - /** - *
-   * 分组管理接口 - 查询用户所在分组
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
-   * 
- * @param openid 微信用户的openid - */ - public long userGetGroup(String openid) throws WxErrorException; - - /** - *
-   * 分组管理接口 - 修改分组名
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
-   *
-   * 如果id为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
-   * 
- * @param group 要更新的group,group的id,name必须设置 - */ - public void groupUpdate(WxMpGroup group) throws WxErrorException; - - /** - *
-   * 分组管理接口 - 移动用户分组
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
-   *
-   * 如果to_groupid为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
-   * 
- * @param openid 用户openid - * @param to_groupid 移动到的分组id - */ - public void userUpdateGroup(String openid, long to_groupid) throws WxErrorException; - - /** - *
-   * 设置用户备注名接口
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=设置用户备注名接口
-   * 
- * @param openid 用户openid - * @param remark 备注名 - */ - public void userUpdateRemark(String openid, String remark) throws WxErrorException; - - /** - *
-   * 获取用户基本信息
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取用户基本信息
-   * 
- * @param openid 用户openid - * @param lang 语言,zh_CN 简体(默认),zh_TW 繁体,en 英语 - */ - public WxMpUser userInfo(String openid, String lang) throws WxErrorException; - - /** - *
-   * 获取关注者列表
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取关注者列表
-   * 
- * @param next_openid 可选,第一个拉取的OPENID,null为从头开始拉取 - */ - public WxMpUserList userList(String next_openid) throws WxErrorException; - - /** - *
-   * 换取临时二维码ticket
-   * 详情请见: 生成带参数的二维码
-   * 
- * @param scene_id 参数。 - * @param expire_seconds 过期秒数,默认60秒,最小60秒,最大1800秒 - */ - public WxMpQrCodeTicket qrCodeCreateTmpTicket(int scene_id, Integer expire_seconds) throws WxErrorException; - - /** - *
-   * 换取永久二维码ticket
-   * 详情请见: 生成带参数的二维码
-   * 
- * @param scene_id 参数。永久二维码时最大值为100000(目前参数只支持1--100000) - */ - public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; - - /** - *
-   * 换取永久字符串二维码ticket
-   * 详情请见: 生成带参数的二维码
-   * 
- * - * @param scene_str 参数。字符串类型长度现在为1到64 - */ - public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException; - - /** - *
-   * 换取二维码图片文件,jpg格式
-   * 详情请见: 生成带参数的二维码
-   * 
- * @param ticket 二维码ticket - */ - public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException; - - /** - *
-   * 换取二维码图片url地址(可以选择是否生成压缩的网址)
-   * 详情请见: 生成带参数的二维码
-   * 
- * @param ticket 二维码ticket - * @param needShortUrl 是否需要压缩的二维码地址 - */ - public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException; - /** - *
-   * 换取二维码图片url地址
-   * 详情请见: 生成带参数的二维码
-   * 
- * @param ticket 二维码ticket - */ - public String qrCodePictureUrl(String ticket) throws WxErrorException; - /** *
    * 长链接转短链接接口
    * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=长链接转短链接接口
    * 
+ * * @param long_url */ public String shortUrl(String long_url) throws WxErrorException; @@ -297,9 +144,10 @@ public interface WxMpService { * 发送模板消息 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=模板消息接口 * + * * @param templateMessage - * @throws WxErrorException * @return msgid + * @throws WxErrorException */ public String templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; @@ -316,6 +164,7 @@ public interface WxMpService { * 构造oauth2授权的url连接 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息 * + * * @param scope * @param state * @return url @@ -327,8 +176,8 @@ public interface WxMpService { * 构造oauth2授权的url连接 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息 * - * @param redirectURI - * 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode + * + * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode * @param scope * @param state * @return url @@ -354,8 +203,9 @@ public interface WxMpService { *
    * 用oauth2获取用户信息, 当前面引导授权时的scope是snsapi_userinfo的时候才可以
    * 
+ * * @param oAuth2AccessToken - * @param lang zh_CN, zh_TW, en + * @param lang zh_CN, zh_TW, en */ public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException; @@ -363,6 +213,7 @@ public interface WxMpService { *
    * 验证oauth2的access token是否有效
    * 
+ * * @param oAuth2AccessToken */ public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken); @@ -375,26 +226,6 @@ public interface WxMpService { */ String[] getCallbackIP() throws WxErrorException; - /** - *
-   * 获取用户增减数据
-   * http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
-   * 
- * @param beginDate 最大时间跨度7天 - * @param endDate endDate不能早于begingDate - */ - List getUserSummary(Date beginDate, Date endDate) throws WxErrorException; - - /** - *
-   * 获取累计用户数据
-   * http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
-   * 
- * @param beginDate 最大时间跨度7天 - * @param endDate endDate不能早于begingDate - */ - List getUserCumulate(Date beginDate, Date endDate) throws WxErrorException; - /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 */ @@ -438,13 +269,14 @@ public interface WxMpService { /** * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1) * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识" - * @param openId 支付人openId + * + * @param openId 支付人openId * @param outTradeNo 商户端对应订单号 - * @param amt 金额(单位元) - * @param body 商品描述 - * @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP - * @param ip 发起支付的客户端IP - * @param notifyUrl 通知地址 + * @param amt 金额(单位元) + * @param body 商品描述 + * @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP + * @param ip 发起支付的客户端IP + * @param notifyUrl 通知地址 * @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getPrepayId(Map) instead */ @Deprecated @@ -454,8 +286,7 @@ public interface WxMpService { * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1) * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识" * - * @param parameters - * All required/optional parameters for weixin payment + * @param parameters All required/optional parameters for weixin payment * @throws IllegalArgumentException */ WxMpPrepayIdResult getPrepayId(Map parameters); @@ -463,21 +294,22 @@ public interface WxMpService { /** * 该接口调用“统一下单”接口,并拼装发起支付请求需要的参数 * 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82 - * @param parameters - * the required or optional parameters + * + * @param parameters the required or optional parameters */ - Map getPayInfo(Map parameters) throws WxErrorException; - + Map getPayInfo(Map parameters) throws WxErrorException; + /** * 该接口调用“统一下单”接口,并拼装NATIVE发起支付请求需要的参数 * 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82 - * tradeType 交易类型 NATIVE (其他交易类型JSAPI,APP,WAP) - * @param productId 商户商品ID + * tradeType 交易类型 NATIVE (其他交易类型JSAPI,APP,WAP) + * + * @param productId 商户商品ID * @param outTradeNo 商户端对应订单号 - * @param amt 金额(单位元) - * @param body 商品描述 - * @param ip 发起支付的客户端IP - * @param notifyUrl 通知地址 + * @param amt 金额(单位元) + * @param body 商品描述 + * @param ip 发起支付的客户端IP + * @param notifyUrl 通知地址 * @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getPayInfo(Map) instead */ @Deprecated @@ -487,12 +319,13 @@ public interface WxMpService { * 该接口调用“统一下单”接口,并拼装JSAPI发起支付请求需要的参数 * 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82 * tradeType 交易类型 JSAPI(其他交易类型NATIVE,APP,WAP) - * @param openId 支付人openId + * + * @param openId 支付人openId * @param outTradeNo 商户端对应订单号 - * @param amt 金额(单位元) - * @param body 商品描述 - * @param ip 发起支付的客户端IP - * @param notifyUrl 通知地址 + * @param amt 金额(单位元) + * @param body 商品描述 + * @param ip 发起支付的客户端IP + * @param notifyUrl 通知地址 * @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getPayInfo(Map) instead */ @Deprecated @@ -501,6 +334,7 @@ public interface WxMpService { /** * 该接口提供所有微信支付订单的查询,当支付通知处理异常戒丢失的情冴,商户可以通过该接口查询订单支付状态。 * 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2 + * * @param transactionId * @param outTradeNo */ @@ -509,6 +343,7 @@ public interface WxMpService { /** * 读取支付结果通知 * 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + * * @param xmlData */ WxMpPayCallback getJSSDKCallbackData(String xmlData); @@ -516,12 +351,13 @@ public interface WxMpService { /** * 微信支付-申请退款 * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 + * * @param parameters 需要传入的退款参数的Map。以下几项为参数的必须项:
- *
  • transaction_id - *
  • out_trade_no (仅在上述transaction_id为空时是必须项) - *
  • out_refund_no - *
  • total_fee - *
  • refund_fee + *
  • transaction_id + *
  • out_trade_no (仅在上述transaction_id为空时是必须项) + *
  • out_refund_no + *
  • total_fee + *
  • refund_fee * @return 退款操作结果 * @throws WxErrorException */ @@ -532,39 +368,41 @@ public interface WxMpService { * 计算Map键值对是否和签名相符, * 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串 * + * * @param kvm * @param signature */ public boolean checkJSSDKCallbackDataSignature(Map kvm, String signature); /** - * 发送微信红包给个人用户 - * - * 需要传入的必填参数如下: - * mch_billno//商户订单号 - * send_name//商户名称 - * re_openid//用户openid - * total_amount//红包总额 - * total_num//红包发放总人数 - * wishing//红包祝福语 - * client_ip//服务器Ip地址 - * act_name//活动名称 - * remark //备注 - * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5 - * - * 使用现金红包功能需要在xml配置文件中额外设置: - * 微信商户平台ID - * 商户平台设置的API密钥 - * - * @param parameters - */ + * 发送微信红包给个人用户 + *

    + * 需要传入的必填参数如下: + * mch_billno//商户订单号 + * send_name//商户名称 + * re_openid//用户openid + * total_amount//红包总额 + * total_num//红包发放总人数 + * wishing//红包祝福语 + * client_ip//服务器Ip地址 + * act_name//活动名称 + * remark //备注 + * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5 + *

    + * 使用现金红包功能需要在xml配置文件中额外设置: + * 微信商户平台ID + * 商户平台设置的API密钥 + * + * @param parameters + */ public WxRedpackResult sendRedpack(Map parameters) throws WxErrorException; /** * 获得卡券api_ticket,不强制刷新卡券api_ticket - * @see #getCardApiTicket(boolean) + * * @return 卡券api_ticket * @throws WxErrorException + * @see #getCardApiTicket(boolean) */ public String getCardApiTicket() throws WxErrorException; @@ -575,6 +413,7 @@ public interface WxMpService { * * 详情请见: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 * @throws WxErrorException @@ -591,15 +430,16 @@ public interface WxMpService { * * * @param optionalSignParam 参与签名的参数数组。 - * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id - *
    注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 + * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id + *
    注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 * @return 卡券Api签名对象 */ public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws - WxErrorException; + WxErrorException; /** * 卡券Code解码 + * * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得 * @return 解密后的Code * @throws WxErrorException @@ -608,14 +448,15 @@ public interface WxMpService { /** * 卡券Code查询 - * @param cardId 卡券ID代表一类卡券 - * @param code 单张卡券的唯一标准 + * + * @param cardId 卡券ID代表一类卡券 + * @param code 单张卡券的唯一标准 * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 * @return WxMpCardResult对象 * @throws WxErrorException */ public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) - throws WxErrorException; + throws WxErrorException; /** * 卡券Code核销。核销失败会抛出异常 @@ -638,51 +479,55 @@ public interface WxMpService { */ public String consumeCardCode(String code, String cardId) throws WxErrorException; - /** - * 卡券Mark接口。 - * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), - * 才能进一步调用核销接口,否则报错。 - * @param code 卡券的code码 - * @param cardId 卡券的ID - * @param openId 用券用户的openid - * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 - * @throws WxErrorException - */ + /** + * 卡券Mark接口。 + * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), + * 才能进一步调用核销接口,否则报错。 + * + * @param code 卡券的code码 + * @param cardId 卡券的ID + * @param openId 用券用户的openid + * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 + * @throws WxErrorException + */ public void markCardCode(String code, String cardId, String openId, boolean isMark) throws - WxErrorException; + 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串中的某个字段。 + *
    [注] 由于返回的JSON格式过于复杂,难以定义其对应格式的Bean并且难以维护,因此只返回String格式的JSON串。 + *
    可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。 * @throws WxErrorException */ public String getCardDetail(String cardId) throws WxErrorException; /** - *

    -     * 预览接口
    -     * 详情请见:http://mp.weixin.qq.com/wiki/15/40b6865b893947b764e2de8e4a1fb55f.html#.E9.A2.84.E8.A7.88.E6.8E.A5.E5.8F.A3.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91
    -     * 
    - * @param wxMpMassPreviewMessage - * @return wxMpMassSendResult - * @throws WxErrorException - */ + *
    +   * 预览接口
    +   * 详情请见:http://mp.weixin.qq.com/wiki/15/40b6865b893947b764e2de8e4a1fb55f.html#.E9.A2.84.E8.A7.88.E6.8E.A5.E5.8F.A3.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91
    +   * 
    + * + * @param wxMpMassPreviewMessage + * @return wxMpMassSendResult + * @throws WxErrorException + */ public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception; /** - *
    -     * 设置所属行业
    -     * 官方文档中暂未告知响应内容
    -     * 详情请见:http://mp.weixin.qq.com/wiki/5/6dde9eaa909f83354e0094dc3ad99e05.html#.E8.AE.BE.E7.BD.AE.E6.89.80.E5.B1.9E.E8.A1.8C.E4.B8.9A
    -     * 
    - * @param wxMpIndustry - * @return JsonObject - * @throws WxErrorException - */ + *
    +   * 设置所属行业
    +   * 官方文档中暂未告知响应内容
    +   * 详情请见:http://mp.weixin.qq.com/wiki/5/6dde9eaa909f83354e0094dc3ad99e05.html#.E8.AE.BE.E7.BD.AE.E6.89.80.E5.B1.9E.E8.A1.8C.E4.B8.9A
    +   * 
    + * + * @param wxMpIndustry + * @return JsonObject + * @throws WxErrorException + */ String setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException; /*** @@ -695,28 +540,53 @@ public interface WxMpService { * @throws WxErrorException */ WxMpIndustry getIndustry() throws WxErrorException; - + + /** + * 获取WxMpConfigStorage 对象 + * + * @return WxMpConfigStorage + */ + WxMpConfigStorage getWxMpConfigStorage(); + /** * 返回客服接口方法实现类,以方便调用个其各种接口 + * * @return WxMpKefuService - */ + */ WxMpKefuService getKefuService(); /** * 返回素材相关接口的方法实现类,以方便调用个其各种接口 + * * @return WxMpMaterialService */ WxMpMaterialService getMaterialService(); /** - * 返回素材相关接口的方法实现类,以方便调用个其各种接口 + * 返回菜单相关接口的方法实现类,以方便调用个其各种接口 + * * @return WxMpMenuService */ WxMpMenuService getMenuService(); /** - * 获取WxMpConfigStorage 对象 - * @return WxMpConfigStorage + * 返回用户相关接口的方法实现类,以方便调用个其各种接口 + * + * @return WxMpUserService */ - WxMpConfigStorage getWxMpConfigStorage(); + WxMpUserService getUserService(); + + /** + * 返回用户分组相关接口的方法实现类,以方便调用个其各种接口 + * + * @return WxMpGroupService + */ + WxMpGroupService getGroupService(); + + /** + * 返回二维码相关接口的方法实现类,以方便调用个其各种接口 + * + * @return WxMpQrcodeService + */ + WxMpQrcodeService getQrcodeService(); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index c7ab51c8..5e8809d7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -1,46 +1,10 @@ package me.chanjar.weixin.mp.api; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.http.Consts; -import org.apache.http.HttpHost; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicResponseHandler; -import org.apache.http.impl.client.CloseableHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.helpers.MessageFormatter; - -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.internal.Streams; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.thoughtworks.xstream.XStream; - import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature; @@ -51,45 +15,32 @@ import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.crypto.WxCryptUtil; -import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; -import me.chanjar.weixin.common.util.http.DefaultApacheHttpHttpClientBuilder; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; -import me.chanjar.weixin.common.util.http.URIUtil; -import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; -import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.common.util.http.*; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import me.chanjar.weixin.mp.api.impl.WxMpKefuServiceImpl; -import me.chanjar.weixin.mp.api.impl.WxMpMaterialServiceImpl; -import me.chanjar.weixin.mp.api.impl.WxMpMenuServiceImpl; -import me.chanjar.weixin.mp.bean.WxMpCustomMessage; -import me.chanjar.weixin.mp.bean.WxMpGroup; -import me.chanjar.weixin.mp.bean.WxMpIndustry; -import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; -import me.chanjar.weixin.mp.bean.WxMpMassNews; -import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; -import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; -import me.chanjar.weixin.mp.bean.WxMpMassVideo; -import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; -import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; -import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; -import me.chanjar.weixin.mp.bean.result.WxMpPayResult; -import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; -import me.chanjar.weixin.mp.bean.result.WxMpUserList; -import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; -import me.chanjar.weixin.mp.bean.result.WxRedpackResult; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; +import me.chanjar.weixin.mp.api.impl.*; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.*; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.impl.client.CloseableHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.helpers.MessageFormatter; + +import java.io.IOException; +import java.io.StringReader; +import java.security.NoSuchAlgorithmException; +import java.util.*; +import java.util.Map.Entry; public class WxMpServiceImpl implements WxMpService { @@ -118,6 +69,12 @@ public class WxMpServiceImpl implements WxMpService { protected WxMpMenuService menuService = new WxMpMenuServiceImpl(this); + protected WxMpUserService userService = new WxMpUserServiceImpl(this); + + protected WxMpGroupService groupService = new WxMpGroupServiceImpl(this); + + protected WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); + protected CloseableHttpClient httpClient; protected HttpHost httpProxy; @@ -266,158 +223,6 @@ public class WxMpServiceImpl implements WxMpService { return WxMpMassSendResult.fromJson(responseContent); } - @Override - public WxMpGroup groupCreate(String name) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/groups/create"; - JsonObject json = new JsonObject(); - JsonObject groupJson = new JsonObject(); - json.add("group", groupJson); - groupJson.addProperty("name", name); - - String responseContent = execute( - new SimplePostRequestExecutor(), - url, - json.toString()); - return WxMpGroup.fromJson(responseContent); - } - - @Override - public List groupGet() throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/groups/get"; - String responseContent = execute(new SimpleGetRequestExecutor(), url, null); - /* - * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } - * 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } - */ - JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); - return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("groups"), - new TypeToken>() { - }.getType()); - } - - @Override - public long userGetGroup(String openid) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/groups/getid"; - JsonObject o = new JsonObject(); - o.addProperty("openid", openid); - String responseContent = execute(new SimplePostRequestExecutor(), url, o.toString()); - JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); - return GsonHelper.getAsLong(tmpJsonElement.getAsJsonObject().get("groupid")); - } - - @Override - public void groupUpdate(WxMpGroup group) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/groups/update"; - execute(new SimplePostRequestExecutor(), url, group.toJson()); - } - - @Override - public void userUpdateGroup(String openid, long to_groupid) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/groups/members/update"; - JsonObject json = new JsonObject(); - json.addProperty("openid", openid); - json.addProperty("to_groupid", to_groupid); - execute(new SimplePostRequestExecutor(), url, json.toString()); - } - - @Override - public void userUpdateRemark(String openid, String remark) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark"; - JsonObject json = new JsonObject(); - json.addProperty("openid", openid); - json.addProperty("remark", remark); - execute(new SimplePostRequestExecutor(), url, json.toString()); - } - - @Override - public WxMpUser userInfo(String openid, String lang) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/user/info"; - lang = lang == null ? "zh_CN" : lang; - String responseContent = execute(new SimpleGetRequestExecutor(), url, "openid=" + openid + "&lang=" + lang); - return WxMpUser.fromJson(responseContent); - } - - @Override - public WxMpUserList userList(String next_openid) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/user/get"; - String responseContent = execute(new SimpleGetRequestExecutor(), url, next_openid == null ? null : "next_openid=" + next_openid); - return WxMpUserList.fromJson(responseContent); - } - - @Override - public WxMpQrCodeTicket qrCodeCreateTmpTicket(int scene_id, Integer expire_seconds) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_SCENE"); - if (expire_seconds != null) { - json.addProperty("expire_seconds", expire_seconds); - } - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", scene_id); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_LIMIT_SCENE"); - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", scene_id); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/qrcode/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", scene_str); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { - String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; - return execute(new QrCodeRequestExecutor(), url, 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, - URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); - if(needShortUrl){ - return this.shortUrl(resultUrl); - } - - return resultUrl; - } catch (UnsupportedEncodingException e) { - WxError error = WxError.newBuilder().setErrorCode(-1) - .setErrorMsg(e.getMessage()).build(); - throw new WxErrorException(error); - } - } - - @Override - public String qrCodePictureUrl(String ticket) throws WxErrorException { - return qrCodePictureUrl(ticket, false); - } - @Override public String shortUrl(String long_url) throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/shorturl"; @@ -562,33 +367,6 @@ public class WxMpServiceImpl implements WxMpService { return ipArray; } - - @Override - public List getUserSummary(Date beginDate, Date endDate) throws WxErrorException { - String url = "https://api.weixin.qq.com/datacube/getusersummary"; - JsonObject param = new JsonObject(); - param.addProperty("begin_date", SIMPLE_DATE_FORMAT.format(beginDate)); - param.addProperty("end_date", SIMPLE_DATE_FORMAT.format(endDate)); - String responseContent = post(url, param.toString()); - JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); - return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - - @Override - public List getUserCumulate(Date beginDate, Date endDate) throws WxErrorException { - String url = "https://api.weixin.qq.com/datacube/getusercumulate"; - JsonObject param = new JsonObject(); - param.addProperty("begin_date", SIMPLE_DATE_FORMAT.format(beginDate)); - param.addProperty("end_date", SIMPLE_DATE_FORMAT.format(endDate)); - String responseContent = post(url, param.toString()); - JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); - return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - @Override public String get(String url, String queryParam) throws WxErrorException { return execute(new SimpleGetRequestExecutor(), url, queryParam); @@ -1255,4 +1033,19 @@ public class WxMpServiceImpl implements WxMpService { return this.menuService; } + @Override + public WxMpUserService getUserService() { + return this.userService; + } + + @Override + public WxMpGroupService getGroupService() { + return this.groupService; + } + + @Override + public WxMpQrcodeService getQrcodeService() { + return this.qrCodeService; + } + } 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 new file mode 100644 index 00000000..818087b4 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java @@ -0,0 +1,72 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; +import me.chanjar.weixin.mp.bean.result.WxMpUserList; +import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; + +import java.util.Date; +import java.util.List; + +/** + * 用户管理和统计相关操作接口 + * + * @author Binary Wang + */ +public interface WxMpUserService { + + /** + *
    +   * 设置用户备注名接口
    +   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=设置用户备注名接口
    +   * 
    + * + * @param openid 用户openid + * @param remark 备注名 + */ + public void userUpdateRemark(String openid, String remark) throws WxErrorException; + + /** + *
    +   * 获取用户基本信息
    +   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取用户基本信息
    +   * 
    + * + * @param openid 用户openid + * @param lang 语言,zh_CN 简体(默认),zh_TW 繁体,en 英语 + */ + public WxMpUser userInfo(String openid, String lang) throws WxErrorException; + + /** + *
    +   * 获取关注者列表
    +   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取关注者列表
    +   * 
    + * + * @param next_openid 可选,第一个拉取的OPENID,null为从头开始拉取 + */ + public WxMpUserList userList(String next_openid) throws WxErrorException; + + /** + *
    +   * 获取用户增减数据
    +   * http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
    +   * 
    + * + * @param beginDate 最大时间跨度7天 + * @param endDate endDate不能早于begingDate + */ + List dataCubeUserSummary(Date beginDate, Date endDate) throws WxErrorException; + + /** + *
    +   * 获取累计用户数据
    +   * http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
    +   * 
    + * + * @param beginDate 最大时间跨度7天 + * @param endDate endDate不能早于begingDate + */ + List dataCubeUserCumulate(Date beginDate, Date endDate) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImpl.java new file mode 100644 index 00000000..ea388dea --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImpl.java @@ -0,0 +1,85 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.api.WxMpGroupService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.WxMpGroup; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.StringReader; +import java.util.List; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpGroupServiceImpl implements WxMpGroupService { + private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/groups"; + private WxMpService wxMpService; + + public WxMpGroupServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpGroup groupCreate(String name) throws WxErrorException { + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + JsonObject groupJson = new JsonObject(); + json.add("group", groupJson); + groupJson.addProperty("name", name); + + String responseContent = this.wxMpService.execute( + new SimplePostRequestExecutor(), + url, + json.toString()); + return WxMpGroup.fromJson(responseContent); + } + + @Override + public List groupGet() throws WxErrorException { + String url = API_URL_PREFIX + "/get"; + String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); + /* + * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } + * 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } + */ + JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); + return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("groups"), + new TypeToken>() { + }.getType()); + } + + @Override + public long userGetGroup(String openid) throws WxErrorException { + String url = API_URL_PREFIX + "/getid"; + JsonObject o = new JsonObject(); + o.addProperty("openid", openid); + String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, o.toString()); + JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); + return GsonHelper.getAsLong(tmpJsonElement.getAsJsonObject().get("groupid")); + } + + @Override + public void groupUpdate(WxMpGroup group) throws WxErrorException { + String url = API_URL_PREFIX + "/update"; + this.wxMpService.execute(new SimplePostRequestExecutor(), url, group.toJson()); + } + + @Override + public void userUpdateGroup(String openid, long to_groupid) throws WxErrorException { + String url = API_URL_PREFIX + "/members/update"; + JsonObject json = new JsonObject(); + json.addProperty("openid", openid); + json.addProperty("to_groupid", to_groupid); + this.wxMpService.execute(new SimplePostRequestExecutor(), url, json.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 6befcc2b..398d6e29 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 @@ -7,11 +7,12 @@ import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; 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.*; +import me.chanjar.weixin.mp.bean.WxMpMaterial; +import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate; +import me.chanjar.weixin.mp.bean.WxMpMaterialNews; import me.chanjar.weixin.mp.bean.result.*; import me.chanjar.weixin.mp.util.http.*; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; @@ -27,6 +28,8 @@ import java.util.UUID; * Created by Binary Wang on 2016/7/21. */ public class WxMpMaterialServiceImpl implements WxMpMaterialService { + private static final String MEDIA_API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; + private static final String MATERIAL_API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; private WxMpService wxMpService; public WxMpMaterialServiceImpl(WxMpService wxMpService) { @@ -40,19 +43,25 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { @Override public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType; + String url = MEDIA_API_URL_PREFIX + "/upload?type=" + mediaType; return this.wxMpService.execute(new MediaUploadRequestExecutor(), url, file); } @Override public File mediaDownload(String media_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/media/get"; + String url = MEDIA_API_URL_PREFIX + "/get"; return this.wxMpService.execute(new MediaDownloadRequestExecutor(this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), url, "media_id=" + media_id); } + @Override + public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { + String url = MEDIA_API_URL_PREFIX + "/uploadimg"; + return this.wxMpService.execute(new MediaImgUploadRequestExecutor(), url, file); + } + @Override public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=" + mediaType; + String url = MATERIAL_API_URL_PREFIX + "/add_material?type=" + mediaType; return this.wxMpService.execute(new MaterialUploadRequestExecutor(), url, material); } @@ -61,32 +70,32 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { if (news == null || news.isEmpty()) { throw new IllegalArgumentException("news is empty!"); } - String url = "https://api.weixin.qq.com/cgi-bin/material/add_news"; + String url = MATERIAL_API_URL_PREFIX + "/add_news"; String responseContent = this.wxMpService.post(url, news.toJson()); return WxMpMaterialUploadResult.fromJson(responseContent); } @Override public InputStream materialImageOrVoiceDownload(String media_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/get_material"; + String url = MATERIAL_API_URL_PREFIX + "/get_material"; return this.wxMpService.execute(new MaterialVoiceAndImageDownloadRequestExecutor(this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), url, media_id); } @Override public WxMpMaterialVideoInfoResult materialVideoInfo(String media_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/get_material"; + String url = MATERIAL_API_URL_PREFIX + "/get_material"; return this.wxMpService.execute(new MaterialVideoInfoRequestExecutor(), url, media_id); } @Override public WxMpMaterialNews materialNewsInfo(String media_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/get_material"; + String url = MATERIAL_API_URL_PREFIX + "/get_material"; return this.wxMpService.execute(new MaterialNewsInfoRequestExecutor(), url, media_id); } @Override public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/update_news"; + String url = MATERIAL_API_URL_PREFIX + "/update_news"; String responseText = this.wxMpService.post(url, wxMpMaterialArticleUpdate.toJson()); WxError wxError = WxError.fromJson(responseText); if (wxError.getErrorCode() == 0) { @@ -98,13 +107,13 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { @Override public boolean materialDelete(String media_id) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/del_material"; + String url = MATERIAL_API_URL_PREFIX + "/del_material"; return this.wxMpService.execute(new MaterialDeleteRequestExecutor(), url, media_id); } @Override public WxMpMaterialCountResult materialCount() throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount"; + String url = MATERIAL_API_URL_PREFIX + "/get_materialcount"; String responseText = this.wxMpService.get(url, null); WxError wxError = WxError.fromJson(responseText); if (wxError.getErrorCode() == 0) { @@ -116,7 +125,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { @Override public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material"; + String url = MATERIAL_API_URL_PREFIX + "/batchget_material"; Map params = new HashMap<>(); params.put("type", WxConsts.MATERIAL_NEWS); params.put("offset", offset); @@ -132,7 +141,7 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { @Override public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material"; + String url = MATERIAL_API_URL_PREFIX + "/batchget_material"; Map params = new HashMap<>(); params.put("type", type); params.put("offset", offset); @@ -146,10 +155,4 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService { } } - @Override - public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg"; - return this.wxMpService.execute(new MediaImgUploadRequestExecutor(), url, file); - } - } 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 new file mode 100644 index 00000000..bb0e112c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java @@ -0,0 +1,102 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpQrcodeService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * Created by Binary Wang on 2016/7/21. + */ +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; + } + + @Override + public WxMpQrCodeTicket qrCodeCreateTmpTicket(int scene_id, Integer expire_seconds) throws WxErrorException { + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_SCENE"); + if (expire_seconds != null) { + json.addProperty("expire_seconds", expire_seconds); + } + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_id", scene_id); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException { + 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", scene_id); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) 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", scene_str); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { + String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; + return this.wxMpService.execute(new QrCodeRequestExecutor(), url, 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, + URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); + if (needShortUrl) { + return this.wxMpService.shortUrl(resultUrl); + } + + return resultUrl; + } catch (UnsupportedEncodingException e) { + WxError error = WxError.newBuilder().setErrorCode(-1) + .setErrorMsg(e.getMessage()).build(); + throw new WxErrorException(error); + } + } + + @Override + public String qrCodePictureUrl(String ticket) throws WxErrorException { + return qrCodePictureUrl(ticket, false); + } + +} 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 new file mode 100644 index 00000000..f2ceac34 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java @@ -0,0 +1,83 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpUserService; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; +import me.chanjar.weixin.mp.bean.result.WxMpUserList; +import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.StringReader; +import java.util.Date; +import java.util.List; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpUserServiceImpl implements WxMpUserService { + private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/user"; + private WxMpService wxMpService; + + public WxMpUserServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public void userUpdateRemark(String openid, String remark) throws WxErrorException { + String url = API_URL_PREFIX + "/info/updateremark"; + JsonObject json = new JsonObject(); + json.addProperty("openid", openid); + json.addProperty("remark", remark); + this.wxMpService.execute(new SimplePostRequestExecutor(), url, json.toString()); + } + + @Override + public WxMpUser userInfo(String openid, String lang) throws WxErrorException { + String url = API_URL_PREFIX + "/info"; + lang = lang == null ? "zh_CN" : lang; + String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, "openid=" + openid + "&lang=" + lang); + return WxMpUser.fromJson(responseContent); + } + + @Override + public WxMpUserList userList(String next_openid) throws WxErrorException { + String url = API_URL_PREFIX + "/get"; + String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, next_openid == null ? null : "next_openid=" + next_openid); + return WxMpUserList.fromJson(responseContent); + } + + @Override + public List dataCubeUserSummary(Date beginDate, Date endDate) throws WxErrorException { + String url = "https://api.weixin.qq.com/datacube/getusersummary"; + JsonObject param = new JsonObject(); + param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); + param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); + String responseContent = this.wxMpService.post(url, param.toString()); + JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); + return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + + @Override + public List dataCubeUserCumulate(Date beginDate, Date endDate) throws WxErrorException { + String url = "https://api.weixin.qq.com/datacube/getusercumulate"; + JsonObject param = new JsonObject(); + param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); + param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); + String responseContent = this.wxMpService.post(url, param.toString()); + JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); + return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java index 562820c3..537b771c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java @@ -45,4 +45,9 @@ public class WxMpQrCodeTicket implements Serializable { public static WxMpQrCodeTicket fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpQrCodeTicket.class); } + + @Override + public String toString() { + return WxMpGsonBuilder.INSTANCE.create().toJson(this); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java index 489d5bed..842f1327 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java @@ -44,4 +44,9 @@ public class WxMpUserList { public static WxMpUserList fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserList.class); } + + @Override + public String toString() { + return WxMpGsonBuilder.INSTANCE.create().toJson(this); + } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java index 6d276efd..565de65f 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java @@ -63,7 +63,7 @@ public class WxMpMassMessageAPITest { WxMpMassGroupMessage massMessage = new WxMpMassGroupMessage(); massMessage.setMsgtype(WxConsts.MASS_MSG_TEXT); massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - massMessage.setGroupId(wxService.groupGet().get(0).getId()); + massMessage.setGroupId(wxService.getGroupService().groupGet().get(0).getId()); WxMpMassSendResult massResult = wxService.massGroupMessageSend(massMessage); Assert.assertNotNull(massResult); @@ -75,7 +75,7 @@ public class WxMpMassMessageAPITest { WxMpMassGroupMessage massMessage = new WxMpMassGroupMessage(); massMessage.setMsgtype(massMsgType); massMessage.setMediaId(mediaId); - massMessage.setGroupId(wxService.groupGet().get(0).getId()); + massMessage.setGroupId(wxService.getGroupService().groupGet().get(0).getId()); WxMpMassSendResult massResult = wxService.massGroupMessageSend(massMessage); Assert.assertNotNull(massResult); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java index 5f2a7392..84408282 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java @@ -1,37 +1,19 @@ package me.chanjar.weixin.mp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.WxSession; -import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; -import me.chanjar.weixin.mp.bean.WxMpMassNews; -import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; -import me.chanjar.weixin.mp.bean.WxMpMassVideo; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; -import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; import org.testng.Assert; -import org.testng.annotations.DataProvider; import org.testng.annotations.Guice; import org.testng.annotations.Test; -import java.io.IOException; -import java.io.InputStream; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Arrays; -import java.util.Date; -import java.util.List; /** * * @author chanjarster * */ -@Test(groups = "miscAPI", dependsOnGroups = { "baseAPI"}) +@Test(groups = "miscAPI") @Guice(modules = ApiTestModule.class) public class WxMpMiscAPITest { @@ -46,24 +28,4 @@ public class WxMpMiscAPITest { Assert.assertNotEquals(ipArray.length, 0); } - @Test - public void testGetUserSummary() throws WxErrorException, ParseException { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - Date beginDate = simpleDateFormat.parse("2015-01-01"); - Date endDate = simpleDateFormat.parse("2015-01-02"); - List summaries = wxService.getUserSummary(beginDate, endDate); - System.out.println(summaries); - Assert.assertNotNull(summaries); - } - - @Test - public void testGetUserCumulate() throws WxErrorException, ParseException { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - Date beginDate = simpleDateFormat.parse("2015-01-01"); - Date endDate = simpleDateFormat.parse("2015-01-02"); - List cumulates = wxService.getUserCumulate(beginDate, endDate); - System.out.println(cumulates); - Assert.assertNotNull(cumulates); - } - } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpUserAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpUserAPITest.java deleted file mode 100644 index fa978c57..00000000 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpUserAPITest.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.chanjar.weixin.mp.api; - -import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import me.chanjar.weixin.mp.bean.result.WxMpUserList; -import org.testng.Assert; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -/** - * 测试用户相关的接口 - * @author chanjarster - * - */ -@Test(groups = "userAPI", dependsOnGroups = { "baseAPI", "groupAPI" }) -@Guice(modules = ApiTestModule.class) -public class WxMpUserAPITest { - - @Inject - protected WxMpServiceImpl wxService; - - public void testUserUpdateRemark() throws WxErrorException { - ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.wxMpConfigStorage; - wxService.userUpdateRemark(configProvider.getOpenId(), "测试备注名"); - } - - public void testUserInfo() throws WxErrorException { - ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.wxMpConfigStorage; - WxMpUser user = wxService.userInfo(configProvider.getOpenId(), null); - Assert.assertNotNull(user); - } - - public void testUserList() throws WxErrorException { - WxMpUserList wxMpUserList = wxService.userList(null); - Assert.assertNotNull(wxMpUserList); - Assert.assertFalse(wxMpUserList.getCount() == -1); - Assert.assertFalse(wxMpUserList.getTotal() == -1); - Assert.assertFalse(wxMpUserList.getOpenIds().size() == -1); - } - - public void testGroupQueryUserGroup() throws WxErrorException { - ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.wxMpConfigStorage; - long groupid = wxService.userGetGroup(configStorage.getOpenId()); - Assert.assertTrue(groupid != -1l); - } - - public void getGroupMoveUser() throws WxErrorException { - ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.wxMpConfigStorage; - wxService.userUpdateGroup(configStorage.getOpenId(), wxService.groupGet().get(3).getId()); - } - -} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpGroupAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImplTest.java similarity index 70% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpGroupAPITest.java rename to weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImplTest.java index 4397e057..4bcf8d9f 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpGroupAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGroupServiceImplTest.java @@ -1,7 +1,9 @@ -package me.chanjar.weixin.mp.api; +package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.ApiTestModule; +import me.chanjar.weixin.mp.api.WxMpServiceImpl; import me.chanjar.weixin.mp.bean.WxMpGroup; import org.testng.Assert; import org.testng.annotations.Guice; @@ -14,9 +16,9 @@ import java.util.List; * * @author chanjarster */ -@Test(groups = "groupAPI", dependsOnGroups = "baseAPI") +@Test(groups = "groupAPI") @Guice(modules = ApiTestModule.class) -public class WxMpGroupAPITest { +public class WxMpGroupServiceImplTest { @Inject protected WxMpServiceImpl wxService; @@ -24,13 +26,13 @@ public class WxMpGroupAPITest { protected WxMpGroup group; public void testGroupCreate() throws WxErrorException { - WxMpGroup res = wxService.groupCreate("测试分组1"); + WxMpGroup res = this.wxService.getGroupService().groupCreate("测试分组1"); Assert.assertEquals(res.getName(), "测试分组1"); } @Test(dependsOnMethods="testGroupCreate") public void testGroupGet() throws WxErrorException { - List groupList = wxService.groupGet(); + List groupList = this.wxService.getGroupService().groupGet(); Assert.assertNotNull(groupList); Assert.assertTrue(groupList.size() > 0); for (WxMpGroup g : groupList) { @@ -42,7 +44,7 @@ public class WxMpGroupAPITest { @Test(dependsOnMethods={"testGroupGet", "testGroupCreate"}) public void getGroupUpdate() throws WxErrorException { group.setName("分组改名"); - wxService.groupUpdate(group); + this.wxService.getGroupService().groupUpdate(group); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpQrCodeAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrCodeServiceImplTest.java similarity index 56% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpQrCodeAPITest.java rename to weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrCodeServiceImplTest.java index 2b12ac25..4600b07d 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpQrCodeAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrCodeServiceImplTest.java @@ -1,7 +1,9 @@ -package me.chanjar.weixin.mp.api; +package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.ApiTestModule; +import me.chanjar.weixin.mp.api.WxMpServiceImpl; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.testng.Assert; import org.testng.annotations.Guice; @@ -16,35 +18,39 @@ import java.io.File; */ @Test(groups = "qrCodeAPI") @Guice(modules = ApiTestModule.class) -public class WxMpQrCodeAPITest { +public class WxMpQrCodeServiceImplTest { @Inject protected WxMpServiceImpl wxService; public void testQrCodeCreateTmpTicket() throws WxErrorException { - WxMpQrCodeTicket ticket = this.wxService.qrCodeCreateTmpTicket(1, null); + WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateTmpTicket(1, null); Assert.assertNotNull(ticket.getUrl()); Assert.assertNotNull(ticket.getTicket()); Assert.assertTrue(ticket.getExpire_seconds() != -1); + System.out.println(ticket); } public void testQrCodeCreateLastTicket() throws WxErrorException { - WxMpQrCodeTicket ticket = this.wxService.qrCodeCreateLastTicket(1); + WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateLastTicket(1); Assert.assertNotNull(ticket.getUrl()); Assert.assertNotNull(ticket.getTicket()); Assert.assertTrue(ticket.getExpire_seconds() == -1); + System.out.println(ticket); } public void testQrCodePicture() throws WxErrorException { - WxMpQrCodeTicket ticket = this.wxService.qrCodeCreateLastTicket(1); - File file = this.wxService.qrCodePicture(ticket); + WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateLastTicket(1); + File file = this.wxService.getQrcodeService().qrCodePicture(ticket); Assert.assertNotNull(file); + System.out.println(file.getAbsolutePath()); } public void testQrCodePictureUrl() throws WxErrorException { - WxMpQrCodeTicket ticket = this.wxService.qrCodeCreateLastTicket(1); - String url = this.wxService.qrCodePictureUrl(ticket.getTicket()); + WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateLastTicket(1); + String url = this.wxService.getQrcodeService().qrCodePictureUrl(ticket.getTicket()); Assert.assertNotNull(url); + System.out.println(url); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java new file mode 100644 index 00000000..5fc3dd9b --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java @@ -0,0 +1,85 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.ApiTestModule; +import me.chanjar.weixin.mp.api.WxMpServiceImpl; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; +import me.chanjar.weixin.mp.bean.result.WxMpUserList; +import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 测试用户相关的接口 + * + * @author chanjarster + * @author Binary Wang + */ +@Test(groups = "userAPI") +@Guice(modules = ApiTestModule.class) +public class WxMpUserServiceImplTest { + + @Inject + protected WxMpServiceImpl wxService; + + public void testUserUpdateRemark() throws WxErrorException { + ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.getWxMpConfigStorage(); + this.wxService.getUserService().userUpdateRemark(configProvider.getOpenId(), "测试备注名"); + } + + public void testUserInfo() throws WxErrorException { + ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.getWxMpConfigStorage(); + WxMpUser user = this.wxService.getUserService().userInfo(configProvider.getOpenId(), null); + Assert.assertNotNull(user); + System.out.println(user); + } + + public void testUserList() throws WxErrorException { + WxMpUserList wxMpUserList = this.wxService.getUserService().userList(null); + Assert.assertNotNull(wxMpUserList); + Assert.assertFalse(wxMpUserList.getCount() == -1); + Assert.assertFalse(wxMpUserList.getTotal() == -1); + Assert.assertFalse(wxMpUserList.getOpenIds().size() == -1); + System.out.println(wxMpUserList); + } + + public void testGroupQueryUserGroup() throws WxErrorException { + ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.getWxMpConfigStorage(); + long groupid = this.wxService.getGroupService().userGetGroup(configStorage.getOpenId()); + Assert.assertTrue(groupid != -1l); + } + + public void testGroupMoveUser() throws WxErrorException { + ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) wxService.getWxMpConfigStorage(); + this.wxService.getGroupService().userUpdateGroup(configStorage.getOpenId(), this.wxService.getGroupService().groupGet().get(3).getId()); + } + + @Test + public void testGetUserSummary() throws WxErrorException, ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date beginDate = simpleDateFormat.parse("2015-01-01"); + Date endDate = simpleDateFormat.parse("2015-01-02"); + List summaries = this.wxService.getUserService().dataCubeUserSummary(beginDate, endDate); + Assert.assertNotNull(summaries); + System.out.println(summaries); + } + + @Test + public void testGetUserCumulate() throws WxErrorException, ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date beginDate = simpleDateFormat.parse("2015-01-01"); + Date endDate = simpleDateFormat.parse("2015-01-02"); + List cumulates = this.wxService.getUserService().dataCubeUserCumulate(beginDate, endDate); + Assert.assertNotNull(cumulates); + System.out.println(cumulates); + } + +} diff --git a/weixin-java-mp/src/test/resources/testng.xml b/weixin-java-mp/src/test/resources/testng.xml index 09184112..d821e398 100644 --- a/weixin-java-mp/src/test/resources/testng.xml +++ b/weixin-java-mp/src/test/resources/testng.xml @@ -7,10 +7,10 @@ - + - - + +