* #519 修复小程序客服消息 URL 被转义的问题 * 优化单元测试提示信息 * 网页授权url增加&connect_redirect=1参数解决两次重定向跳转问题: https://blog.csdn.net/jiangguilong2000/article/details/79416615 * 修复错误的feeToYuan方法名为fenToYuan * #529 EntPayBankRequest增加默认构造函数 * #529 EntPayBankResult中cmmsAmount的数据类型改为Integer * #528 WxMpUser类增加三个属性:subscribe_scene、 qr_scene 和qr_scene_str * 修复代码 * 发布3.0.1.BETA测试版本 * #533 微信刷卡支付请求类增加缺少的三个参数 * #536 企业号模块增加获取企业号应用相关接口 * 定义《企业号应用》的bean * 增加《获取企业号应用》接口实现 * 增加获取测试企业号应用信息测试类 * #535 修复Tomcat 不能正常关闭的问题,增加线程池shutdown相关的操作 * #541 企业号增加实现管理标签的(获取标签成员)接口 * 定义《企业号应用》的bean * 增加《获取企业号应用》接口实现 * 增加获取测试企业号应用信息测试类 * tag service增加获取标签成员方法 http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 * #534 公众号发送模版消息中的小程序path改回pagepath * 发布3.0.2.BETA测试版本 * #547 开放平台模块 componentAccessToken 增加过期自动刷新 * createOrder方法增加H5支付的支持 * #551 文本卡片消息增加btntext字段 * #550 企业微信删除标签成员接口增加部门列表参数 * 清理无用代码 * #530 微信支付申请退款接口结果类增加单个代金券相关参数 ,并根据官方文档整理其他参数 * #531 小程序WxMaMessage类增加小程序卡片消息相关的几个属性 * #520 企业微信网页授权增加使用user_ticket获取成员详情的接口 * 发布3.0.3.BETA测试版本 * 优化代码 * 完善测试 * #559 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * #560 微信开放平台:增加小程序代码模板库管理 * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * #562 小程序增加代码管理相关 API * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * 小程序:增加代码管理相关 API * #563 小程序增加修改服务器地址、成员管理 API * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * 小程序:增加代码管理相关 API * 小程序:增加修改服务器地址、成员管理 API * #565 小程序增加数据分析相关 API * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * 小程序:增加代码管理相关 API * 小程序:增加修改服务器地址、成员管理 API * 小程序:增加数据分析相关 API * #567 微信开放平台增加 HTTP proxy 机制 * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * 小程序:增加代码管理相关 API * 小程序:增加修改服务器地址、成员管理 API * 小程序:增加数据分析相关 API * 微信开放平台:增加 HTTP proxy 机制 * #568 修复三方平台多次授权时,RefreshToken 没有刷新的问题 * fix 多次授权时,RefreshToken 没有刷新 * null 判断 * 发布3.0.4.BETA测试版本 * fix code * #569 微信支付几个查询关闭对账下载相关接口增加重载方法,以方便客户端指定更多参数 * #578 微信开放平台增加 WxMaUserService 的实现 * 微信开放平台:1. WxOpenInRedisConfigStorage 支持 JedisPool/JedisSentinelPool 等 Pool<Jedis> 的子类;2. WxOpenInRedisConfigStorage 增加 keyPrefix 以支持可配置的前缀; * 微信开放平台:增加小程序代码模板库管理 * 小程序:增加代码管理相关 API * 小程序:增加修改服务器地址、成员管理 API * 小程序:增加数据分析相关 API * 微信开放平台:增加 HTTP proxy 机制 * 微信开放平台:增加 WxMaUserService 的实现 * 修复小程序码的相关方法命名:WxCode->WxaCode, WxCodeLimit -> WxaCodeUnlimit * #556 日志信息中如果含有secret值的,将其值隐藏掉 * #585 小程序二维码支持is_hyaline参数生成透明背景二维码 * 发布3.0.5.BETA测试版本 * #584 修复企业付款到银行卡接口签名失败的问题 * 简化代码 * #586 微信支付 WxPayConfig增加支持byte数组方式设置证书 * #581 增加微信公众号错误信息枚举类WxMpErrorMsg,并提供方法,方便根据错误代码查询错误信息内容 * #555 修复微信支付服务商模式支付验证签名失败的问题 * #521 微信支付回调通知类WxPayOrderNotifyResult增加version参数 * #583 企业微信新增人员接口新增字段to_invite * #583 企业微信通讯录管理增加邀请成员接口 * #587 企业微信几个接口增加个人二维码字段 * 修复字符 * 修复单元测试 * 发布3.0.6.BETA测试版本 * 重构WxError相关代码,自动根据代码补充错误中文说明 * 优化微信支付代码 * #584 修复企业付款queryEntPay签名失败问题 * #591 文件上传接口不自动关闭inputStream,由调用方自己控制 * #595 优化WxPayException * 发布3.0.7.BETA测试版本 * 更新pom * 优化代码 * #615 公众号客服消息添加 "发送小程序卡片" 类型 * 优化XStreamTransformer * 微信支付模块jodd-http修改scope * 发布3.0.8.BETA测试版本 * #623 群发接口增加clientmsgid * add author for some files * clean code * 重构规范RequestExecuter代码 * #532 实现微信AI开放接口的三个接口:语音上传、查询识别结果和微信翻译功能 * 发布3.0.9.BETA测试版本 * #516 增加获取Wi-Fi门店列表接口 * #629 修复WxPayOrderNotifyResult解析xml报错问题 * #639 修复小程序代码模版库管理 access_token key 错误 * 发布3.1.0正式版本master
@@ -6,7 +6,7 @@ | |||||
<modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>3.0.0</version> | |||||
<version>3.1.0</version> | |||||
<packaging>pom</packaging> | <packaging>pom</packaging> | ||||
<name>Weixin Java Tools - Parent</name> | <name>Weixin Java Tools - Parent</name> | ||||
<description>微信公众号、企业号上级POM</description> | <description>微信公众号、企业号上级POM</description> | ||||
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>3.0.0</version> | |||||
<version>3.1.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-common</artifactId> | <artifactId>weixin-java-common</artifactId> | ||||
@@ -109,6 +109,11 @@ | |||||
<artifactId>jetty-servlet</artifactId> | <artifactId>jetty-servlet</artifactId> | ||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.assertj</groupId> | |||||
<artifactId>assertj-guava</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
<build> | <build> | ||||
@@ -0,0 +1,32 @@ | |||||
package me.chanjar.weixin.common; | |||||
/** | |||||
* <pre> | |||||
* 微信类型枚举. | |||||
* Created by BinaryWang on 2018/5/14. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
public enum WxType { | |||||
/** | |||||
* 企业微信 | |||||
*/ | |||||
CP, | |||||
/** | |||||
* 微信公众号 | |||||
*/ | |||||
MP, | |||||
/** | |||||
* 微信小程序 | |||||
*/ | |||||
MiniApp, | |||||
/** | |||||
* 微信开放平台 | |||||
*/ | |||||
Open, | |||||
/** | |||||
* 微信支付 | |||||
*/ | |||||
Pay; | |||||
} |
@@ -78,6 +78,11 @@ public class WxConsts { | |||||
* 转发到客服的消息. | * 转发到客服的消息. | ||||
*/ | */ | ||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | ||||
/** | |||||
* 小程序卡片(要求小程序与公众号已关联) | |||||
*/ | |||||
public static final String MINIPROGRAMPAGE="miniprogrampage"; | |||||
} | } | ||||
/** | /** | ||||
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.common.api; | package me.chanjar.weixin.common.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* WxErrorException处理器. | * WxErrorException处理器. | ||||
@@ -1,38 +0,0 @@ | |||||
package me.chanjar.weixin.common.bean.result; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
import java.io.Serializable; | |||||
/** | |||||
* 微信错误码说明,请阅读: <a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a>. | |||||
* | |||||
* @author Daniel Qian | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
public class WxError implements Serializable { | |||||
private static final long serialVersionUID = 7869786563361406291L; | |||||
private int errorCode; | |||||
private String errorMsg; | |||||
private String json; | |||||
public static WxError fromJson(String json) { | |||||
return WxGsonBuilder.create().fromJson(json, WxError.class); | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
if (this.json != null) { | |||||
return this.json; | |||||
} | |||||
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; | |||||
} | |||||
} |
@@ -0,0 +1,806 @@ | |||||
package me.chanjar.weixin.common.error; | |||||
import lombok.Getter; | |||||
/** | |||||
* <pre> | |||||
* 企业微信全局错误码. | |||||
* 参考文档:<a href="https://work.weixin.qq.com/api/doc#10649">企业微信全局错误码</a> | |||||
* Created by Binary Wang on 2018/5/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
@Getter | |||||
public enum WxCpErrorMsgEnum { | |||||
/** | |||||
* 系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。 | |||||
*/ | |||||
CODE_1(-1, "系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。"), | |||||
/** | |||||
* 请求成功;接口调用成功 | |||||
*/ | |||||
CODE_0(0, "请求成功;接口调用成功"), | |||||
/** | |||||
* 不合法的secret参数;secret在应用详情/通讯录管理助手可查看 | |||||
*/ | |||||
CODE_40001(40001, "不合法的secret参数;secret在应用详情/通讯录管理助手可查看"), | |||||
/** | |||||
* 无效的UserID | |||||
*/ | |||||
CODE_40003(40003, "无效的UserID"), | |||||
/** | |||||
* 不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制 | |||||
*/ | |||||
CODE_40004(40004, "不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制"), | |||||
/** | |||||
* 不合法的type参数;合法的type取值,参考:上传临时素材 | |||||
*/ | |||||
CODE_40005(40005, "不合法的type参数;合法的type取值,参考:上传临时素材"), | |||||
/** | |||||
* 不合法的文件大小;系统文件要求,参考:上传的媒体文件限制 | |||||
*/ | |||||
CODE_40006(40006, "不合法的文件大小;系统文件要求,参考:上传的媒体文件限制"), | |||||
/** | |||||
* 不合法的media_id参数 | |||||
*/ | |||||
CODE_40007(40007, "不合法的media_id参数"), | |||||
/** | |||||
* 不合法的msgtype参数;合法的msgtype取值,参考:消息类型 | |||||
*/ | |||||
CODE_40008(40008, "不合法的msgtype参数;合法的msgtype取值,参考:消息类型"), | |||||
/** | |||||
* 上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制 | |||||
*/ | |||||
CODE_40009(40009, "上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制"), | |||||
/** | |||||
* 上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制 | |||||
*/ | |||||
CODE_40011(40011, "上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制"), | |||||
/** | |||||
* 不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看 | |||||
*/ | |||||
CODE_40013(40013, "不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看"), | |||||
/** | |||||
* 不合法的access_token | |||||
*/ | |||||
CODE_40014(40014, "不合法的access_token"), | |||||
/** | |||||
* 不合法的按钮个数;菜单按钮1-3个 | |||||
*/ | |||||
CODE_40016(40016, "不合法的按钮个数;菜单按钮1-3个"), | |||||
/** | |||||
* 不合法的按钮类型;支持的类型,参考:按钮类型 | |||||
*/ | |||||
CODE_40017(40017, "不合法的按钮类型;支持的类型,参考:按钮类型"), | |||||
/** | |||||
* 不合法的按钮名字长度;长度应不超过16个字节 | |||||
*/ | |||||
CODE_40018(40018, "不合法的按钮名字长度;长度应不超过16个字节"), | |||||
/** | |||||
* 不合法的按钮KEY长度;长度应不超过128字节 | |||||
*/ | |||||
CODE_40019(40019, "不合法的按钮KEY长度;长度应不超过128字节"), | |||||
/** | |||||
* 不合法的按钮URL长度;长度应不超过1024字节 | |||||
*/ | |||||
CODE_40020(40020, "不合法的按钮URL长度;长度应不超过1024字节"), | |||||
/** | |||||
* 不合法的子菜单级数;只能包含一级菜单和二级菜单 | |||||
*/ | |||||
CODE_40022(40022, "不合法的子菜单级数;只能包含一级菜单和二级菜单"), | |||||
/** | |||||
* 不合法的子菜单按钮个数;子菜单按钮1-5个 | |||||
*/ | |||||
CODE_40023(40023, "不合法的子菜单按钮个数;子菜单按钮1-5个"), | |||||
/** | |||||
* 不合法的子菜单按钮类型;支持的类型,参考:按钮类型 | |||||
*/ | |||||
CODE_40024(40024, "不合法的子菜单按钮类型;支持的类型,参考:按钮类型"), | |||||
/** | |||||
* 不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型 | |||||
*/ | |||||
CODE_40025(40025, "不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型"), | |||||
/** | |||||
* 不合法的子菜单按钮KEY长度;长度应不超过60个字节 | |||||
*/ | |||||
CODE_40026(40026, "不合法的子菜单按钮KEY长度;长度应不超过60个字节"), | |||||
/** | |||||
* 不合法的子菜单按钮URL长度;长度应不超过1024字节 | |||||
*/ | |||||
CODE_40027(40027, "不合法的子菜单按钮URL长度;长度应不超过1024字节"), | |||||
/** | |||||
* 不合法的oauth_code | |||||
*/ | |||||
CODE_40029(40029, "不合法的oauth_code"), | |||||
/** | |||||
* 不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中 | |||||
*/ | |||||
CODE_40031(40031, "不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中"), | |||||
/** | |||||
* 不合法的UserID列表长度 | |||||
*/ | |||||
CODE_40032(40032, "不合法的UserID列表长度"), | |||||
/** | |||||
* 不合法的请求字符;不能包含\\uxxxx格式的字符 | |||||
*/ | |||||
CODE_40033(40033, "不合法的请求字符;不能包含\\uxxxx格式的字符"), | |||||
/** | |||||
* 不合法的参数 | |||||
*/ | |||||
CODE_40035(40035, "不合法的参数"), | |||||
/** | |||||
* chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天 | |||||
*/ | |||||
CODE_40050(40050, "chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天"), | |||||
/** | |||||
* 不合法的子菜单url域名 | |||||
*/ | |||||
CODE_40054(40054, "不合法的子菜单url域名"), | |||||
/** | |||||
* 不合法的菜单url域名 | |||||
*/ | |||||
CODE_40055(40055, "不合法的菜单url域名"), | |||||
/** | |||||
* 不合法的agentid | |||||
*/ | |||||
CODE_40056(40056, "不合法的agentid"), | |||||
/** | |||||
* 不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现 | |||||
*/ | |||||
CODE_40057(40057, "不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现"), | |||||
/** | |||||
* 不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明 | |||||
*/ | |||||
CODE_40058(40058, "不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明"), | |||||
/** | |||||
* 不合法的上报地理位置标志位;开关标志位只能填 0 或者 1 | |||||
*/ | |||||
CODE_40059(40059, "不合法的上报地理位置标志位;开关标志位只能填 0 或者 1"), | |||||
/** | |||||
* 参数为空 | |||||
*/ | |||||
CODE_40063(40063, "参数为空"), | |||||
/** | |||||
* 不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中 | |||||
*/ | |||||
CODE_40066(40066, "不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中"), | |||||
/** | |||||
* 不合法的标签ID;标签ID未指定,或者指定的标签ID不存在 | |||||
*/ | |||||
CODE_40068(40068, "不合法的标签ID;标签ID未指定,或者指定的标签ID不存在"), | |||||
/** | |||||
* 指定的标签范围结点全部无效 | |||||
*/ | |||||
CODE_40070(40070, "指定的标签范围结点全部无效"), | |||||
/** | |||||
* 不合法的标签名字;标签名字已经存在 | |||||
*/ | |||||
CODE_40071(40071, "不合法的标签名字;标签名字已经存在"), | |||||
/** | |||||
* 不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母) | |||||
*/ | |||||
CODE_40072(40072, "不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母)"), | |||||
/** | |||||
* 不合法的openid;openid不存在,需确认获取来源 | |||||
*/ | |||||
CODE_40073(40073, "不合法的openid;openid不存在,需确认获取来源"), | |||||
/** | |||||
* news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews | |||||
*/ | |||||
CODE_40074(40074, "news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews"), | |||||
/** | |||||
* 不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码 | |||||
*/ | |||||
CODE_40077(40077, "不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码"), | |||||
/** | |||||
* 不合法的auth_code参数;需确认获取来源,并且只能消费一次 | |||||
*/ | |||||
CODE_40078(40078, "不合法的auth_code参数;需确认获取来源,并且只能消费一次"), | |||||
/** | |||||
* 不合法的suite_secret;套件secret可在第三方管理端套件详情查看 | |||||
*/ | |||||
CODE_40080(40080, "不合法的suite_secret;套件secret可在第三方管理端套件详情查看"), | |||||
/** | |||||
* 不合法的suite_token | |||||
*/ | |||||
CODE_40082(40082, "不合法的suite_token"), | |||||
/** | |||||
* 不合法的suite_id;suite_id不存在 | |||||
*/ | |||||
CODE_40083(40083, "不合法的suite_id;suite_id不存在"), | |||||
/** | |||||
* 不合法的permanent_code参数 | |||||
*/ | |||||
CODE_40084(40084, "不合法的permanent_code参数"), | |||||
/** | |||||
* 不合法的的suite_ticket参数;suite_ticket不存在或者已失效 | |||||
*/ | |||||
CODE_40085(40085, "不合法的的suite_ticket参数;suite_ticket不存在或者已失效"), | |||||
/** | |||||
* 不合法的第三方应用appid;至少有一个不存在应用id | |||||
*/ | |||||
CODE_40086(40086, "不合法的第三方应用appid;至少有一个不存在应用id"), | |||||
/** | |||||
* jobid不存在;请检查 jobid 来源 | |||||
*/ | |||||
CODE_40088(40088, "jobid不存在;请检查 jobid 来源"), | |||||
/** | |||||
* 批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况 | |||||
*/ | |||||
CODE_40089(40089, "批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况"), | |||||
/** | |||||
* secret不合法;可能用了别的企业的secret | |||||
*/ | |||||
CODE_40091(40091, "secret不合法;可能用了别的企业的secret"), | |||||
/** | |||||
* 导入文件存在不合法的内容 | |||||
*/ | |||||
CODE_40092(40092, "导入文件存在不合法的内容"), | |||||
/** | |||||
* 不合法的jsapi_ticket参数;ticket已失效,或者拼写错误 | |||||
*/ | |||||
CODE_40093(40093, "不合法的jsapi_ticket参数;ticket已失效,或者拼写错误"), | |||||
/** | |||||
* 不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头) | |||||
*/ | |||||
CODE_40094(40094, "不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头)"), | |||||
/** | |||||
* 缺少access_token参数 | |||||
*/ | |||||
CODE_41001(41001, "缺少access_token参数"), | |||||
/** | |||||
* 缺少corpid参数 | |||||
*/ | |||||
CODE_41002(41002, "缺少corpid参数"), | |||||
/** | |||||
* 缺少secret参数 | |||||
*/ | |||||
CODE_41004(41004, "缺少secret参数"), | |||||
/** | |||||
* 缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递 | |||||
*/ | |||||
CODE_41006(41006, "缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递"), | |||||
/** | |||||
* 缺少auth code参数 | |||||
*/ | |||||
CODE_41008(41008, "缺少auth code参数"), | |||||
/** | |||||
* 缺少userid参数 | |||||
*/ | |||||
CODE_41009(41009, "缺少userid参数"), | |||||
/** | |||||
* 缺少url参数 | |||||
*/ | |||||
CODE_41010(41010, "缺少url参数"), | |||||
/** | |||||
* 缺少agentid参数 | |||||
*/ | |||||
CODE_41011(41011, "缺少agentid参数"), | |||||
/** | |||||
* 缺少 description 参数;发送文本卡片消息接口,description 是必填字段 | |||||
*/ | |||||
CODE_41033(41033, "缺少 description 参数;发送文本卡片消息接口,description 是必填字段"), | |||||
/** | |||||
* 缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。 | |||||
*/ | |||||
CODE_41016(41016, "缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。"), | |||||
/** | |||||
* 缺少 department 参数 | |||||
*/ | |||||
CODE_41019(41019, "缺少 department 参数"), | |||||
/** | |||||
* 缺少tagid参数 | |||||
*/ | |||||
CODE_41017(41017, "缺少tagid参数"), | |||||
/** | |||||
* 缺少suite_id参数 | |||||
*/ | |||||
CODE_41021(41021, "缺少suite_id参数"), | |||||
/** | |||||
* 缺少suite_access_token参数 | |||||
*/ | |||||
CODE_41022(41022, "缺少suite_access_token参数"), | |||||
/** | |||||
* 缺少suite_ticket参数 | |||||
*/ | |||||
CODE_41023(41023, "缺少suite_ticket参数"), | |||||
/** | |||||
* 缺少secret参数 | |||||
*/ | |||||
CODE_41024(41024, "缺少secret参数"), | |||||
/** | |||||
* 缺少permanent_code参数 | |||||
*/ | |||||
CODE_41025(41025, "缺少permanent_code参数"), | |||||
/** | |||||
* access_token已过期;access_token有时效性,需要重新获取一次 | |||||
*/ | |||||
CODE_42001(42001, "access_token已过期;access_token有时效性,需要重新获取一次"), | |||||
/** | |||||
* pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次 | |||||
*/ | |||||
CODE_42007(42007, "pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次"), | |||||
/** | |||||
* suite_access_token已过期;suite_access_token有时效性,需要重新获取一次 | |||||
*/ | |||||
CODE_42009(42009, "suite_access_token已过期;suite_access_token有时效性,需要重新获取一次"), | |||||
/** | |||||
* 指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid | |||||
*/ | |||||
CODE_43004(43004, "指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid"), | |||||
/** | |||||
* 多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。 | |||||
*/ | |||||
CODE_44001(44001, "多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。"), | |||||
/** | |||||
* 文本消息content参数为空;发文本消息content为必填参数,且不能为空 | |||||
*/ | |||||
CODE_44004(44004, "文本消息content参数为空;发文本消息content为必填参数,且不能为空"), | |||||
/** | |||||
* 多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M | |||||
*/ | |||||
CODE_45001(45001, "多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M"), | |||||
/** | |||||
* 消息内容大小超过限制 | |||||
*/ | |||||
CODE_45002(45002, "消息内容大小超过限制"), | |||||
/** | |||||
* 应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符 | |||||
*/ | |||||
CODE_45004(45004, "应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符"), | |||||
/** | |||||
* 语音播放时间超过限制;语音播放时长不能超过60秒 | |||||
*/ | |||||
CODE_45007(45007, "语音播放时间超过限制;语音播放时长不能超过60秒"), | |||||
/** | |||||
* 图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条 | |||||
*/ | |||||
CODE_45008(45008, "图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条"), | |||||
/** | |||||
* 接口调用超过限制 | |||||
*/ | |||||
CODE_45009(45009, "接口调用超过限制"), | |||||
/** | |||||
* 应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符 | |||||
*/ | |||||
CODE_45022(45022, "应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符"), | |||||
/** | |||||
* 帐号数量超过上限 | |||||
*/ | |||||
CODE_45024(45024, "帐号数量超过上限"), | |||||
/** | |||||
* 触发删除用户数的保护;限制参考:全量覆盖成员 | |||||
*/ | |||||
CODE_45026(45026, "触发删除用户数的保护;限制参考:全量覆盖成员"), | |||||
/** | |||||
* 图文消息author参数长度超过限制;最长64个字节 | |||||
*/ | |||||
CODE_45032(45032, "图文消息author参数长度超过限制;最长64个字节"), | |||||
/** | |||||
* 接口并发调用超过限制 | |||||
*/ | |||||
CODE_45033(45033, "接口并发调用超过限制"), | |||||
/** | |||||
* 菜单未设置;菜单需发布后才能获取到数据 | |||||
*/ | |||||
CODE_46003(46003, "菜单未设置;菜单需发布后才能获取到数据"), | |||||
/** | |||||
* 指定的用户不存在;需要确认指定的用户存在于通讯录中 | |||||
*/ | |||||
CODE_46004(46004, "指定的用户不存在;需要确认指定的用户存在于通讯录中"), | |||||
/** | |||||
* API接口无权限调用 | |||||
*/ | |||||
CODE_48002(48002, "API接口无权限调用"), | |||||
/** | |||||
* 不合法的suite_id;确认suite_access_token由指定的suite_id生成 | |||||
*/ | |||||
CODE_48003(48003, "不合法的suite_id;确认suite_access_token由指定的suite_id生成"), | |||||
/** | |||||
* 授权关系无效;可能是无授权或授权已被取消 | |||||
*/ | |||||
CODE_48004(48004, "授权关系无效;可能是无授权或授权已被取消"), | |||||
/** | |||||
* API接口已废弃;接口已不再支持,建议改用新接口或者新方案 | |||||
*/ | |||||
CODE_48005(48005, "API接口已废弃;接口已不再支持,建议改用新接口或者新方案"), | |||||
/** | |||||
* redirect_url未登记可信域名 | |||||
*/ | |||||
CODE_50001(50001, "redirect_url未登记可信域名"), | |||||
/** | |||||
* 成员不在权限范围;请检查应用或管理组的权限范围 | |||||
*/ | |||||
CODE_50002(50002, "成员不在权限范围;请检查应用或管理组的权限范围"), | |||||
/** | |||||
* 应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用 | |||||
*/ | |||||
CODE_50003(50003, "应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用"), | |||||
/** | |||||
* 部门长度不符合限制;部门名称不能为空且长度不能超过32个字 | |||||
*/ | |||||
CODE_60001(60001, "部门长度不符合限制;部门名称不能为空且长度不能超过32个字"), | |||||
/** | |||||
* 部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中 | |||||
*/ | |||||
CODE_60003(60003, "部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中"), | |||||
/** | |||||
* 父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中 | |||||
*/ | |||||
CODE_60004(60004, "父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中"), | |||||
/** | |||||
* 部门下存在成员;不允许删除有成员的部门 | |||||
*/ | |||||
CODE_60005(60005, "部门下存在成员;不允许删除有成员的部门"), | |||||
/** | |||||
* 部门下存在子部门;不允许删除有子部门的部门 | |||||
*/ | |||||
CODE_60006(60006, "部门下存在子部门;不允许删除有子部门的部门"), | |||||
/** | |||||
* 不允许删除根部门 | |||||
*/ | |||||
CODE_60007(60007, "不允许删除根部门"), | |||||
/** | |||||
* 部门已存在;部门ID或者部门名称已存在 | |||||
*/ | |||||
CODE_60008(60008, "部门已存在;部门ID或者部门名称已存在"), | |||||
/** | |||||
* 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符 | |||||
*/ | |||||
CODE_60009(60009, "部门名称含有非法字符;不能含有 \\ :?*“< >| 等字符"), | |||||
/** | |||||
* 部门存在循环关系 | |||||
*/ | |||||
CODE_60010(60010, "部门存在循环关系"), | |||||
/** | |||||
* 指定的成员/部门/标签参数无权限 | |||||
*/ | |||||
CODE_60011(60011, "指定的成员/部门/标签参数无权限"), | |||||
/** | |||||
* 不允许删除默认应用;默认应用的id为0 | |||||
*/ | |||||
CODE_60012(60012, "不允许删除默认应用;默认应用的id为0"), | |||||
/** | |||||
* 访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表 | |||||
*/ | |||||
CODE_60020(60020, "访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表"), | |||||
/** | |||||
* 不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL | |||||
*/ | |||||
CODE_60028(60028, "不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL"), | |||||
/** | |||||
* UserID已存在 | |||||
*/ | |||||
CODE_60102(60102, "UserID已存在"), | |||||
/** | |||||
* 手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号 | |||||
*/ | |||||
CODE_60103(60103, "手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号"), | |||||
/** | |||||
* 手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。 | |||||
*/ | |||||
CODE_60104(60104, "手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。"), | |||||
/** | |||||
* 邮箱不合法;长度不超过64位,且为有效的email格式 | |||||
*/ | |||||
CODE_60105(60105, "邮箱不合法;长度不超过64位,且为有效的email格式"), | |||||
/** | |||||
* 邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。 | |||||
*/ | |||||
CODE_60106(60106, "邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。"), | |||||
/** | |||||
* 微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“ | |||||
*/ | |||||
CODE_60107(60107, "微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“"), | |||||
/** | |||||
* 用户所属部门数量超过限制;用户同时归属部门不超过20个 | |||||
*/ | |||||
CODE_60110(60110, "用户所属部门数量超过限制;用户同时归属部门不超过20个"), | |||||
/** | |||||
* UserID不存在;UserID参数为空,或者不存在通讯录中 | |||||
*/ | |||||
CODE_60111(60111, "UserID不存在;UserID参数为空,或者不存在通讯录中"), | |||||
/** | |||||
* 成员name参数不合法;不能为空,且不能超过64字符 | |||||
*/ | |||||
CODE_60112(60112, "成员name参数不合法;不能为空,且不能超过64字符"), | |||||
/** | |||||
* 无效的部门id;部门不存在通讯录中 | |||||
*/ | |||||
CODE_60123(60123, "无效的部门id;部门不存在通讯录中"), | |||||
/** | |||||
* 无效的父部门id;父部门不存在通讯录中 | |||||
*/ | |||||
CODE_60124(60124, "无效的父部门id;父部门不存在通讯录中"), | |||||
/** | |||||
* 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符 | |||||
*/ | |||||
CODE_60125(60125, "非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符"), | |||||
/** | |||||
* 缺少department参数 | |||||
*/ | |||||
CODE_60127(60127, "缺少department参数"), | |||||
/** | |||||
* 成员手机和邮箱都为空;成员手机和邮箱至少有个非空 | |||||
*/ | |||||
CODE_60129(60129, "成员手机和邮箱都为空;成员手机和邮箱至少有个非空"), | |||||
/** | |||||
* 发票已被其他公众号锁定 | |||||
*/ | |||||
CODE_72023(72023, "发票已被其他公众号锁定"), | |||||
/** | |||||
* 发票状态错误;reimburse_status状态错误,参考:更新发票状态 | |||||
*/ | |||||
CODE_72024(72024, "发票状态错误;reimburse_status状态错误,参考:更新发票状态"), | |||||
/** | |||||
* 存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态 | |||||
*/ | |||||
CODE_72037(72037, "存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态"), | |||||
/** | |||||
* 可信域名不正确,或者无ICP备案 | |||||
*/ | |||||
CODE_80001(80001, "可信域名不正确,或者无ICP备案"), | |||||
/** | |||||
* 部门下的结点数超过限制(3W) | |||||
*/ | |||||
CODE_81001(81001, "部门下的结点数超过限制(3W)"), | |||||
/** | |||||
* 部门最多15层 | |||||
*/ | |||||
CODE_81002(81002, "部门最多15层"), | |||||
/** | |||||
* 无权限操作标签 | |||||
*/ | |||||
CODE_81011(81011, "无权限操作标签"), | |||||
/** | |||||
* UserID、部门ID、标签ID全部非法或无权限 | |||||
*/ | |||||
CODE_81013(81013, "UserID、部门ID、标签ID全部非法或无权限"), | |||||
/** | |||||
* 标签添加成员,单次添加user或party过多 | |||||
*/ | |||||
CODE_81014(81014, "标签添加成员,单次添加user或party过多"), | |||||
/** | |||||
* 指定的成员/部门/标签全部无效 | |||||
*/ | |||||
CODE_82001(82001, "指定的成员/部门/标签全部无效"), | |||||
/** | |||||
* 不合法的PartyID列表长度;发消息,单次不能超过100个部门 | |||||
*/ | |||||
CODE_82002(82002, "不合法的PartyID列表长度;发消息,单次不能超过100个部门"), | |||||
/** | |||||
* 不合法的TagID列表长度;发消息,单次不能超过100个标签 | |||||
*/ | |||||
CODE_82003(82003, "不合法的TagID列表长度;发消息,单次不能超过100个标签"), | |||||
/** | |||||
* 成员票据过期 | |||||
*/ | |||||
CODE_84014(84014, "成员票据过期"), | |||||
/** | |||||
* 成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息 | |||||
*/ | |||||
CODE_84015(84015, "成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息"), | |||||
/** | |||||
* 缺少templateid参数 | |||||
*/ | |||||
CODE_84019(84019, "缺少templateid参数"), | |||||
/** | |||||
* templateid不存在;确认参数是否有带,并且已创建 | |||||
*/ | |||||
CODE_84020(84020, "templateid不存在;确认参数是否有带,并且已创建"), | |||||
/** | |||||
* 缺少register_code参数 | |||||
*/ | |||||
CODE_84021(84021, "缺少register_code参数"), | |||||
/** | |||||
* 无效的register_code参数 | |||||
*/ | |||||
CODE_84022(84022, "无效的register_code参数"), | |||||
/** | |||||
* 不允许调用设置通讯录同步完成接口 | |||||
*/ | |||||
CODE_84023(84023, "不允许调用设置通讯录同步完成接口"), | |||||
/** | |||||
* 无注册信息 | |||||
*/ | |||||
CODE_84024(84024, "无注册信息"), | |||||
/** | |||||
* 不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节 | |||||
*/ | |||||
CODE_84025(84025, "不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节"), | |||||
/** | |||||
* 包含不合法的词语 | |||||
*/ | |||||
CODE_85002(85002, "包含不合法的词语"), | |||||
/** | |||||
* 每企业每个月设置的可信域名不可超过20个 | |||||
*/ | |||||
CODE_85004(85004, "每企业每个月设置的可信域名不可超过20个"), | |||||
/** | |||||
* 可信域名未通过所有权校验 | |||||
*/ | |||||
CODE_85005(85005, "可信域名未通过所有权校验"), | |||||
/** | |||||
* 参数 chatid 不合法 | |||||
*/ | |||||
CODE_86001(86001, "参数 chatid 不合法"), | |||||
/** | |||||
* 参数 chatid 不存在 | |||||
*/ | |||||
CODE_86003(86003, "参数 chatid 不存在"), | |||||
/** | |||||
* 参数 群名不合法 | |||||
*/ | |||||
CODE_86004(86004, "参数 群名不合法"), | |||||
/** | |||||
* 参数 群主不合法 | |||||
*/ | |||||
CODE_86005(86005, "参数 群主不合法"), | |||||
/** | |||||
* 群成员数过多或过少 | |||||
*/ | |||||
CODE_86006(86006, "群成员数过多或过少"), | |||||
/** | |||||
* 不合法的群成员 | |||||
*/ | |||||
CODE_86007(86007, "不合法的群成员"), | |||||
/** | |||||
* 非法操作非自己创建的群 | |||||
*/ | |||||
CODE_86008(86008, "非法操作非自己创建的群"), | |||||
/** | |||||
* 存在非法会话成员ID | |||||
*/ | |||||
CODE_86216(86216, "存在非法会话成员ID"), | |||||
/** | |||||
* 会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一 | |||||
*/ | |||||
CODE_86217(86217, "会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一"), | |||||
/** | |||||
* 指定的会话参数不合法 | |||||
*/ | |||||
CODE_86220(86220, "指定的会话参数不合法"), | |||||
/** | |||||
* 未认证摇一摇周边 | |||||
*/ | |||||
CODE_90001(90001, "未认证摇一摇周边"), | |||||
/** | |||||
* 缺少摇一摇周边ticket参数 | |||||
*/ | |||||
CODE_90002(90002, "缺少摇一摇周边ticket参数"), | |||||
/** | |||||
* 摇一摇周边ticket参数不合法 | |||||
*/ | |||||
CODE_90003(90003, "摇一摇周边ticket参数不合法"), | |||||
/** | |||||
* 非法的对外属性类型 | |||||
*/ | |||||
CODE_90100(90100, "非法的对外属性类型"), | |||||
/** | |||||
* 对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符 | |||||
*/ | |||||
CODE_90101(90101, "对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符"), | |||||
/** | |||||
* 对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符 | |||||
*/ | |||||
CODE_90102(90102, "对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符"), | |||||
/** | |||||
* 对外属性:网页url不合法 | |||||
*/ | |||||
CODE_90103(90103, "对外属性:网页url不合法"), | |||||
/** | |||||
* 对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符 | |||||
*/ | |||||
CODE_90104(90104, "对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符"), | |||||
/** | |||||
* 对外属性:小程序类型pagepath不合法 | |||||
*/ | |||||
CODE_90105(90105, "对外属性:小程序类型pagepath不合法"), | |||||
/** | |||||
* 对外属性:请求参数不合法 | |||||
*/ | |||||
CODE_90106(90106, "对外属性:请求参数不合法"), | |||||
/** | |||||
* 获取ticket的类型无效 | |||||
*/ | |||||
CODE_91040(91040, "获取ticket的类型无效"), | |||||
/** | |||||
* 无权限操作指定的应用 | |||||
*/ | |||||
CODE_301002(301002, "无权限操作指定的应用"), | |||||
/** | |||||
* 不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。 | |||||
*/ | |||||
CODE_301005(301005, "不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。"), | |||||
/** | |||||
* 参数 position 不合法;长度不允许超过128个字符 | |||||
*/ | |||||
CODE_301012(301012, "参数 position 不合法;长度不允许超过128个字符"), | |||||
/** | |||||
* 参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。 | |||||
*/ | |||||
CODE_301013(301013, "参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。"), | |||||
/** | |||||
* 参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成 | |||||
*/ | |||||
CODE_301014(301014, "参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成"), | |||||
/** | |||||
* 参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid | |||||
*/ | |||||
CODE_301015(301015, "参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid"), | |||||
/** | |||||
* 上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制 | |||||
*/ | |||||
CODE_301016(301016, "上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制"), | |||||
/** | |||||
* 上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制 | |||||
*/ | |||||
CODE_301017(301017, "上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制"), | |||||
/** | |||||
* 参数 userid 无效;至少有一个userid不存在于通讯录中 | |||||
*/ | |||||
CODE_301021(301021, "参数 userid 无效;至少有一个userid不存在于通讯录中"), | |||||
/** | |||||
* 获取打卡数据失败;系统失败,可重试处理 | |||||
*/ | |||||
CODE_301022(301022, "获取打卡数据失败;系统失败,可重试处理"), | |||||
/** | |||||
* useridlist非法或超过限额;列表数量不能为0且不超过100 | |||||
*/ | |||||
CODE_301023(301023, "useridlist非法或超过限额;列表数量不能为0且不超过100"), | |||||
/** | |||||
* 获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天 | |||||
*/ | |||||
CODE_301024(301024, "获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天"), | |||||
/** | |||||
* 不允许更新该用户的userid | |||||
*/ | |||||
CODE_301036(301036, "不允许更新该用户的userid"), | |||||
/** | |||||
* 批量导入任务的文件中userid有重复 | |||||
*/ | |||||
CODE_302003(302003, "批量导入任务的文件中userid有重复"), | |||||
/** | |||||
* 组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查) | |||||
*/ | |||||
CODE_302004(302004, "组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查)"), | |||||
/** | |||||
* 批量导入系统失败,请重新尝试导入 | |||||
*/ | |||||
CODE_302005(302005, "批量导入系统失败,请重新尝试导入"), | |||||
/** | |||||
* 批量导入任务的文件中partyid有重复 | |||||
*/ | |||||
CODE_302006(302006, "批量导入任务的文件中partyid有重复"), | |||||
/** | |||||
* 批量导入任务的文件中,同一个部门下有两个子部门名字一样 | |||||
*/ | |||||
CODE_302007(302007, "批量导入任务的文件中,同一个部门下有两个子部门名字一样"), | |||||
/** | |||||
* CorpId参数无效;指定的CorpId不存在 | |||||
*/ | |||||
CODE_2000002(2000002, "CorpId参数无效;指定的CorpId不存在"); | |||||
private int code; | |||||
private String msg; | |||||
WxCpErrorMsgEnum(int code, String msg) { | |||||
this.code = code; | |||||
this.msg = msg; | |||||
} | |||||
/** | |||||
* 通过错误代码查找其中文含义. | |||||
*/ | |||||
public static String findMsgByCode(int code) { | |||||
WxCpErrorMsgEnum[] values = WxCpErrorMsgEnum.values(); | |||||
for (WxCpErrorMsgEnum value : values) { | |||||
if (value.code == code) { | |||||
return value.msg; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,80 @@ | |||||
package me.chanjar.weixin.common.error; | |||||
import java.io.Serializable; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.WxType; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
/** | |||||
* 微信错误码. | |||||
* 请阅读: | |||||
* 公众平台:<a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a> | |||||
* 企业微信:<a href="https://work.weixin.qq.com/api/doc#10649">全局错误码</a> | |||||
* | |||||
* @author Daniel Qian & Binary Wang | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
public class WxError implements Serializable { | |||||
private static final long serialVersionUID = 7869786563361406291L; | |||||
/** | |||||
* 微信错误代码. | |||||
*/ | |||||
private int errorCode; | |||||
/** | |||||
* 微信错误信息. | |||||
* (如果可以翻译为中文,就为中文) | |||||
*/ | |||||
private String errorMsg; | |||||
/** | |||||
* 微信接口返回的错误原始信息(英文). | |||||
*/ | |||||
private String errorMsgEn; | |||||
private String json; | |||||
public static WxError fromJson(String json) { | |||||
return fromJson(json, null); | |||||
} | |||||
public static WxError fromJson(String json, WxType type) { | |||||
final WxError wxError = WxGsonBuilder.create().fromJson(json, WxError.class); | |||||
if (StringUtils.isNotEmpty(wxError.getErrorMsg())) { | |||||
wxError.setErrorMsgEn(wxError.getErrorMsg()); | |||||
} | |||||
if (type == null) { | |||||
return wxError; | |||||
} | |||||
if (type == WxType.MP) { | |||||
final String msg = WxMpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||||
if (msg != null) { | |||||
wxError.setErrorMsg(msg); | |||||
} | |||||
} else if (type == WxType.CP) { | |||||
final String msg = WxCpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||||
if (msg != null) { | |||||
wxError.setErrorMsg(msg); | |||||
} | |||||
} | |||||
return wxError; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
if (this.json != null) { | |||||
return this.json; | |||||
} | |||||
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; | |||||
} | |||||
} |
@@ -1,9 +1,9 @@ | |||||
package me.chanjar.weixin.common.exception; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
package me.chanjar.weixin.common.error; | |||||
/** | |||||
* @author Daniel Qian | |||||
*/ | |||||
public class WxErrorException extends Exception { | public class WxErrorException extends Exception { | ||||
private static final long serialVersionUID = -6357149550353160810L; | private static final long serialVersionUID = -6357149550353160810L; | ||||
private WxError error; | private WxError error; |
@@ -0,0 +1,654 @@ | |||||
package me.chanjar.weixin.common.error; | |||||
import lombok.Getter; | |||||
/** | |||||
* <pre> | |||||
* 微信公众平台全局返回码. | |||||
* 参考文档:<a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">公众平台全局返回码</a> | |||||
* Created by Binary Wang on 2018/5/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
@Getter | |||||
public enum WxMpErrorMsgEnum { | |||||
/** | |||||
* 系统繁忙,此时请开发者稍候再试 | |||||
*/ | |||||
CODE_1(-1, "系统繁忙,此时请开发者稍候再试"), | |||||
/** | |||||
* 请求成功 | |||||
*/ | |||||
CODE_0(0, "请求成功"), | |||||
/** | |||||
* 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口 | |||||
*/ | |||||
CODE_40001(40001, "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口"), | |||||
/** | |||||
* 不合法的凭证类型 | |||||
*/ | |||||
CODE_40002(40002, "不合法的凭证类型"), | |||||
/** | |||||
* 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID | |||||
*/ | |||||
CODE_40003(40003, "不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID"), | |||||
/** | |||||
* 不合法的媒体文件类型 | |||||
*/ | |||||
CODE_40004(40004, "不合法的媒体文件类型"), | |||||
/** | |||||
* 不合法的文件类型 | |||||
*/ | |||||
CODE_40005(40005, "不合法的文件类型"), | |||||
/** | |||||
* 不合法的文件大小 | |||||
*/ | |||||
CODE_40006(40006, "不合法的文件大小"), | |||||
/** | |||||
* 不合法的媒体文件 id | |||||
*/ | |||||
CODE_40007(40007, "不合法的媒体文件 id"), | |||||
/** | |||||
* 不合法的消息类型 | |||||
*/ | |||||
CODE_40008(40008, "不合法的消息类型"), | |||||
/** | |||||
* 不合法的图片文件大小 | |||||
*/ | |||||
CODE_40009(40009, "不合法的图片文件大小"), | |||||
/** | |||||
* 不合法的语音文件大小 | |||||
*/ | |||||
CODE_40010(40010, "不合法的语音文件大小"), | |||||
/** | |||||
* 不合法的视频文件大小 | |||||
*/ | |||||
CODE_40011(40011, "不合法的视频文件大小"), | |||||
/** | |||||
* 不合法的缩略图文件大小 | |||||
*/ | |||||
CODE_40012(40012, "不合法的缩略图文件大小"), | |||||
/** | |||||
* 不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写 | |||||
*/ | |||||
CODE_40013(40013, "不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写"), | |||||
/** | |||||
* 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 | |||||
*/ | |||||
CODE_40014(40014, "不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口"), | |||||
/** | |||||
* 不合法的菜单类型 | |||||
*/ | |||||
CODE_40015(40015, "不合法的菜单类型"), | |||||
/** | |||||
* 不合法的按钮个数 | |||||
*/ | |||||
CODE_40016(40016, "不合法的按钮个数"), | |||||
/** | |||||
* 不合法的按钮个数 | |||||
*/ | |||||
CODE_40017(40017, "不合法的按钮个数"), | |||||
/** | |||||
* 不合法的按钮名字长度 | |||||
*/ | |||||
CODE_40018(40018, "不合法的按钮名字长度"), | |||||
/** | |||||
* 不合法的按钮 KEY 长度 | |||||
*/ | |||||
CODE_40019(40019, "不合法的按钮 KEY 长度"), | |||||
/** | |||||
* 不合法的按钮 URL 长度 | |||||
*/ | |||||
CODE_40020(40020, "不合法的按钮 URL 长度"), | |||||
/** | |||||
* 不合法的菜单版本号 | |||||
*/ | |||||
CODE_40021(40021, "不合法的菜单版本号"), | |||||
/** | |||||
* 不合法的子菜单级数 | |||||
*/ | |||||
CODE_40022(40022, "不合法的子菜单级数"), | |||||
/** | |||||
* 不合法的子菜单按钮个数 | |||||
*/ | |||||
CODE_40023(40023, "不合法的子菜单按钮个数"), | |||||
/** | |||||
* 不合法的子菜单按钮类型 | |||||
*/ | |||||
CODE_40024(40024, "不合法的子菜单按钮类型"), | |||||
/** | |||||
* 不合法的子菜单按钮名字长度 | |||||
*/ | |||||
CODE_40025(40025, "不合法的子菜单按钮名字长度"), | |||||
/** | |||||
* 不合法的子菜单按钮 KEY 长度 | |||||
*/ | |||||
CODE_40026(40026, "不合法的子菜单按钮 KEY 长度"), | |||||
/** | |||||
* 不合法的子菜单按钮 URL 长度 | |||||
*/ | |||||
CODE_40027(40027, "不合法的子菜单按钮 URL 长度"), | |||||
/** | |||||
* 不合法的自定义菜单使用用户 | |||||
*/ | |||||
CODE_40028(40028, "不合法的自定义菜单使用用户"), | |||||
/** | |||||
* 不合法的 oauth_code | |||||
*/ | |||||
CODE_40029(40029, "不合法的 oauth_code"), | |||||
/** | |||||
* 不合法的 refresh_token | |||||
*/ | |||||
CODE_40030(40030, "不合法的 refresh_token"), | |||||
/** | |||||
* 不合法的 openid 列表 | |||||
*/ | |||||
CODE_40031(40031, "不合法的 openid 列表"), | |||||
/** | |||||
* 不合法的 openid 列表长度 | |||||
*/ | |||||
CODE_40032(40032, "不合法的 openid 列表长度"), | |||||
/** | |||||
* 不合法的请求字符,不能包含\\uxxxx 格式的字符 | |||||
*/ | |||||
CODE_40033(40033, "不合法的请求字符,不能包含\\uxxxx 格式的字符"), | |||||
/** | |||||
* 不合法的参数 | |||||
*/ | |||||
CODE_40035(40035, "不合法的参数"), | |||||
/** | |||||
* 不合法的请求格式 | |||||
*/ | |||||
CODE_40038(40038, "不合法的请求格式"), | |||||
/** | |||||
* 不合法的 URL 长度 | |||||
*/ | |||||
CODE_40039(40039, "不合法的 URL 长度"), | |||||
/** | |||||
* 不合法的分组 id | |||||
*/ | |||||
CODE_40050(40050, "不合法的分组 id"), | |||||
/** | |||||
* 分组名字不合法 | |||||
*/ | |||||
CODE_40051(40051, "分组名字不合法"), | |||||
/** | |||||
* 删除单篇图文时,指定的 article_idx 不合法 | |||||
*/ | |||||
CODE_40060(40060, "删除单篇图文时,指定的 article_idx 不合法"), | |||||
/** | |||||
* 分组名字不合法 | |||||
*/ | |||||
CODE_40117(40117, "分组名字不合法"), | |||||
/** | |||||
* media_id 大小不合法 | |||||
*/ | |||||
CODE_40118(40118, "media_id 大小不合法"), | |||||
/** | |||||
* button 类型错误 | |||||
*/ | |||||
CODE_40119(40119, "button 类型错误"), | |||||
/** | |||||
* button 类型错误 | |||||
*/ | |||||
CODE_40120(40120, "button 类型错误"), | |||||
/** | |||||
* 不合法的 media_id 类型 | |||||
*/ | |||||
CODE_40121(40121, "不合法的 media_id 类型"), | |||||
/** | |||||
* 微信号不合法 | |||||
*/ | |||||
CODE_40132(40132, "微信号不合法"), | |||||
/** | |||||
* 不支持的图片格式 | |||||
*/ | |||||
CODE_40137(40137, "不支持的图片格式"), | |||||
/** | |||||
* 请勿添加其他公众号的主页链接 | |||||
*/ | |||||
CODE_40155(40155, "请勿添加其他公众号的主页链接"), | |||||
/** | |||||
* 缺少 access_token 参数 | |||||
*/ | |||||
CODE_41001(41001, "缺少 access_token 参数"), | |||||
/** | |||||
* 缺少 appid 参数 | |||||
*/ | |||||
CODE_41002(41002, "缺少 appid 参数"), | |||||
/** | |||||
* 缺少 refresh_token 参数 | |||||
*/ | |||||
CODE_41003(41003, "缺少 refresh_token 参数"), | |||||
/** | |||||
* 缺少 secret 参数 | |||||
*/ | |||||
CODE_41004(41004, "缺少 secret 参数"), | |||||
/** | |||||
* 缺少多媒体文件数据 | |||||
*/ | |||||
CODE_41005(41005, "缺少多媒体文件数据"), | |||||
/** | |||||
* 缺少 media_id 参数 | |||||
*/ | |||||
CODE_41006(41006, "缺少 media_id 参数"), | |||||
/** | |||||
* 缺少子菜单数据 | |||||
*/ | |||||
CODE_41007(41007, "缺少子菜单数据"), | |||||
/** | |||||
* 缺少 oauth code | |||||
*/ | |||||
CODE_41008(41008, "缺少 oauth code"), | |||||
/** | |||||
* 缺少 openid | |||||
*/ | |||||
CODE_41009(41009, "缺少 openid"), | |||||
/** | |||||
* access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明 | |||||
*/ | |||||
CODE_42001(42001, "access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明"), | |||||
/** | |||||
* refresh_token 超时 | |||||
*/ | |||||
CODE_42002(42002, "refresh_token 超时"), | |||||
/** | |||||
* oauth_code 超时 | |||||
*/ | |||||
CODE_42003(42003, "oauth_code 超时"), | |||||
/** | |||||
* 用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权 | |||||
*/ | |||||
CODE_42007(42007, "用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权"), | |||||
/** | |||||
* 需要 GET 请求 | |||||
*/ | |||||
CODE_43001(43001, "需要 GET 请求"), | |||||
/** | |||||
* 需要 POST 请求 | |||||
*/ | |||||
CODE_43002(43002, "需要 POST 请求"), | |||||
/** | |||||
* 需要 HTTPS 请求 | |||||
*/ | |||||
CODE_43003(43003, "需要 HTTPS 请求"), | |||||
/** | |||||
* 需要接收者关注 | |||||
*/ | |||||
CODE_43004(43004, "需要接收者关注"), | |||||
/** | |||||
* 需要好友关系 | |||||
*/ | |||||
CODE_43005(43005, "需要好友关系"), | |||||
/** | |||||
* 需要将接收者从黑名单中移除 | |||||
*/ | |||||
CODE_43019(43019, "需要将接收者从黑名单中移除"), | |||||
/** | |||||
* 多媒体文件为空 | |||||
*/ | |||||
CODE_44001(44001, "多媒体文件为空"), | |||||
/** | |||||
* POST 的数据包为空 | |||||
*/ | |||||
CODE_44002(44002, "POST 的数据包为空"), | |||||
/** | |||||
* 图文消息内容为空 | |||||
*/ | |||||
CODE_44003(44003, "图文消息内容为空"), | |||||
/** | |||||
* 文本消息内容为空 | |||||
*/ | |||||
CODE_44004(44004, "文本消息内容为空"), | |||||
/** | |||||
* 多媒体文件大小超过限制 | |||||
*/ | |||||
CODE_45001(45001, "多媒体文件大小超过限制"), | |||||
/** | |||||
* 消息内容超过限制 | |||||
*/ | |||||
CODE_45002(45002, "消息内容超过限制"), | |||||
/** | |||||
* 标题字段超过限制 | |||||
*/ | |||||
CODE_45003(45003, "标题字段超过限制"), | |||||
/** | |||||
* 描述字段超过限制 | |||||
*/ | |||||
CODE_45004(45004, "描述字段超过限制"), | |||||
/** | |||||
* 链接字段超过限制 | |||||
*/ | |||||
CODE_45005(45005, "链接字段超过限制"), | |||||
/** | |||||
* 图片链接字段超过限制 | |||||
*/ | |||||
CODE_45006(45006, "图片链接字段超过限制"), | |||||
/** | |||||
* 语音播放时间超过限制 | |||||
*/ | |||||
CODE_45007(45007, "语音播放时间超过限制"), | |||||
/** | |||||
* 图文消息超过限制 | |||||
*/ | |||||
CODE_45008(45008, "图文消息超过限制"), | |||||
/** | |||||
* 接口调用超过限制 | |||||
*/ | |||||
CODE_45009(45009, "接口调用超过限制"), | |||||
/** | |||||
* 创建菜单个数超过限制 | |||||
*/ | |||||
CODE_45010(45010, "创建菜单个数超过限制"), | |||||
/** | |||||
* API 调用太频繁,请稍候再试 | |||||
*/ | |||||
CODE_45011(45011, "API 调用太频繁,请稍候再试"), | |||||
/** | |||||
* 回复时间超过限制 | |||||
*/ | |||||
CODE_45015(45015, "回复时间超过限制"), | |||||
/** | |||||
* 系统分组,不允许修改 | |||||
*/ | |||||
CODE_45016(45016, "系统分组,不允许修改"), | |||||
/** | |||||
* 分组名字过长 | |||||
*/ | |||||
CODE_45017(45017, "分组名字过长"), | |||||
/** | |||||
* 分组数量超过上限 | |||||
*/ | |||||
CODE_45018(45018, "分组数量超过上限"), | |||||
/** | |||||
* 客服接口下行条数超过上限 | |||||
*/ | |||||
CODE_45047(45047, "客服接口下行条数超过上限"), | |||||
/** | |||||
* 不存在媒体数据 | |||||
*/ | |||||
CODE_46001(46001, "不存在媒体数据"), | |||||
/** | |||||
* 不存在的菜单版本 | |||||
*/ | |||||
CODE_46002(46002, "不存在的菜单版本"), | |||||
/** | |||||
* 不存在的菜单数据 | |||||
*/ | |||||
CODE_46003(46003, "不存在的菜单数据"), | |||||
/** | |||||
* 不存在的用户 | |||||
*/ | |||||
CODE_46004(46004, "不存在的用户"), | |||||
/** | |||||
* 解析 JSON/XML 内容错误 | |||||
*/ | |||||
CODE_47001(47001, "解析 JSON/XML 内容错误"), | |||||
/** | |||||
* api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限 | |||||
*/ | |||||
CODE_48001(48001, "api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限"), | |||||
/** | |||||
* 粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” ) | |||||
*/ | |||||
CODE_48002(48002, "粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” )"), | |||||
/** | |||||
* api 接口被封禁,请登录 mp.weixin.qq.com 查看详情 | |||||
*/ | |||||
CODE_48004(48004, "api 接口被封禁,请登录 mp.weixin.qq.com 查看详情"), | |||||
/** | |||||
* api 禁止删除被自动回复和自定义菜单引用的素材 | |||||
*/ | |||||
CODE_48005(48005, "api 禁止删除被自动回复和自定义菜单引用的素材"), | |||||
/** | |||||
* api 禁止清零调用次数,因为清零次数达到上限 | |||||
*/ | |||||
CODE_48006(48006, "api 禁止清零调用次数,因为清零次数达到上限"), | |||||
/** | |||||
* 没有该类型消息的发送权限 | |||||
*/ | |||||
CODE_48008(48008, "没有该类型消息的发送权限"), | |||||
/** | |||||
* 用户未授权该 api | |||||
*/ | |||||
CODE_50001(50001, "用户未授权该 api"), | |||||
/** | |||||
* 用户受限,可能是违规后接口被封禁 | |||||
*/ | |||||
CODE_50002(50002, "用户受限,可能是违规后接口被封禁"), | |||||
/** | |||||
* 用户未关注公众号 | |||||
*/ | |||||
CODE_50005(50005, "用户未关注公众号"), | |||||
/** | |||||
* 参数错误 (invalid parameter) | |||||
*/ | |||||
CODE_61451(61451, "参数错误 (invalid parameter)"), | |||||
/** | |||||
* 无效客服账号 (invalid kf_account) | |||||
*/ | |||||
CODE_61452(61452, "无效客服账号 (invalid kf_account)"), | |||||
/** | |||||
* 客服帐号已存在 (kf_account exsited) | |||||
*/ | |||||
CODE_61453(61453, "客服帐号已存在 (kf_account exsited)"), | |||||
/** | |||||
* 客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length) | |||||
*/ | |||||
CODE_61454(61454, "客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length)"), | |||||
/** | |||||
* 客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account) | |||||
*/ | |||||
CODE_61455(61455, "客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account)"), | |||||
/** | |||||
* 客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded) | |||||
*/ | |||||
CODE_61456(61456, "客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded)"), | |||||
/** | |||||
* 无效头像文件类型 (invalid file type) | |||||
*/ | |||||
CODE_61457(61457, "无效头像文件类型 (invalid file type)"), | |||||
/** | |||||
* 系统错误 (system error) | |||||
*/ | |||||
CODE_61450(61450, "系统错误 (system error)"), | |||||
/** | |||||
* 日期格式错误 | |||||
*/ | |||||
CODE_61500(61500, "日期格式错误"), | |||||
/** | |||||
* 不存在此 menuid 对应的个性化菜单 | |||||
*/ | |||||
CODE_65301(65301, "不存在此 menuid 对应的个性化菜单"), | |||||
/** | |||||
* 没有相应的用户 | |||||
*/ | |||||
CODE_65302(65302, "没有相应的用户"), | |||||
/** | |||||
* 没有默认菜单,不能创建个性化菜单 | |||||
*/ | |||||
CODE_65303(65303, "没有默认菜单,不能创建个性化菜单"), | |||||
/** | |||||
* MatchRule 信息为空 | |||||
*/ | |||||
CODE_65304(65304, "MatchRule 信息为空"), | |||||
/** | |||||
* 个性化菜单数量受限 | |||||
*/ | |||||
CODE_65305(65305, "个性化菜单数量受限"), | |||||
/** | |||||
* 不支持个性化菜单的帐号 | |||||
*/ | |||||
CODE_65306(65306, "不支持个性化菜单的帐号"), | |||||
/** | |||||
* 个性化菜单信息为空 | |||||
*/ | |||||
CODE_65307(65307, "个性化菜单信息为空"), | |||||
/** | |||||
* 包含没有响应类型的 button | |||||
*/ | |||||
CODE_65308(65308, "包含没有响应类型的 button"), | |||||
/** | |||||
* 个性化菜单开关处于关闭状态 | |||||
*/ | |||||
CODE_65309(65309, "个性化菜单开关处于关闭状态"), | |||||
/** | |||||
* 填写了省份或城市信息,国家信息不能为空 | |||||
*/ | |||||
CODE_65310(65310, "填写了省份或城市信息,国家信息不能为空"), | |||||
/** | |||||
* 填写了城市信息,省份信息不能为空 | |||||
*/ | |||||
CODE_65311(65311, "填写了城市信息,省份信息不能为空"), | |||||
/** | |||||
* 不合法的国家信息 | |||||
*/ | |||||
CODE_65312(65312, "不合法的国家信息"), | |||||
/** | |||||
* 不合法的省份信息 | |||||
*/ | |||||
CODE_65313(65313, "不合法的省份信息"), | |||||
/** | |||||
* 不合法的城市信息 | |||||
*/ | |||||
CODE_65314(65314, "不合法的城市信息"), | |||||
/** | |||||
* 该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接) | |||||
*/ | |||||
CODE_65316(65316, "该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接)"), | |||||
/** | |||||
* 不合法的 URL | |||||
*/ | |||||
CODE_65317(65317, "不合法的 URL"), | |||||
/** | |||||
* POST 数据参数不合法 | |||||
*/ | |||||
CODE_9001001(9001001, "POST 数据参数不合法"), | |||||
/** | |||||
* 远端服务不可用 | |||||
*/ | |||||
CODE_9001002(9001002, "远端服务不可用"), | |||||
/** | |||||
* Ticket 不合法 | |||||
*/ | |||||
CODE_9001003(9001003, "Ticket 不合法"), | |||||
/** | |||||
* 获取摇周边用户信息失败 | |||||
*/ | |||||
CODE_9001004(9001004, "获取摇周边用户信息失败"), | |||||
/** | |||||
* 获取商户信息失败 | |||||
*/ | |||||
CODE_9001005(9001005, "获取商户信息失败"), | |||||
/** | |||||
* 获取 OpenID 失败 | |||||
*/ | |||||
CODE_9001006(9001006, "获取 OpenID 失败"), | |||||
/** | |||||
* 上传文件缺失 | |||||
*/ | |||||
CODE_9001007(9001007, "上传文件缺失"), | |||||
/** | |||||
* 上传素材的文件类型不合法 | |||||
*/ | |||||
CODE_9001008(9001008, "上传素材的文件类型不合法"), | |||||
/** | |||||
* 上传素材的文件尺寸不合法 | |||||
*/ | |||||
CODE_9001009(9001009, "上传素材的文件尺寸不合法"), | |||||
/** | |||||
* 上传失败 | |||||
*/ | |||||
CODE_9001010(9001010, "上传失败"), | |||||
/** | |||||
* 帐号不合法 | |||||
*/ | |||||
CODE_9001020(9001020, "帐号不合法"), | |||||
/** | |||||
* 已有设备激活率低于 50% ,不能新增设备 | |||||
*/ | |||||
CODE_9001021(9001021, "已有设备激活率低于 50% ,不能新增设备"), | |||||
/** | |||||
* 设备申请数不合法,必须为大于 0 的数字 | |||||
*/ | |||||
CODE_9001022(9001022, "设备申请数不合法,必须为大于 0 的数字"), | |||||
/** | |||||
* 已存在审核中的设备 ID 申请 | |||||
*/ | |||||
CODE_9001023(9001023, "已存在审核中的设备 ID 申请"), | |||||
/** | |||||
* 一次查询设备 ID 数量不能超过 50 | |||||
*/ | |||||
CODE_9001024(9001024, "一次查询设备 ID 数量不能超过 50"), | |||||
/** | |||||
* 设备 ID 不合法 | |||||
*/ | |||||
CODE_9001025(9001025, "设备 ID 不合法"), | |||||
/** | |||||
* 页面 ID 不合法 | |||||
*/ | |||||
CODE_9001026(9001026, "页面 ID 不合法"), | |||||
/** | |||||
* 页面参数不合法 | |||||
*/ | |||||
CODE_9001027(9001027, "页面参数不合法"), | |||||
/** | |||||
* 一次删除页面 ID 数量不能超过 10 | |||||
*/ | |||||
CODE_9001028(9001028, "一次删除页面 ID 数量不能超过 10"), | |||||
/** | |||||
* 页面已应用在设备中,请先解除应用关系再删除 | |||||
*/ | |||||
CODE_9001029(9001029, "页面已应用在设备中,请先解除应用关系再删除"), | |||||
/** | |||||
* 一次查询页面 ID 数量不能超过 50 | |||||
*/ | |||||
CODE_9001030(9001030, "一次查询页面 ID 数量不能超过 50"), | |||||
/** | |||||
* 时间区间不合法 | |||||
*/ | |||||
CODE_9001031(9001031, "时间区间不合法"), | |||||
/** | |||||
* 保存设备与页面的绑定关系参数错误 | |||||
*/ | |||||
CODE_9001032(9001032, "保存设备与页面的绑定关系参数错误"), | |||||
/** | |||||
* 门店 ID 不合法 | |||||
*/ | |||||
CODE_9001033(9001033, "门店 ID 不合法"), | |||||
/** | |||||
* 设备备注信息过长 | |||||
*/ | |||||
CODE_9001034(9001034, "设备备注信息过长"), | |||||
/** | |||||
* 设备申请参数不合法 | |||||
*/ | |||||
CODE_9001035(9001035, "设备申请参数不合法"), | |||||
/** | |||||
* 查询起始值 begin 不合法 | |||||
*/ | |||||
CODE_9001036(9001036, "查询起始值 begin 不合法"); | |||||
private int code; | |||||
private String msg; | |||||
WxMpErrorMsgEnum(int code, String msg) { | |||||
this.code = code; | |||||
this.msg = msg; | |||||
} | |||||
/** | |||||
* 通过错误代码查找其中文含义. | |||||
*/ | |||||
public static String findMsgByCode(int code) { | |||||
WxMpErrorMsgEnum[] values = WxMpErrorMsgEnum.values(); | |||||
for (WxMpErrorMsgEnum value : values) { | |||||
if (value.code == code) { | |||||
return value.msg; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -1,21 +1,17 @@ | |||||
package me.chanjar.weixin.common.util; | package me.chanjar.weixin.common.util; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.google.common.collect.Maps; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||
import java.lang.reflect.Modifier; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -0,0 +1,24 @@ | |||||
package me.chanjar.weixin.common.util; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
/** | |||||
* <pre> | |||||
* 数据处理工具类 | |||||
* Created by BinaryWang on 2018/5/8. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
public class DataUtils { | |||||
/** | |||||
* 将数据中包含的secret字符使用星号替换,防止日志打印时被输出 | |||||
*/ | |||||
public static <E> E handleDataWithSecret(E data) { | |||||
E dataForLog = data; | |||||
if(data instanceof String && StringUtils.contains((String)data, "&secret=")){ | |||||
dataForLog = (E) StringUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&"); | |||||
} | |||||
return dataForLog; | |||||
} | |||||
} |
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util; | package me.chanjar.weixin.common.util; | ||||
import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
@@ -19,7 +19,7 @@ public class FileUtils { | |||||
File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile); | File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile); | ||||
resultFile.deleteOnExit(); | resultFile.deleteOnExit(); | ||||
org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, resultFile); | |||||
org.apache.commons.io.FileUtils.copyToFile(inputStream, resultFile); | |||||
return resultFile; | return resultFile; | ||||
} | } | ||||
@@ -1,8 +1,8 @@ | |||||
package me.chanjar.weixin.common.util.http; | package me.chanjar.weixin.common.util.http; | ||||
import jodd.http.HttpResponse; | import jodd.http.HttpResponse; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import okhttp3.Response; | import okhttp3.Response; | ||||
import org.apache.http.Header; | import org.apache.http.Header; | ||||
import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.common.util.http; | package me.chanjar.weixin.common.util.http; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
@@ -9,51 +9,13 @@ import java.io.IOException; | |||||
* | * | ||||
* @param <T> 返回值类型 | * @param <T> 返回值类型 | ||||
* @param <E> 请求参数类型 | * @param <E> 请求参数类型 | ||||
* @author Daniel Qian | |||||
*/ | */ | ||||
public interface RequestExecutor<T, E> { | public interface RequestExecutor<T, E> { | ||||
/** | /** | ||||
* @param uri uri | * @param uri uri | ||||
* @param data 数据 | * @param data 数据 | ||||
* @throws WxErrorException | |||||
* @throws IOException | |||||
*/ | */ | ||||
T execute(String uri, E data) throws WxErrorException, IOException; | T execute(String uri, E data) throws WxErrorException, IOException; | ||||
/** | |||||
* apache-http实现方式 | |||||
* @param httpclient | |||||
* @param httpProxy | |||||
* @param uri | |||||
* @param data | |||||
* @return | |||||
* @throws WxErrorException | |||||
* @throws IOException | |||||
*//* | |||||
T executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException; | |||||
*//** | |||||
* jodd-http实现方式 | |||||
* @param provider | |||||
* @param proxyInfo | |||||
* @param uri | |||||
* @param data | |||||
* @return | |||||
* @throws WxErrorException | |||||
* @throws IOException | |||||
*//* | |||||
T executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; | |||||
*//** okhttp实现方式 | |||||
* @param pool | |||||
* @param proxyInfo | |||||
* @param uri | |||||
* @param data | |||||
* @return | |||||
* @throws WxErrorException | |||||
* @throws IOException | |||||
*//* | |||||
T executeOkhttp(ConnectionPool pool, final OkHttpProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; | |||||
*/ | |||||
} | } |
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.http.apache; | package me.chanjar.weixin.common.util.http.apache; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | ||||
import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
@@ -1,11 +1,9 @@ | |||||
package me.chanjar.weixin.common.util.http.apache; | package me.chanjar.weixin.common.util.http.apache; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import org.apache.commons.io.FilenameUtils; | import org.apache.commons.io.FilenameUtils; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.apache.http.Header; | import org.apache.http.Header; | ||||
@@ -16,9 +14,12 @@ import org.apache.http.client.methods.HttpGet; | |||||
import org.apache.http.entity.ContentType; | import org.apache.http.entity.ContentType; | ||||
import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||||
/** | /** | ||||
* Created by ecoolper on 2017/5/5. | * Created by ecoolper on 2017/5/5. | ||||
@@ -45,8 +46,7 @@ public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequest | |||||
} | } | ||||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet); | try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet); | ||||
InputStream inputStream = InputStreamResponseHandler.INSTANCE | |||||
.handleResponse(response)) { | |||||
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) { | |||||
Header[] contentTypeHeader = response.getHeaders("Content-Type"); | Header[] contentTypeHeader = response.getHeaders("Content-Type"); | ||||
if (contentTypeHeader != null && contentTypeHeader.length > 0) { | if (contentTypeHeader != null && contentTypeHeader.length > 0) { | ||||
if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | ||||
@@ -1,8 +1,8 @@ | |||||
package me.chanjar.weixin.common.util.http.apache; | package me.chanjar.weixin.common.util.http.apache; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import org.apache.http.HttpEntity; | import org.apache.http.HttpEntity; | ||||
@@ -10,7 +10,6 @@ import org.apache.http.HttpHost; | |||||
import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
import org.apache.http.client.methods.HttpPost; | import org.apache.http.client.methods.HttpPost; | ||||
import org.apache.http.entity.ContentType; | |||||
import org.apache.http.entity.mime.HttpMultipartMode; | import org.apache.http.entity.mime.HttpMultipartMode; | ||||
import org.apache.http.entity.mime.MultipartEntityBuilder; | import org.apache.http.entity.mime.MultipartEntityBuilder; | ||||
import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.http.apache; | package me.chanjar.weixin.common.util.http.apache; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | ||||
import org.apache.http.Consts; | import org.apache.http.Consts; | ||||
@@ -1,23 +1,24 @@ | |||||
package me.chanjar.weixin.common.util.http.jodd; | package me.chanjar.weixin.common.util.http.jodd; | ||||
import java.io.ByteArrayInputStream; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import org.apache.commons.io.FilenameUtils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import jodd.http.HttpConnectionProvider; | import jodd.http.HttpConnectionProvider; | ||||
import jodd.http.HttpRequest; | import jodd.http.HttpRequest; | ||||
import jodd.http.HttpResponse; | import jodd.http.HttpResponse; | ||||
import jodd.http.ProxyInfo; | import jodd.http.ProxyInfo; | ||||
import jodd.util.StringPool; | import jodd.util.StringPool; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import org.apache.commons.io.FilenameUtils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.ByteArrayInputStream; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
/** | /** | ||||
* Created by ecoolper on 2017/5/5. | * Created by ecoolper on 2017/5/5. | ||||
@@ -57,9 +58,12 @@ public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadReque | |||||
return null; | return null; | ||||
} | } | ||||
InputStream inputStream = new ByteArrayInputStream(response.bodyBytes()); | |||||
return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName), | |||||
super.tmpDirFile); | |||||
try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) { | |||||
return FileUtils.createTmpFile(inputStream, | |||||
FilenameUtils.getBaseName(fileName), | |||||
FilenameUtils.getExtension(fileName), | |||||
super.tmpDirFile); | |||||
} | |||||
} | } | ||||
@@ -6,9 +6,9 @@ import jodd.http.HttpResponse; | |||||
import jodd.http.ProxyInfo; | import jodd.http.ProxyInfo; | ||||
import jodd.util.StringPool; | import jodd.util.StringPool; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
@@ -3,8 +3,8 @@ package me.chanjar.weixin.common.util.http.jodd; | |||||
import jodd.http.*; | import jodd.http.*; | ||||
import jodd.util.StringPool; | import jodd.util.StringPool; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | ||||
@@ -5,8 +5,8 @@ import jodd.http.HttpRequest; | |||||
import jodd.http.HttpResponse; | import jodd.http.HttpResponse; | ||||
import jodd.http.ProxyInfo; | import jodd.http.ProxyInfo; | ||||
import jodd.util.StringPool; | import jodd.util.StringPool; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.http.okhttp; | package me.chanjar.weixin.common.util.http.okhttp; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | import me.chanjar.weixin.common.util.http.HttpResponseProxy; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
@@ -1,8 +1,8 @@ | |||||
package me.chanjar.weixin.common.util.http.okhttp; | package me.chanjar.weixin.common.util.http.okhttp; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import okhttp3.*; | import okhttp3.*; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.http.okhttp; | package me.chanjar.weixin.common.util.http.okhttp; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | ||||
import okhttp3.*; | import okhttp3.*; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.http.okhttp; | package me.chanjar.weixin.common.util.http.okhttp; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | ||||
import okhttp3.*; | import okhttp3.*; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.json; | package me.chanjar.weixin.common.util.json; | ||||
import com.google.gson.*; | import com.google.gson.*; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
@@ -4,7 +4,7 @@ import com.google.gson.Gson; | |||||
import com.google.gson.GsonBuilder; | import com.google.gson.GsonBuilder; | ||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
public class WxGsonBuilder { | public class WxGsonBuilder { | ||||
@@ -1,5 +1,7 @@ | |||||
package me.chanjar.weixin.common.util.xml; | package me.chanjar.weixin.common.util.xml; | ||||
import java.io.Writer; | |||||
import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; | import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; | ||||
import com.thoughtworks.xstream.core.util.QuickWriter; | import com.thoughtworks.xstream.core.util.QuickWriter; | ||||
@@ -9,8 +11,6 @@ import com.thoughtworks.xstream.io.xml.XppDriver; | |||||
import com.thoughtworks.xstream.security.NullPermission; | import com.thoughtworks.xstream.security.NullPermission; | ||||
import com.thoughtworks.xstream.security.PrimitiveTypePermission; | import com.thoughtworks.xstream.security.PrimitiveTypePermission; | ||||
import java.io.Writer; | |||||
public class XStreamInitializer { | public class XStreamInitializer { | ||||
public static XStream getInstance() { | public static XStream getInstance() { | ||||
@@ -38,7 +38,8 @@ public class XStreamInitializer { | |||||
@Override | @Override | ||||
public String encodeNode(String name) { | public String encodeNode(String name) { | ||||
return name;//防止将_转换成__ | |||||
//防止将_转换成__ | |||||
return name; | |||||
} | } | ||||
}; | }; | ||||
} | } | ||||
@@ -48,6 +49,7 @@ public class XStreamInitializer { | |||||
xstream.setMode(XStream.NO_REFERENCES); | xstream.setMode(XStream.NO_REFERENCES); | ||||
xstream.addPermission(NullPermission.NULL); | xstream.addPermission(NullPermission.NULL); | ||||
xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
return xstream; | return xstream; | ||||
} | } | ||||
@@ -1,8 +1,9 @@ | |||||
package me.chanjar.weixin.common.bean; | |||||
package me.chanjar.weixin.common.error; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import org.testng.*; | |||||
import org.testng.annotations.*; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.Test; | |||||
import static org.testng.Assert.*; | |||||
@Test | @Test | ||||
public class WxErrorTest { | public class WxErrorTest { | ||||
@@ -10,26 +11,24 @@ public class WxErrorTest { | |||||
public void testFromJson() { | public void testFromJson() { | ||||
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; | String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; | ||||
WxError wxError = WxError.fromJson(json); | WxError wxError = WxError.fromJson(json); | ||||
Assert.assertTrue(wxError.getErrorCode() == 40003); | |||||
Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||||
assertEquals(40003, wxError.getErrorCode()); | |||||
assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||||
} | } | ||||
public void testFromBadJson1() { | public void testFromBadJson1() { | ||||
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; | String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; | ||||
WxError wxError = WxError.fromJson(json); | WxError wxError = WxError.fromJson(json); | ||||
Assert.assertTrue(wxError.getErrorCode() == 40003); | |||||
Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||||
assertEquals(40003, wxError.getErrorCode()); | |||||
assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||||
} | } | ||||
public void testFromBadJson2() { | public void testFromBadJson2() { | ||||
String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; | String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; | ||||
WxError wxError = WxError.fromJson(json); | WxError wxError = WxError.fromJson(json); | ||||
Assert.assertTrue(wxError.getErrorCode() == 0); | |||||
Assert.assertEquals(wxError.getErrorMsg(), null); | |||||
assertEquals(0, wxError.getErrorCode()); | |||||
assertEquals(wxError.getErrorMsg(), null); | |||||
} | } | ||||
@@ -0,0 +1,23 @@ | |||||
package me.chanjar.weixin.common.util; | |||||
import org.testng.annotations.Test; | |||||
import static org.assertj.core.api.Assertions.assertThat; | |||||
import static org.testng.Assert.*; | |||||
/** | |||||
* <pre> | |||||
* Created by BinaryWang on 2018/5/8. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
public class DataUtilsTest { | |||||
@Test | |||||
public void testHandleDataWithSecret() { | |||||
String data = "js_code=001tZveq0SMoiq1AEXeq0ECJeq0tZveZ&secret=5681022fa1643845392367ea88888888&grant_type=authorization_code&appid=wxe156d4848d999999"; | |||||
final String s = DataUtils.handleDataWithSecret(data); | |||||
assertThat(s).contains("&secret=******&"); | |||||
} | |||||
} |
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>3.0.0</version> | |||||
<version>3.1.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-cp</artifactId> | <artifactId>weixin-java-cp</artifactId> | ||||
@@ -0,0 +1,28 @@ | |||||
package me.chanjar.weixin.cp.api; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.bean.WxCpAgent; | |||||
/** | |||||
* <pre> | |||||
* 管理企业号应用 | |||||
* Created by huansinho on 2018/4/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/huansinho">huansinho</a> | |||||
*/ | |||||
public interface WxCpAgentService { | |||||
/** | |||||
* <pre> | |||||
* 获取企业号应用信息 | |||||
* 该API用于获取企业号某个应用的基本信息,包括头像、昵称、帐号类型、认证类型、可见范围等信息 | |||||
* 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=获取企业号应用 | |||||
* </pre> | |||||
* | |||||
* @param agentId 企业应用的id | |||||
* @return 部门id | |||||
*/ | |||||
WxCpAgent get(Integer agentId) throws WxErrorException; | |||||
} |
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.bean.WxCpDepart; | import me.chanjar.weixin.cp.bean.WxCpDepart; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -1,12 +1,12 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 媒体管理接口 | * 媒体管理接口 | ||||
@@ -30,7 +30,7 @@ public interface WxCpMediaService { | |||||
* | * | ||||
* @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} | * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} | ||||
* @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} | * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} | ||||
* @param inputStream 输入流 | |||||
* @param inputStream 输入流,需要调用方控制关闭该输入流 | |||||
*/ | */ | ||||
WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream) | WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream) | ||||
throws WxErrorException, IOException; | throws WxErrorException, IOException; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -1,6 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.bean.WxCpUserDetail; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -64,4 +65,19 @@ public interface WxCpOAuth2Service { | |||||
*/ | */ | ||||
String[] getUserInfo(Integer agentId, String code) throws WxErrorException; | String[] getUserInfo(Integer agentId, String code) throws WxErrorException; | ||||
/** | |||||
* <pre> | |||||
* 使用user_ticket获取成员详情. | |||||
* | |||||
* 文档地址:https://work.weixin.qq.com/api/doc#10028/%E4%BD%BF%E7%94%A8user_ticket%E8%8E%B7%E5%8F%96%E6%88%90%E5%91%98%E8%AF%A6%E6%83%85 | |||||
* 请求方式:POST(HTTPS) | |||||
* 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=ACCESS_TOKEN | |||||
* | |||||
* 权限说明: | |||||
* 需要有对应应用的使用权限,且成员必须在授权应用的可见范围内。 | |||||
* </pre> | |||||
* | |||||
* @param userTicket 成员票据 | |||||
*/ | |||||
WxCpUserDetail getUserDetail(String userTicket) throws WxErrorException; | |||||
} | } |
@@ -1,9 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | import me.chanjar.weixin.common.bean.WxJsapiSignature; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSession; | import me.chanjar.weixin.common.session.WxSession; | ||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
@@ -12,11 +10,6 @@ import me.chanjar.weixin.common.util.http.RequestHttp; | |||||
import me.chanjar.weixin.cp.bean.*; | import me.chanjar.weixin.cp.bean.*; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.util.List; | |||||
/** | /** | ||||
* 微信API的Service | * 微信API的Service | ||||
* @author chanjaster | * @author chanjaster | ||||
@@ -249,6 +242,8 @@ public interface WxCpService { | |||||
*/ | */ | ||||
WxCpUserService getUserService(); | WxCpUserService getUserService(); | ||||
WxCpAgentService getAgentService(); | |||||
/** | /** | ||||
* http请求对象 | * http请求对象 | ||||
*/ | */ | ||||
@@ -1,15 +1,16 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.bean.WxCpTag; | import me.chanjar.weixin.cp.bean.WxCpTag; | ||||
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; | 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.bean.WxCpUser; | ||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 标签管理接口 | |||||
* 标签管理接口. | |||||
* Created by BinaryWang on 2017/6/24. | * Created by BinaryWang on 2017/6/24. | ||||
* </pre> | * </pre> | ||||
* | * | ||||
@@ -17,14 +18,14 @@ import java.util.List; | |||||
*/ | */ | ||||
public interface WxCpTagService { | public interface WxCpTagService { | ||||
/** | /** | ||||
* 创建标签 | |||||
* 创建标签. | |||||
* | * | ||||
* @param tagName 标签名 | * @param tagName 标签名 | ||||
*/ | */ | ||||
String create(String tagName) throws WxErrorException; | String create(String tagName) throws WxErrorException; | ||||
/** | /** | ||||
* 更新标签 | |||||
* 更新标签. | |||||
* | * | ||||
* @param tagId 标签id | * @param tagId 标签id | ||||
* @param tagName 标签名 | * @param tagName 标签名 | ||||
@@ -32,35 +33,49 @@ public interface WxCpTagService { | |||||
void update(String tagId, String tagName) throws WxErrorException; | void update(String tagId, String tagName) throws WxErrorException; | ||||
/** | /** | ||||
* 删除标签 | |||||
* 删除标签. | |||||
* | * | ||||
* @param tagId 标签id | * @param tagId 标签id | ||||
*/ | */ | ||||
void delete(String tagId) throws WxErrorException; | void delete(String tagId) throws WxErrorException; | ||||
/** | /** | ||||
* 获得标签列表 | |||||
* 获得标签列表. | |||||
*/ | */ | ||||
List<WxCpTag> listAll() throws WxErrorException; | List<WxCpTag> listAll() throws WxErrorException; | ||||
/** | /** | ||||
* 获取标签成员 | |||||
* 获取标签成员. | |||||
* | * | ||||
* @param tagId 标签ID | * @param tagId 标签ID | ||||
*/ | */ | ||||
List<WxCpUser> listUsersByTagId(String tagId) throws WxErrorException; | List<WxCpUser> listUsersByTagId(String tagId) throws WxErrorException; | ||||
/** | /** | ||||
* 增加标签成员 | |||||
* @param tagId 标签id | |||||
* @param userIds 用户ID 列表 | |||||
* 增加标签成员. | |||||
* | |||||
* @param tagId 标签id | |||||
* @param userIds 用户ID 列表 | |||||
* @param partyIds 企业部门ID列表 | |||||
*/ | */ | ||||
WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException; | WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException; | ||||
/** | /** | ||||
* 移除标签成员 | |||||
* @param tagId 标签id | |||||
* @param userIds 用户id列表 | |||||
* 移除标签成员. | |||||
* | |||||
* @param tagId 标签id | |||||
* @param userIds 用户id列表 | |||||
* @param partyIds 企业部门ID列表 | |||||
*/ | */ | ||||
WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List<String> userIds) throws WxErrorException; | |||||
WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException; | |||||
/** | |||||
* 获取标签成员. | |||||
* 对应: http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 中的get接口 | |||||
* | |||||
* @param tagId 标签id | |||||
*/ | |||||
WxCpTagGetResult get(String tagId) throws WxErrorException; | |||||
} | } |
@@ -1,6 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
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.WxCpUser; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -84,18 +85,18 @@ public interface WxCpUserService { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 邀请成员关注 | |||||
* http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E9.82.80.E8.AF.B7.E6.88.90.E5.91.98.E5.85.B3.E6.B3.A8 | |||||
* 邀请成员 | |||||
* 企业可通过接口批量邀请成员使用企业微信,邀请后将通过短信或邮件下发通知。 | |||||
* 请求方式:POST(HTTPS) | |||||
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/batch/invite?access_token=ACCESS_TOKEN | |||||
* 文档地址:https://work.weixin.qq.com/api/doc#12543 | |||||
* </pre> | * </pre> | ||||
* | * | ||||
* @param userId 用户的userid | |||||
* @param inviteTips 推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。 | |||||
* @return 1:微信邀请 2.邮件邀请 | |||||
* @deprecated api obsoleted. 邀请关注的功能微信企业号已经下线了, | |||||
* 详细请参考该链接点击查看 https://qy.weixin.qq.com/cgi-bin/homepagenotify?action=get&id=46 | |||||
* @param userIds 成员ID列表, 最多支持1000个。 | |||||
* @param partyIds 部门ID列表,最多支持100个。 | |||||
* @param tagIds 标签ID列表,最多支持100个。 | |||||
*/ | */ | ||||
@Deprecated | |||||
int invite(String userId, String inviteTips) throws WxErrorException; | |||||
WxCpInviteResult invite(List<String> userIds, List<String> partyIds, List<String> tagIds) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -0,0 +1,37 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpAgentService; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | |||||
import me.chanjar.weixin.cp.bean.WxCpAgent; | |||||
/** | |||||
* <pre> | |||||
* 管理企业号应用 | |||||
* Created by huansinho on 2018/4/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/huansinho">huansinho</a> | |||||
*/ | |||||
public class WxCpAgentServiceImpl implements WxCpAgentService { | |||||
private WxCpService mainService; | |||||
public WxCpAgentServiceImpl(WxCpService mainService) { | |||||
this.mainService = mainService; | |||||
} | |||||
@Override | |||||
public WxCpAgent get(Integer agentId) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/get"; | |||||
if (agentId != null) { | |||||
url += "?agentid=" + agentId; | |||||
} else { | |||||
throw new IllegalArgumentException("缺少agentid参数"); | |||||
} | |||||
String responseContent = this.mainService.get(url, null); | |||||
return WxCpAgent.fromJson(responseContent); | |||||
} | |||||
} |
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.gson.JsonElement; | import com.google.gson.JsonElement; | ||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import com.google.gson.reflect.TypeToken; | import com.google.gson.reflect.TypeToken; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.json.GsonHelper; | import me.chanjar.weixin.common.util.json.GsonHelper; | ||||
import me.chanjar.weixin.cp.api.WxCpDepartmentService; | import me.chanjar.weixin.cp.api.WxCpDepartmentService; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpMenuService; | import me.chanjar.weixin.cp.api.WxCpMenuService; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
@@ -1,13 +1,15 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import com.google.gson.GsonBuilder; | |||||
import com.google.gson.JsonElement; | import com.google.gson.JsonElement; | ||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.URIUtil; | import me.chanjar.weixin.common.util.http.URIUtil; | ||||
import me.chanjar.weixin.common.util.json.GsonHelper; | import me.chanjar.weixin.common.util.json.GsonHelper; | ||||
import me.chanjar.weixin.cp.api.WxCpOAuth2Service; | import me.chanjar.weixin.cp.api.WxCpOAuth2Service; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpUserDetail; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -52,9 +54,8 @@ public class WxCpOAuth2ServiceImpl implements WxCpOAuth2Service { | |||||
@Override | @Override | ||||
public String[] getUserInfo(Integer agentId, String code) throws WxErrorException { | public String[] getUserInfo(Integer agentId, String code) throws WxErrorException { | ||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?" | |||||
+ "code=" + code | |||||
+ "&agentid=" + agentId; | |||||
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); | String responseText = this.mainService.get(url, null); | ||||
JsonElement je = new JsonParser().parse(responseText); | JsonElement je = new JsonParser().parse(responseText); | ||||
JsonObject jo = je.getAsJsonObject(); | JsonObject jo = je.getAsJsonObject(); | ||||
@@ -63,4 +64,12 @@ public class WxCpOAuth2ServiceImpl implements WxCpOAuth2Service { | |||||
GsonHelper.getString(jo, "OpenId")}; | GsonHelper.getString(jo, "OpenId")}; | ||||
} | } | ||||
@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()); | |||||
return new GsonBuilder().create().fromJson(responseText, WxCpUserDetail.class); | |||||
} | |||||
} | } |
@@ -5,13 +5,12 @@ import com.google.gson.JsonElement; | |||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | import me.chanjar.weixin.common.bean.WxJsapiSignature; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.session.StandardSessionManager; | import me.chanjar.weixin.common.session.StandardSessionManager; | ||||
import me.chanjar.weixin.common.session.WxSession; | import me.chanjar.weixin.common.session.WxSession; | ||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.common.util.DataUtils; | |||||
import me.chanjar.weixin.common.util.RandomUtils; | import me.chanjar.weixin.common.util.RandomUtils; | ||||
import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
@@ -21,14 +20,11 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||||
import me.chanjar.weixin.cp.api.*; | import me.chanjar.weixin.cp.api.*; | ||||
import me.chanjar.weixin.cp.bean.*; | import me.chanjar.weixin.cp.bean.*; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | |||||
import java.util.List; | |||||
public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, RequestHttp<H, P> { | public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, RequestHttp<H, P> { | ||||
protected final Logger log = LoggerFactory.getLogger(this.getClass()); | protected final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
@@ -39,6 +35,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
private WxCpMenuService menuService = new WxCpMenuServiceImpl(this); | private WxCpMenuService menuService = new WxCpMenuServiceImpl(this); | ||||
private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); | private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); | ||||
private WxCpTagService tagService = new WxCpTagServiceImpl(this); | private WxCpTagService tagService = new WxCpTagServiceImpl(this); | ||||
private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); | |||||
/** | /** | ||||
* 全局的是否正在刷新access token的锁 | * 全局的是否正在刷新access token的锁 | ||||
@@ -200,6 +197,8 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
} | } | ||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | ||||
E dataForLog = DataUtils.handleDataWithSecret(data); | |||||
if (uri.contains("access_token=")) { | if (uri.contains("access_token=")) { | ||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | ||||
} | } | ||||
@@ -209,7 +208,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
try { | try { | ||||
T result = executor.execute(uriWithAccessToken, data); | T result = executor.execute(uriWithAccessToken, data); | ||||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); | |||||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||||
return result; | return result; | ||||
} catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
WxError error = e.getError(); | WxError error = e.getError(); | ||||
@@ -226,12 +225,12 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
} | } | ||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); | |||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | |||||
throw new WxErrorException(error, e); | throw new WxErrorException(error, e); | ||||
} | } | ||||
return null; | return null; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); | |||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | |||||
throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
} | } | ||||
} | } | ||||
@@ -368,4 +367,13 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
public void setTagService(WxCpTagService tagService) { | public void setTagService(WxCpTagService tagService) { | ||||
this.tagService = tagService; | this.tagService = tagService; | ||||
} | } | ||||
@Override | |||||
public WxCpAgentService getAgentService() { | |||||
return agentService; | |||||
} | |||||
public void setAgentService(WxCpAgentService agentService) { | |||||
this.agentService = agentService; | |||||
} | |||||
} | } |
@@ -1,9 +1,10 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import me.chanjar.weixin.common.WxType; | |||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
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.HttpType; | ||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | ||||
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | ||||
@@ -58,7 +59,7 @@ public class WxCpServiceApacheHttpClientImpl extends WxCpServiceAbstractImpl<Clo | |||||
} finally { | } finally { | ||||
httpGet.releaseConnection(); | httpGet.releaseConnection(); | ||||
} | } | ||||
WxError error = WxError.fromJson(resultContent); | |||||
WxError error = WxError.fromJson(resultContent, WxType.CP); | |||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
} | } | ||||
@@ -1,9 +1,10 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import jodd.http.*; | import jodd.http.*; | ||||
import me.chanjar.weixin.common.WxType; | |||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
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.HttpType; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
@@ -44,7 +45,7 @@ public class WxCpServiceJoddHttpImpl extends WxCpServiceAbstractImpl<HttpConnect | |||||
HttpResponse response = request.send(); | HttpResponse response = request.send(); | ||||
String resultContent = response.bodyText(); | String resultContent = response.bodyText(); | ||||
WxError error = WxError.fromJson(resultContent); | |||||
WxError error = WxError.fromJson(resultContent, WxType.CP); | |||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
} | } | ||||
@@ -1,8 +1,9 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import me.chanjar.weixin.common.WxType; | |||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
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.HttpType; | ||||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; | import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
@@ -51,7 +52,7 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, | |||||
this.log.error(e.getMessage(), e); | this.log.error(e.getMessage(), e); | ||||
} | } | ||||
WxError error = WxError.fromJson(resultContent); | |||||
WxError error = WxError.fromJson(resultContent, WxType.CP); | |||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
} | } | ||||
@@ -2,11 +2,12 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.gson.*; | import com.google.gson.*; | ||||
import com.google.gson.reflect.TypeToken; | import com.google.gson.reflect.TypeToken; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.api.WxCpTagService; | import me.chanjar.weixin.cp.api.WxCpTagService; | ||||
import me.chanjar.weixin.cp.bean.WxCpTag; | import me.chanjar.weixin.cp.bean.WxCpTag; | ||||
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; | 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.bean.WxCpUser; | ||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
@@ -82,6 +83,22 @@ public class WxCpTagServiceImpl implements WxCpTagService { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers"; | String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers"; | ||||
JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
jsonObject.addProperty("tagid", tagId); | jsonObject.addProperty("tagid", tagId); | ||||
this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject); | |||||
return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); | |||||
} | |||||
@Override | |||||
public WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers"; | |||||
JsonObject jsonObject = new JsonObject(); | |||||
jsonObject.addProperty("tagid", tagId); | |||||
this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject); | |||||
return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); | |||||
} | |||||
private void addUserIdsAndPartyIdsToJson(List<String> userIds, List<String> partyIds, JsonObject jsonObject) { | |||||
if (userIds != null) { | if (userIds != null) { | ||||
JsonArray jsonArray = new JsonArray(); | JsonArray jsonArray = new JsonArray(); | ||||
for (String userId : userIds) { | for (String userId : userIds) { | ||||
@@ -89,6 +106,7 @@ public class WxCpTagServiceImpl implements WxCpTagService { | |||||
} | } | ||||
jsonObject.add("userlist", jsonArray); | jsonObject.add("userlist", jsonArray); | ||||
} | } | ||||
if (partyIds != null) { | if (partyIds != null) { | ||||
JsonArray jsonArray = new JsonArray(); | JsonArray jsonArray = new JsonArray(); | ||||
for (String userId : partyIds) { | for (String userId : partyIds) { | ||||
@@ -96,21 +114,19 @@ public class WxCpTagServiceImpl implements WxCpTagService { | |||||
} | } | ||||
jsonObject.add("partylist", jsonArray); | jsonObject.add("partylist", jsonArray); | ||||
} | } | ||||
return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); | |||||
} | } | ||||
@Override | @Override | ||||
public WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List<String> userIds) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers"; | |||||
JsonObject jsonObject = new JsonObject(); | |||||
jsonObject.addProperty("tagid", tagId); | |||||
JsonArray jsonArray = new JsonArray(); | |||||
for (String userId : userIds) { | |||||
jsonArray.add(new JsonPrimitive(userId)); | |||||
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 { | |||||
throw new IllegalArgumentException("缺少tagId参数"); | |||||
} | } | ||||
jsonObject.add("userlist", jsonArray); | |||||
return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); | |||||
String responseContent = this.mainService.get(url, null); | |||||
return WxCpTagGetResult.fromJson(responseContent); | |||||
} | } | ||||
} | } |
@@ -3,12 +3,12 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import com.google.gson.*; | import com.google.gson.*; | ||||
import com.google.gson.reflect.TypeToken; | import com.google.gson.reflect.TypeToken; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.api.WxCpUserService; | 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.WxCpUser; | ||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -116,17 +116,34 @@ public class WxCpUserServiceImpl implements WxCpUserService { | |||||
} | } | ||||
@Override | @Override | ||||
@Deprecated | |||||
public int invite(String userId, String inviteTips) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/invite/send"; | |||||
public WxCpInviteResult invite(List<String> userIds, List<String> partyIds, List<String> tagIds) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/invite"; | |||||
JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
jsonObject.addProperty("userid", userId); | |||||
if (StringUtils.isNotEmpty(inviteTips)) { | |||||
jsonObject.addProperty("invite_tips", inviteTips); | |||||
if (userIds != null) { | |||||
JsonArray jsonArray = new JsonArray(); | |||||
for (String userId : userIds) { | |||||
jsonArray.add(new JsonPrimitive(userId)); | |||||
} | |||||
jsonObject.add("user", jsonArray); | |||||
} | } | ||||
String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||||
return tmpJsonElement.getAsJsonObject().get("type").getAsInt(); | |||||
if (partyIds != null) { | |||||
JsonArray jsonArray = new JsonArray(); | |||||
for (String userId : partyIds) { | |||||
jsonArray.add(new JsonPrimitive(userId)); | |||||
} | |||||
jsonObject.add("party", jsonArray); | |||||
} | |||||
if (tagIds != null) { | |||||
JsonArray jsonArray = new JsonArray(); | |||||
for (String tagId : tagIds) { | |||||
jsonArray.add(new JsonPrimitive(tagId)); | |||||
} | |||||
jsonObject.add("tag", jsonArray); | |||||
} | |||||
return WxCpInviteResult.fromJson(this.mainService.post(url, jsonObject.toString())); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -0,0 +1,47 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
/** | |||||
* <pre> | |||||
* 性别枚举 | |||||
* Created by BinaryWang on 2018/4/22. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
public enum Gender { | |||||
/** | |||||
* 男 | |||||
*/ | |||||
MALE("男", "1"), | |||||
/** | |||||
* 女 | |||||
*/ | |||||
FEMALE("女", "2"); | |||||
private String genderName; | |||||
private String code; | |||||
Gender(String genderName, String code) { | |||||
this.genderName = genderName; | |||||
this.code = code; | |||||
} | |||||
public String getGenderName() { | |||||
return this.genderName; | |||||
} | |||||
public String getCode() { | |||||
return this.code; | |||||
} | |||||
public static Gender fromCode(String code) { | |||||
if ("1".equals(code)) { | |||||
return Gender.MALE; | |||||
} | |||||
if ("2".equals(code)) { | |||||
return Gender.FEMALE; | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,96 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
/** | |||||
* <pre> | |||||
* 企业号应用信息. | |||||
* Created by huansinho on 2018/4/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/huansinho">huansinho</a> | |||||
*/ | |||||
@Data | |||||
public class WxCpAgent implements Serializable { | |||||
@SerializedName("errcode") | |||||
private Integer errcode; | |||||
@SerializedName("errmsg") | |||||
private String errmsg; | |||||
@SerializedName("agentid") | |||||
private Integer agentid; | |||||
@SerializedName("name") | |||||
private String name; | |||||
@SerializedName("square_logo_url") | |||||
private String squareLogoUrl; | |||||
@SerializedName("description") | |||||
private String description; | |||||
@SerializedName("allow_userinfos") | |||||
private Users allowUserinfos; | |||||
@SerializedName("allow_partys") | |||||
private Partys allowPartys; | |||||
@SerializedName("allow_tags") | |||||
private Tags allowTags; | |||||
@SerializedName("close") | |||||
private Integer close; | |||||
@SerializedName("redirect_domain") | |||||
private String redirectDomain; | |||||
@SerializedName("report_location_flag") | |||||
private Integer reportLocationFlag; | |||||
@SerializedName("isreportenter") | |||||
private Integer isreportenter; | |||||
@SerializedName("home_url") | |||||
private String homeUrl; | |||||
public static WxCpAgent fromJson(String json) { | |||||
return WxCpGsonBuilder.create().fromJson(json, WxCpAgent.class); | |||||
} | |||||
public String toJson() { | |||||
return WxCpGsonBuilder.create().toJson(this); | |||||
} | |||||
@Data | |||||
public static class Users implements Serializable { | |||||
@SerializedName("user") | |||||
private List<User> user; | |||||
} | |||||
@Data | |||||
public class User implements Serializable { | |||||
@SerializedName("userid") | |||||
private String userid; | |||||
} | |||||
@Data | |||||
public class Partys { | |||||
@SerializedName("partyid") | |||||
private List<Integer> partyids = null; | |||||
} | |||||
@Data | |||||
public class Tags { | |||||
@SerializedName("tagid") | |||||
private List<Integer> tagids = null; | |||||
} | |||||
} |
@@ -0,0 +1,60 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
import com.google.common.base.Splitter; | |||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.Serializable; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
/** | |||||
* 邀请成员的结果对象类. | |||||
* Created by Binary Wang on 2018-5-13. | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
@Data | |||||
public class WxCpInviteResult implements Serializable { | |||||
private static final long serialVersionUID = 1420065684270213578L; | |||||
@Override | |||||
public String toString() { | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | |||||
public static WxCpInviteResult fromJson(String json) { | |||||
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpInviteResult.class); | |||||
} | |||||
@SerializedName("errcode") | |||||
private Integer errCode; | |||||
@SerializedName("errmsg") | |||||
private String errMsg; | |||||
@SerializedName("invaliduser") | |||||
private String invalidUsers; | |||||
@SerializedName("invalidparty") | |||||
private String[] invalidParties; | |||||
@SerializedName("invalidtag") | |||||
private String[] invalidTags; | |||||
public List<String> getInvalidUserList() { | |||||
return this.content2List(this.invalidUsers); | |||||
} | |||||
private List<String> content2List(String content) { | |||||
if (StringUtils.isBlank(content)) { | |||||
return Collections.emptyList(); | |||||
} | |||||
return Splitter.on("|").splitToList(content); | |||||
} | |||||
} |
@@ -34,6 +34,7 @@ public class WxCpMessage implements Serializable { | |||||
private String hqMusicUrl; | private String hqMusicUrl; | ||||
private String safe; | private String safe; | ||||
private String url; | private String url; | ||||
private String btnTxt; | |||||
private List<NewArticle> articles = new ArrayList<>(); | private List<NewArticle> articles = new ArrayList<>(); | ||||
private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | ||||
@@ -0,0 +1,57 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
/** | |||||
* <pre> | |||||
* 管理企业号应用-测试 | |||||
* Created by huansinho on 2018/4/16. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/huansinho">huansinho</a> | |||||
*/ | |||||
@Data | |||||
@AllArgsConstructor | |||||
@NoArgsConstructor | |||||
public class WxCpTagGetResult implements Serializable { | |||||
@SerializedName("errcode") | |||||
private Integer errcode; | |||||
@SerializedName("errmsg") | |||||
private String errmsg; | |||||
/** | |||||
* 用户列表 | |||||
*/ | |||||
@SerializedName("userlist") | |||||
private List<WxCpUser> userlist; | |||||
/** | |||||
* 部门列表 | |||||
*/ | |||||
@SerializedName("partylist") | |||||
private List<Integer> partylist; | |||||
/** | |||||
* 标签名称 | |||||
*/ | |||||
@SerializedName("tagname") | |||||
private String tagname; | |||||
public static WxCpTagGetResult fromJson(String json) { | |||||
return WxCpGsonBuilder.create().fromJson(json, WxCpTagGetResult.class); | |||||
} | |||||
public String toJson() { | |||||
return WxCpGsonBuilder.create().toJson(this); | |||||
} | |||||
} |
@@ -15,44 +15,6 @@ import java.util.List; | |||||
*/ | */ | ||||
@Data | @Data | ||||
public class WxCpUser implements Serializable { | public class WxCpUser implements Serializable { | ||||
public enum Gender { | |||||
/** | |||||
* 男 | |||||
*/ | |||||
MALE("男", "1"), | |||||
/** | |||||
* 女 | |||||
*/ | |||||
FEMALE("女", "2"); | |||||
private String genderName; | |||||
private String code; | |||||
Gender(String genderName, String code) { | |||||
this.genderName = genderName; | |||||
this.code = code; | |||||
} | |||||
public String getGenderName() { | |||||
return this.genderName; | |||||
} | |||||
public String getCode() { | |||||
return this.code; | |||||
} | |||||
public static Gender fromCode(String code) { | |||||
if ("1".equals(code)) { | |||||
return Gender.MALE; | |||||
} | |||||
if ("2".equals(code)) { | |||||
return Gender.FEMALE; | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
private static final long serialVersionUID = -5696099236344075582L; | private static final long serialVersionUID = -5696099236344075582L; | ||||
private String userId; | private String userId; | ||||
private String name; | private String name; | ||||
@@ -69,6 +31,8 @@ public class WxCpUser implements Serializable { | |||||
private Integer hideMobile; | private Integer hideMobile; | ||||
private String englishName; | private String englishName; | ||||
private String telephone; | private String telephone; | ||||
private String qrCode; | |||||
private Boolean toInvite; | |||||
public void addExtAttr(String name, String value) { | public void addExtAttr(String name, String value) { | ||||
this.extAttrs.add(new Attr(name, value)); | this.extAttrs.add(new Attr(name, value)); | ||||
@@ -0,0 +1,24 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.Data; | |||||
/** | |||||
* <pre> | |||||
* 使用user_ticket获取成员详情接口返回类. | |||||
* Created by BinaryWang on 2018/4/22. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
@Data | |||||
public class WxCpUserDetail { | |||||
@SerializedName("userid") | |||||
private String userId; | |||||
private String name; | |||||
private String mobile; | |||||
private String gender; | |||||
private String email; | |||||
@SerializedName("qrCode") | |||||
private String qrCode; | |||||
} |
@@ -3,6 +3,7 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
@@ -11,6 +12,7 @@ import java.util.List; | |||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | @Data | ||||
@EqualsAndHashCode(callSuper = true) | |||||
public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = -5796178637883178826L; | private static final long serialVersionUID = -5796178637883178826L; | ||||
@@ -16,6 +16,7 @@ public class TextCardBuilder extends BaseBuilder<TextCardBuilder> { | |||||
private String title; | private String title; | ||||
private String description; | private String description; | ||||
private String url; | private String url; | ||||
private String btnTxt; | |||||
public TextCardBuilder() { | public TextCardBuilder() { | ||||
this.msgType = WxConsts.KefuMsgType.TEXTCARD; | this.msgType = WxConsts.KefuMsgType.TEXTCARD; | ||||
@@ -36,12 +37,18 @@ public class TextCardBuilder extends BaseBuilder<TextCardBuilder> { | |||||
return this; | return this; | ||||
} | } | ||||
public TextCardBuilder btnTxt(String btnTxt) { | |||||
this.btnTxt = btnTxt; | |||||
return this; | |||||
} | |||||
@Override | @Override | ||||
public WxCpMessage build() { | public WxCpMessage build() { | ||||
WxCpMessage m = super.build(); | WxCpMessage m = super.build(); | ||||
m.setTitle(this.title); | m.setTitle(this.title); | ||||
m.setDescription(this.description); | m.setDescription(this.description); | ||||
m.setUrl(this.url); | m.setUrl(this.url); | ||||
m.setBtnTxt(this.btnTxt); | |||||
return m; | return m; | ||||
} | } | ||||
} | } |
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.cp.message; | package me.chanjar.weixin.cp.message; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.cp.message; | package me.chanjar.weixin.cp.message; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.message; | package me.chanjar.weixin.cp.message; | ||||
import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.util.json; | |||||
import com.google.gson.Gson; | import com.google.gson.Gson; | ||||
import com.google.gson.GsonBuilder; | import com.google.gson.GsonBuilder; | ||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.util.json.WxErrorAdapter; | import me.chanjar.weixin.common.util.json.WxErrorAdapter; | ||||
import me.chanjar.weixin.cp.bean.WxCpDepart; | import me.chanjar.weixin.cp.bean.WxCpDepart; | ||||
import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
@@ -48,6 +48,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
text.addProperty("title", message.getTitle()); | text.addProperty("title", message.getTitle()); | ||||
text.addProperty("description", message.getDescription()); | text.addProperty("description", message.getDescription()); | ||||
text.addProperty("url", message.getUrl()); | text.addProperty("url", message.getUrl()); | ||||
text.addProperty("btntxt", message.getBtnTxt()); | |||||
messageJson.add("textcard", text); | messageJson.add("textcard", text); | ||||
} | } | ||||
@@ -10,6 +10,7 @@ package me.chanjar.weixin.cp.util.json; | |||||
import com.google.gson.*; | import com.google.gson.*; | ||||
import me.chanjar.weixin.common.util.json.GsonHelper; | import me.chanjar.weixin.common.util.json.GsonHelper; | ||||
import me.chanjar.weixin.cp.bean.Gender; | |||||
import me.chanjar.weixin.cp.bean.WxCpUser; | import me.chanjar.weixin.cp.bean.WxCpUser; | ||||
import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
@@ -39,7 +40,7 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
user.setName(GsonHelper.getString(o, "name")); | user.setName(GsonHelper.getString(o, "name")); | ||||
user.setPosition(GsonHelper.getString(o, "position")); | user.setPosition(GsonHelper.getString(o, "position")); | ||||
user.setMobile(GsonHelper.getString(o, "mobile")); | user.setMobile(GsonHelper.getString(o, "mobile")); | ||||
user.setGender(WxCpUser.Gender.fromCode(GsonHelper.getString(o, "gender"))); | |||||
user.setGender(Gender.fromCode(GsonHelper.getString(o, "gender"))); | |||||
user.setEmail(GsonHelper.getString(o, "email")); | user.setEmail(GsonHelper.getString(o, "email")); | ||||
user.setAvatar(GsonHelper.getString(o, "avatar")); | user.setAvatar(GsonHelper.getString(o, "avatar")); | ||||
user.setStatus(GsonHelper.getInteger(o, "status")); | user.setStatus(GsonHelper.getInteger(o, "status")); | ||||
@@ -48,6 +49,8 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); | user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); | ||||
user.setEnglishName(GsonHelper.getString(o, "english_name")); | user.setEnglishName(GsonHelper.getString(o, "english_name")); | ||||
user.setTelephone(GsonHelper.getString(o, "telephone")); | user.setTelephone(GsonHelper.getString(o, "telephone")); | ||||
user.setQrCode(GsonHelper.getString(o, "qr_code")); | |||||
user.setToInvite(GsonHelper.getBoolean(o, "to_invite")); | |||||
if (GsonHelper.isNotNull(o.get("extattr"))) { | if (GsonHelper.isNotNull(o.get("extattr"))) { | ||||
JsonArray attrJsonElements = o.get("extattr").getAsJsonObject().get("attrs").getAsJsonArray(); | JsonArray attrJsonElements = o.get("extattr").getAsJsonObject().get("attrs").getAsJsonArray(); | ||||
@@ -111,6 +114,13 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
if (user.getTelephone() != null) { | if (user.getTelephone() != null) { | ||||
o.addProperty("telephone", user.getTelephone()); | o.addProperty("telephone", user.getTelephone()); | ||||
} | } | ||||
if (user.getQrCode() != null) { | |||||
o.addProperty("qr_code", user.getQrCode()); | |||||
} | |||||
if (user.getToInvite() != null) { | |||||
o.addProperty("to_invite", user.getToInvite()); | |||||
} | |||||
if (user.getExtAttrs().size() > 0) { | if (user.getExtAttrs().size() > 0) { | ||||
JsonArray attrsJsonArray = new JsonArray(); | JsonArray attrsJsonArray = new JsonArray(); | ||||
for (WxCpUser.Attr attr : user.getExtAttrs()) { | for (WxCpUser.Attr attr : user.getExtAttrs()) { | ||||
@@ -63,7 +63,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlMessage() { | private static XStream configWxCpXmlMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlMessage.class); | xstream.processAnnotations(WxCpXmlMessage.class); | ||||
xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | ||||
@@ -75,7 +74,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlOutImageMessage() { | private static XStream configWxCpXmlOutImageMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutImageMessage.class); | xstream.processAnnotations(WxCpXmlOutImageMessage.class); | ||||
@@ -84,7 +82,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlOutNewsMessage() { | private static XStream configWxCpXmlOutNewsMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | ||||
@@ -94,7 +91,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlOutTextMessage() { | private static XStream configWxCpXmlOutTextMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutTextMessage.class); | xstream.processAnnotations(WxCpXmlOutTextMessage.class); | ||||
@@ -103,7 +99,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlOutVideoMessage() { | private static XStream configWxCpXmlOutVideoMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | ||||
@@ -113,7 +108,6 @@ public class XStreamTransformer { | |||||
private static XStream configWxCpXmlOutVoiceMessage() { | private static XStream configWxCpXmlOutVoiceMessage() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | ||||
@@ -1,20 +1,24 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import com.google.inject.Binder; | import com.google.inject.Binder; | ||||
import com.google.inject.Module; | import com.google.inject.Module; | ||||
import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||||
import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; | import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; | ||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
public class ApiTestModule implements Module { | public class ApiTestModule implements Module { | ||||
private final Logger log = LoggerFactory.getLogger(this.getClass()); | |||||
private static final String TEST_CONFIG_XML = "test-config.xml"; | |||||
public static <T> T fromXml(Class<T> clazz, InputStream is) { | |||||
private static <T> T fromXml(Class<T> clazz, InputStream is) { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.alias("xml", clazz); | xstream.alias("xml", clazz); | ||||
xstream.processAnnotations(clazz); | xstream.processAnnotations(clazz); | ||||
@@ -23,17 +27,19 @@ public class ApiTestModule implements Module { | |||||
@Override | @Override | ||||
public void configure(Binder binder) { | public void configure(Binder binder) { | ||||
try (InputStream is1 = ClassLoader | |||||
.getSystemResourceAsStream("test-config.xml")) { | |||||
WxXmlCpInMemoryConfigStorage config = fromXml( | |||||
WxXmlCpInMemoryConfigStorage.class, is1); | |||||
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { | |||||
if (inputStream == null) { | |||||
throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); | |||||
} | |||||
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream); | |||||
WxCpService wxService = new WxCpServiceImpl(); | WxCpService wxService = new WxCpServiceImpl(); | ||||
wxService.setWxCpConfigStorage(config); | wxService.setWxCpConfigStorage(config); | ||||
binder.bind(WxCpService.class).toInstance(wxService); | binder.bind(WxCpService.class).toInstance(wxService); | ||||
binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config); | binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
e.printStackTrace(); | |||||
this.log.error(e.getMessage(), e); | |||||
} | } | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -1,7 +1,7 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | ||||
import org.testng.annotations.DataProvider; | import org.testng.annotations.DataProvider; | ||||
@@ -2,7 +2,7 @@ package me.chanjar.weixin.cp.api; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
@@ -0,0 +1,52 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.inject.Inject; | |||||
import me.chanjar.weixin.common.api.WxConsts; | |||||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||||
import me.chanjar.weixin.common.bean.menu.WxMenuButton; | |||||
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 me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; | |||||
import org.mockito.Mock; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.DataProvider; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import static org.testng.Assert.assertEquals; | |||||
import static org.testng.Assert.assertNotNull; | |||||
import static org.mockito.Mockito.*; | |||||
/** | |||||
* <pre> | |||||
* 管理企业号应用-测试 | |||||
* Created by huansinho on 2018/4/13. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/huansinho">huansinho</a> | |||||
*/ | |||||
public class WxCpAgentServiceImplTest { | |||||
protected WxCpService wxService = mock(WxCpService.class); | |||||
@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.getAgentService()).thenReturn(new WxCpAgentServiceImpl(wxService)); | |||||
WxCpAgentService wxAgentService = this.wxService.getAgentService(); | |||||
WxCpAgent wxCpAgent = wxAgentService.get(9); | |||||
Assert.assertEquals(9, wxCpAgent.getAgentid().intValue()); | |||||
Assert.assertEquals(new Integer[]{42762742}, wxCpAgent.getAllowPartys().getPartyids().toArray()); | |||||
Assert.assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, wxCpAgent.getAllowTags().getTagids().toArray()); | |||||
} | |||||
} |
@@ -56,7 +56,7 @@ public class WxCpDepartmentServiceImplTest { | |||||
} | } | ||||
} | } | ||||
@Test(dependsOnMethods = {"testListAll", "testCreate"}) | |||||
@Test(dependsOnMethods = {"testList", "testCreate"}) | |||||
public void testUpdate() throws Exception { | public void testUpdate() throws Exception { | ||||
System.out.println("=================更新部门"); | System.out.println("=================更新部门"); | ||||
this.depart.setName("子部门改名" + System.currentTimeMillis()); | this.depart.setName("子部门改名" + System.currentTimeMillis()); | ||||
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.ApiTestModule; | import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
import me.chanjar.weixin.cp.api.TestConstants; | import me.chanjar.weixin.cp.api.TestConstants; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
@@ -0,0 +1,33 @@ | |||||
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.WxCpUserDetail; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
/** | |||||
* <pre> | |||||
* Created by BinaryWang on 2018/4/22. | |||||
* </pre> | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | |||||
@Guice(modules = ApiTestModule.class) | |||||
public class WxCpOAuth2ServiceImplTest { | |||||
@Inject | |||||
private WxCpService wxService; | |||||
@Test | |||||
public void testGetUserDetail() throws WxErrorException { | |||||
WxCpUserDetail userDetail = this.wxService.getOauth2Service().getUserDetail("b"); | |||||
System.out.println(userDetail); | |||||
} | |||||
@Test | |||||
public void testGetUserInfo() throws WxErrorException { | |||||
this.wxService.getOauth2Service().getUserInfo("abc"); | |||||
} | |||||
} |
@@ -2,16 +2,23 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import com.google.common.base.Splitter; | import com.google.common.base.Splitter; | ||||
import com.google.inject.Inject; | 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.ApiTestModule; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.api.WxCpTagService; | |||||
import me.chanjar.weixin.cp.bean.WxCpTag; | import me.chanjar.weixin.cp.bean.WxCpTag; | ||||
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; | 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.bean.WxCpUser; | ||||
import org.testng.annotations.*; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import java.util.List; | import java.util.List; | ||||
import static org.testng.Assert.*; | |||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.when; | |||||
import static org.testng.Assert.assertEquals; | |||||
import static org.testng.Assert.assertNotEquals; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -63,7 +70,7 @@ public class WxCpTagServiceImplTest { | |||||
@Test(dependsOnMethods = {"testListUsersByTagId", "testAddUsers2Tag", "testListAll", "testUpdate", "testCreate"}) | @Test(dependsOnMethods = {"testListUsersByTagId", "testAddUsers2Tag", "testListAll", "testUpdate", "testCreate"}) | ||||
public void testRemoveUsersFromTag() throws Exception { | public void testRemoveUsersFromTag() throws Exception { | ||||
List<String> userIds = Splitter.on("|").splitToList(this.configStorage.getUserId()); | List<String> userIds = Splitter.on("|").splitToList(this.configStorage.getUserId()); | ||||
WxCpTagAddOrRemoveUsersResult result = this.wxService.getTagService().removeUsersFromTag(this.tagId, userIds); | |||||
WxCpTagAddOrRemoveUsersResult result = this.wxService.getTagService().removeUsersFromTag(this.tagId, userIds, null); | |||||
assertEquals(result.getErrCode(), Integer.valueOf(0)); | assertEquals(result.getErrCode(), Integer.valueOf(0)); | ||||
} | } | ||||
@@ -72,4 +79,24 @@ public class WxCpTagServiceImplTest { | |||||
this.wxService.getTagService().delete(this.tagId); | this.wxService.getTagService().delete(this.tagId); | ||||
} | } | ||||
@Test | |||||
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.getTagService()).thenReturn(new WxCpTagServiceImpl(wxService)); | |||||
WxCpTagService wxCpTagService = wxService.getTagService(); | |||||
WxCpTagGetResult wxCpTagGetResult = wxCpTagService.get(String.valueOf(150)); | |||||
assertEquals(0, wxCpTagGetResult.getErrcode().intValue()); | |||||
assertEquals(2, wxCpTagGetResult.getUserlist().size()); | |||||
assertEquals(3, wxCpTagGetResult.getPartylist().size()); | |||||
assertEquals("测试标签-001", wxCpTagGetResult.getTagname()); | |||||
} | |||||
} | } |
@@ -1,8 +1,11 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import com.google.common.collect.Lists; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.cp.api.ApiTestModule; | import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.Gender; | |||||
import me.chanjar.weixin.cp.bean.WxCpInviteResult; | |||||
import me.chanjar.weixin.cp.bean.WxCpUser; | import me.chanjar.weixin.cp.bean.WxCpUser; | ||||
import org.apache.commons.lang3.builder.ToStringBuilder; | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||
import org.apache.commons.lang3.builder.ToStringStyle; | import org.apache.commons.lang3.builder.ToStringStyle; | ||||
@@ -40,7 +43,7 @@ public class WxCpUserServiceImplTest { | |||||
user.setName("Some Woman"); | user.setName("Some Woman"); | ||||
user.setDepartIds(new Integer[]{2}); | user.setDepartIds(new Integer[]{2}); | ||||
user.setEmail("none@none.com"); | user.setEmail("none@none.com"); | ||||
user.setGender(WxCpUser.Gender.FEMALE); | |||||
user.setGender(Gender.FEMALE); | |||||
user.setMobile("13560084979"); | user.setMobile("13560084979"); | ||||
user.setPosition("woman"); | user.setPosition("woman"); | ||||
user.setTelephone("3300393"); | user.setTelephone("3300393"); | ||||
@@ -87,9 +90,9 @@ public class WxCpUserServiceImplTest { | |||||
} | } | ||||
@Test | @Test | ||||
@Deprecated | |||||
public void testInvite() throws Exception { | public void testInvite() throws Exception { | ||||
int result = this.wxCpService.getUserService().invite(userId, ""); | |||||
WxCpInviteResult result = this.wxCpService.getUserService().invite( | |||||
Lists.newArrayList(userId), null,null); | |||||
System.out.println(result); | System.out.println(result); | ||||
} | } | ||||
@@ -0,0 +1,25 @@ | |||||
package me.chanjar.weixin.cp.bean; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.Test; | |||||
/** | |||||
* Created by huansinho on 2018/4/13. | |||||
*/ | |||||
@Test | |||||
public class WxCpAgentTest { | |||||
public void testDeserialize() { | |||||
String json = "{\"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\": \"\"}"; | |||||
WxCpAgent wxCpAgent = WxCpAgent.fromJson(json); | |||||
Assert.assertEquals(9, wxCpAgent.getAgentid().intValue()); | |||||
Assert.assertEquals(new Integer[]{42762742}, wxCpAgent.getAllowPartys().getPartyids().toArray()); | |||||
Assert.assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, wxCpAgent.getAllowTags().getTagids().toArray()); | |||||
} | |||||
} |
@@ -2,39 +2,47 @@ package me.chanjar.weixin.cp.bean; | |||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
import me.chanjar.weixin.cp.bean.article.NewArticle; | import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
import org.testng.annotations.*; | |||||
import org.testng.annotations.Test; | |||||
import static org.testng.Assert.*; | |||||
import static org.assertj.core.api.Assertions.assertThat; | |||||
import static org.testng.Assert.assertEquals; | |||||
@Test | @Test | ||||
public class WxCpMessageTest { | public class WxCpMessageTest { | ||||
public void testTextBuild() { | public void testTextBuild() { | ||||
WxCpMessage reply = WxCpMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); | WxCpMessage reply = WxCpMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"},\"safe\":\"0\"}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"},\"safe\":\"0\"}"); | |||||
} | } | ||||
public void testTextCardBuild() { | public void testTextCardBuild() { | ||||
WxCpMessage reply = WxCpMessage.TEXTCARD().toUser("OPENID") | WxCpMessage reply = WxCpMessage.TEXTCARD().toUser("OPENID") | ||||
.title("领奖通知") | .title("领奖通知") | ||||
.description( "<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>") | |||||
.url("http://www.qq.com").build(); | |||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\",\"description\":\"<div class=\\\"gray\\\">2016年9月26日</div> <div class=\\\"normal\\\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\\\"highlight\\\">请于2016年10月10日前联系行政同事领取</div>\",\"url\":\"http://www.qq.com\"},\"safe\":\"0\"}"); | |||||
.description("<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>") | |||||
.url("http://www.qq.com") | |||||
.btnTxt("更多") | |||||
.build(); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\",\"description\":\"<div class=\\\"gray\\\">2016年9月26日</div> <div class=\\\"normal\\\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\\\"highlight\\\">请于2016年10月10日前联系行政同事领取</div>\",\"url\":\"http://www.qq.com\",\"btntxt\":\"更多\"},\"safe\":\"0\"}"); | |||||
} | } | ||||
public void testImageBuild() { | public void testImageBuild() { | ||||
WxCpMessage reply = WxCpMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); | WxCpMessage reply = WxCpMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); | |||||
} | } | ||||
public void testVoiceBuild() { | public void testVoiceBuild() { | ||||
WxCpMessage reply = WxCpMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); | WxCpMessage reply = WxCpMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); | |||||
} | } | ||||
public void testVideoBuild() { | public void testVideoBuild() { | ||||
WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); | WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"safe\":\"0\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"safe\":\"0\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); | |||||
} | } | ||||
public void testNewsBuild() { | public void testNewsBuild() { | ||||
@@ -52,7 +60,8 @@ public class WxCpMessageTest { | |||||
WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); | WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"safe\":\"0\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"safe\":\"0\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); | |||||
} | } | ||||
public void testMpnewsBuild_with_articles() { | public void testMpnewsBuild_with_articles() { | ||||
@@ -78,14 +87,15 @@ public class WxCpMessageTest { | |||||
WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); | WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); | ||||
assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"},{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"},{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); | |||||
} | } | ||||
public void testMpnewsBuild_with_media_id() { | public void testMpnewsBuild_with_media_id() { | ||||
WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); | WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); | ||||
assertEquals(reply.toJson(), | |||||
"{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"media_id\":\"mmm\"}}"); | |||||
assertThat(reply.toJson()) | |||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"media_id\":\"mmm\"}}"); | |||||
} | } | ||||
} | } |
@@ -1,6 +1,6 @@ | |||||
package me.chanjar.weixin.cp.demo; | package me.chanjar.weixin.cp.demo; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import javax.servlet.http.HttpServlet; | import javax.servlet.http.HttpServlet; | ||||
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>3.0.0</version> | |||||
<version>3.1.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-miniapp</artifactId> | <artifactId>weixin-java-miniapp</artifactId> | ||||
<name>Weixin Java Tools - MiniApp</name> | <name>Weixin Java Tools - MiniApp</name> | ||||
@@ -0,0 +1,145 @@ | |||||
package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaSummaryTrend; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitPage; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitTrend; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
/** | |||||
* 小程序数据分析相关接口 | |||||
* 文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/analysis.html | |||||
* | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-28 | |||||
*/ | |||||
public interface WxMaAnalysisService { | |||||
String GET_DAILY_SUMMARY_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend"; | |||||
String GET_DAILY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend"; | |||||
String GET_WEEKLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend"; | |||||
String GET_MONTHLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend"; | |||||
String GET_VISIT_DISTRIBUTION_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution"; | |||||
String GET_DAILY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo"; | |||||
String GET_WEEKLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo"; | |||||
String GET_MONTHLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo"; | |||||
String GET_VISIT_PAGE_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage"; | |||||
String GET_USER_PORTRAIT_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait"; | |||||
/** | |||||
* 查询概况趋势 | |||||
* 温馨提示:小程序接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 | |||||
* | |||||
* @param beginDate 开始日期 | |||||
* @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 | |||||
* @return 概况趋势 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
List<WxMaSummaryTrend> getDailySummaryTrend(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取日访问趋势 | |||||
* 温馨提示:小程序接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 | |||||
* | |||||
* @param beginDate 开始日期 | |||||
* @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 | |||||
* @return 日访问趋势 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
List<WxMaVisitTrend> getDailyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取周访问趋势 | |||||
* 限定查询一个自然周的数据,时间必须按照自然周的方式输入: 如:20170306(周一), 20170312(周日) | |||||
* | |||||
* @param beginDate 开始日期,为周一日期 | |||||
* @param endDate 结束日期,为周日日期,限定查询一周数据 | |||||
* @return 周访问趋势(每项数据都是一个自然周汇总) | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
List<WxMaVisitTrend> getWeeklyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取月访问趋势 | |||||
* 限定查询一个自然月的数据,时间必须按照自然月的方式输入: 如:20170201(月初), 20170228(月末) | |||||
* | |||||
* @param beginDate 开始日期,为自然月第一天 | |||||
* @param endDate 结束日期,为自然月最后一天,限定查询一个月数据 | |||||
* @return 月访问趋势(每项数据都是一个自然月汇总) | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
List<WxMaVisitTrend> getMonthlyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取访问分布 | |||||
* (此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样) | |||||
* | |||||
* @param beginDate 开始日期,为周一日期 | |||||
* @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 | |||||
* @return 访问分布 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaVisitDistribution getVisitDistribution(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 日留存 | |||||
* (此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样) | |||||
* | |||||
* @param beginDate 开始日期,为周一日期 | |||||
* @param endDate 结束日期,限定查询 1 天数据,endDate 允许设置的最大值为昨日 | |||||
* @return 日留存 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaRetainInfo getDailyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 周留存 | |||||
* 限定查询一个自然周的数据,时间必须按照自然周的方式输入: 如:20170306(周一), 20170312(周日) | |||||
* | |||||
* @param beginDate 开始日期,为周一日期 | |||||
* @param endDate 结束日期,为周日日期,限定查询一周数据 | |||||
* @return 周留存 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaRetainInfo getWeeklyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 月留存 | |||||
* 限定查询一个自然月的数据,时间必须按照自然月的方式输入: 如:20170201(月初), 20170228(月末) | |||||
* | |||||
* @param beginDate 开始日期,为自然月第一天 | |||||
* @param endDate 结束日期,为自然月最后一天,限定查询一个月数据 | |||||
* @return 月留存 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaRetainInfo getMonthlyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取访问页面数据 | |||||
* 温馨提示:此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 | |||||
* | |||||
* @param beginDate 开始日期 | |||||
* @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 | |||||
* @return 访问页面数据 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
List<WxMaVisitPage> getVisitPage(Date beginDate, Date endDate) throws WxErrorException; | |||||
/** | |||||
* 获取小程序新增或活跃用户的画像分布数据 | |||||
* 时间范围支持昨天、最近7天、最近30天。 | |||||
* 其中,新增用户数为时间范围内首次访问小程序的去重用户数, | |||||
* 活跃用户数为时间范围内访问过小程序的去重用户数。 | |||||
* 画像属性包括用户年龄、性别、省份、城市、终端类型、机型。 | |||||
* | |||||
* @param beginDate 开始日期 | |||||
* @param endDate 结束日期,开始日期与结束日期相差的天数限定为0/6/29,分别表示查询最近1/7/30天数据,end_date允许设置的最大值为昨日 | |||||
* @return 小程序新增或活跃用户的画像分布数据 | |||||
* @throws WxErrorException 获取失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaUserPortrait getUserPortrait(Date beginDate, Date endDate) throws WxErrorException; | |||||
} |
@@ -0,0 +1,140 @@ | |||||
package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCategory; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.List; | |||||
/** | |||||
* 小程序代码管理相关 API(大部分只能是第三方平台调用) | |||||
* 文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=&lang=zh_CN | |||||
* | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-26 19:43 | |||||
*/ | |||||
public interface WxMaCodeService { | |||||
/** | |||||
* 为授权的小程序帐号上传小程序代码 | |||||
*/ | |||||
String COMMIT_URL = "https://api.weixin.qq.com/wxa/commit"; | |||||
String GET_QRCODE_URL = "https://api.weixin.qq.com/wxa/get_qrcode"; | |||||
String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxa/get_category"; | |||||
String GET_PAGE_URL = "https://api.weixin.qq.com/wxa/get_page"; | |||||
String SUBMIT_AUDIT_URL = "https://api.weixin.qq.com/wxa/submit_audit"; | |||||
String GET_AUDIT_STATUS_URL = "https://api.weixin.qq.com/wxa/get_auditstatus"; | |||||
String GET_LATEST_AUDIT_STATUS_URL = "https://api.weixin.qq.com/wxa/get_latest_auditstatus"; | |||||
String RELEASE_URL = "https://api.weixin.qq.com/wxa/release"; | |||||
String CHANGE_VISIT_STATUS_URL = "https://api.weixin.qq.com/wxa/change_visitstatus"; | |||||
String REVERT_CODE_RELEASE_URL = "https://api.weixin.qq.com/wxa/revertcoderelease"; | |||||
String GET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion"; | |||||
String SET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion"; | |||||
String UNDO_CODE_AUDIT_URL = "https://api.weixin.qq.com/wxa/undocodeaudit"; | |||||
/** | |||||
* 为授权的小程序帐号上传小程序代码(仅仅支持第三方开放平台) | |||||
* | |||||
* @param commitRequest 参数 | |||||
* @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档 | |||||
*/ | |||||
void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException; | |||||
/** | |||||
* 获取体验小程序的体验二维码 | |||||
* | |||||
* @return 二维码 bytes | |||||
* @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档 | |||||
*/ | |||||
byte[] getQrCode() throws WxErrorException; | |||||
/** | |||||
* 获取授权小程序帐号的可选类目 | |||||
* | |||||
* @return List<WxMaCategory> | |||||
* @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
List<WxMaCategory> getCategory() throws WxErrorException; | |||||
/** | |||||
* 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) | |||||
* | |||||
* @return page_list 页面配置列表 | |||||
* @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
List<String> getPage() throws WxErrorException; | |||||
/** | |||||
* 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) | |||||
* | |||||
* @param auditRequest 提交审核参数 | |||||
* @return 审核编号 | |||||
* @throws WxErrorException 提交失败时返回,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
long submitAudit(WxMaCodeSubmitAuditRequest auditRequest) throws WxErrorException; | |||||
/** | |||||
* 查询某个指定版本的审核状态(仅供第三方代小程序调用) | |||||
* | |||||
* @param auditId 提交审核时获得的审核id | |||||
* @return 审核状态 | |||||
* @throws WxErrorException 查询失败时返回,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
WxMaCodeAuditStatus getAuditStatus(long auditId) throws WxErrorException; | |||||
/** | |||||
* 查询最新一次提交的审核状态(仅供第三方代小程序调用) | |||||
* | |||||
* @return 审核状态 | |||||
* @throws WxErrorException 查询失败时返回,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
WxMaCodeAuditStatus getLatestAuditStatus() throws WxErrorException; | |||||
/** | |||||
* 发布已通过审核的小程序(仅供第三方代小程序调用) | |||||
* | |||||
* @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
void release() throws WxErrorException; | |||||
/** | |||||
* 修改小程序线上代码的可见状态(仅供第三方代小程序调用) | |||||
* | |||||
* @param action 设置可访问状态,发布后默认可访问,close为不可见,open为可见 | |||||
* @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
void changeVisitStatus(String action) throws WxErrorException; | |||||
/** | |||||
* 小程序版本回退(仅供第三方代小程序调用) | |||||
* | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
void revertCodeRelease() throws WxErrorException; | |||||
/** | |||||
* 查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用) | |||||
* | |||||
* @return 小程序版本分布信息 | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
WxMaCodeVersionDistribution getSupportVersion() throws WxErrorException; | |||||
/** | |||||
* 设置最低基础库版本(仅供第三方代小程序调用) | |||||
* | |||||
* @param version 版本 | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
void setSupportVersion(String version) throws WxErrorException; | |||||
/** | |||||
* 小程序审核撤回 | |||||
* 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次 | |||||
* | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 | |||||
*/ | |||||
void undoCodeAudit() throws WxErrorException; | |||||
} |
@@ -1,7 +1,7 @@ | |||||
package cn.binarywang.wx.miniapp.api; | package cn.binarywang.wx.miniapp.api; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
@@ -2,7 +2,7 @@ package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -1,7 +1,7 @@ | |||||
package cn.binarywang.wx.miniapp.api; | package cn.binarywang.wx.miniapp.api; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.io.File; | import java.io.File; | ||||
@@ -9,7 +9,7 @@ import java.io.File; | |||||
* <pre> | * <pre> | ||||
* 二维码相关操作接口. | * 二维码相关操作接口. | ||||
* | * | ||||
* 接口A(createWxCode)加上接口C(createQrcode),总共生成的码数量限制为100,000,请谨慎调用。 | |||||
* 接口A(createWxaCode)加上接口C(createQrcode),总共生成的码数量限制为100,000,请谨慎调用。 | |||||
* | * | ||||
* 文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html | * 文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html | ||||
* </pre> | * </pre> | ||||
@@ -40,16 +40,17 @@ public interface WxMaQrcodeService { | |||||
/** | /** | ||||
* 接口A: 获取小程序码. | * 接口A: 获取小程序码. | ||||
* | * | ||||
* @param path 不能为空,最大长度 128 字节 | |||||
* @param width 默认430 二维码的宽度 | |||||
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | |||||
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | |||||
* @param path 不能为空,最大长度 128 字节 | |||||
* @param width 默认430 二维码的宽度 | |||||
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | |||||
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | |||||
* @param is_hyaline 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码 | |||||
*/ | */ | ||||
File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException; | |||||
File createWxaCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean is_hyaline) throws WxErrorException; | |||||
File createWxCode(String path, int width) throws WxErrorException; | |||||
File createWxaCode(String path, int width) throws WxErrorException; | |||||
File createWxCode(String path) throws WxErrorException; | |||||
File createWxaCode(String path) throws WxErrorException; | |||||
/** | /** | ||||
* 接口B: 获取小程序码(永久有效、数量暂无限制). | * 接口B: 获取小程序码(永久有效、数量暂无限制). | ||||
@@ -59,14 +60,16 @@ public interface WxMaQrcodeService { | |||||
* 使用如下代码可以获取到二维码中的 scene 字段的值。 | * 使用如下代码可以获取到二维码中的 scene 字段的值。 | ||||
* 调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟,开发工具模拟时的 scene 的参数值需要进行 urlencode | * 调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟,开发工具模拟时的 scene 的参数值需要进行 urlencode | ||||
* </pre> | * </pre> | ||||
* | |||||
* @param scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式) | * @param scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式) | ||||
* @param page 必须是已经发布的小程序页面,例如 "pages/index/index" ,如果不填写这个字段,默认跳主页面 | * @param page 必须是已经发布的小程序页面,例如 "pages/index/index" ,如果不填写这个字段,默认跳主页面 | ||||
* @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | * @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | ||||
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | * @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | ||||
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | * @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | ||||
* @param isHyaline 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码 | |||||
*/ | */ | ||||
File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException; | |||||
File createWxaCodeUnlimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException; | |||||
File createWxCodeLimit(String scene, String page) throws WxErrorException; | |||||
File createWxaCodeUnlimit(String scene, String page) throws WxErrorException; | |||||
} | } |
@@ -2,7 +2,7 @@ package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | ||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
@@ -135,6 +135,27 @@ public interface WxMaService { | |||||
*/ | */ | ||||
WxMaTemplateService getTemplateService(); | WxMaTemplateService getTemplateService(); | ||||
/** | |||||
* 数据分析相关查询服务 | |||||
* | |||||
* @return WxMaAnalysisService | |||||
*/ | |||||
WxMaAnalysisService getAnalysisService(); | |||||
/** | |||||
* 返回代码操作相关的 API | |||||
* | |||||
* @return WxMaCodeService | |||||
*/ | |||||
WxMaCodeService getCodeService(); | |||||
/** | |||||
* 小程序修改服务器地址、成员管理 API | |||||
* | |||||
* @return WxMaSettingService | |||||
*/ | |||||
WxMaSettingService getSettingService(); | |||||
/** | /** | ||||
* 初始化http请求对象. | * 初始化http请求对象. | ||||
*/ | */ | ||||
@@ -0,0 +1,65 @@ | |||||
package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | |||||
* 小程序修改服务器地址、成员管理 API(大部分只能是第三方平台调用) | |||||
* | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-27 15:46 | |||||
*/ | |||||
public interface WxMaSettingService { | |||||
/** | |||||
* 修改服务器地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489138143_WPbOO&token=&lang=zh_CN | |||||
* access_token 为 authorizer_access_token | |||||
*/ | |||||
String MODIFY_DOMAIN_URL = "https://api.weixin.qq.com/wxa/modify_domain"; | |||||
String SET_WEB_VIEW_DOMAIN_URL = "https://api.weixin.qq.com/wxa/setwebviewdomain"; | |||||
/** | |||||
* 小程序成员管理:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140588_nVUgx&token=&lang=zh_CN | |||||
* access_token 为 authorizer_access_token | |||||
*/ | |||||
String BIND_TESTER_URL = "https://api.weixin.qq.com/wxa/bind_tester"; | |||||
String UNBIND_TESTER_URL = "https://api.weixin.qq.com/wxa/unbind_tester"; | |||||
/** | |||||
* 操作服务器域名 | |||||
* | |||||
* @param domainAction 域名操作参数 | |||||
* 除了 webViewDomain,都是有效的 | |||||
* @return 以下字段仅在 get 时返回完整字段 | |||||
* @throws WxErrorException 操作失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaDomainAction modifyDomain(WxMaDomainAction domainAction) throws WxErrorException; | |||||
/** | |||||
* 设置小程序业务域名(仅供第三方代小程序调用) | |||||
* 授权给第三方的小程序,其业务域名只可以为第三方的服务器, | |||||
* 当小程序通过第三方发布代码上线后,小程序原先自己配置的业务域名将被删除, | |||||
* 只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加业务域名。 | |||||
* 提示:需要先将域名登记到第三方平台的小程序业务域名中,才可以调用接口进行配置。 | |||||
* | |||||
* @param domainAction 域名操作参数 | |||||
* 只有 action 和 webViewDomain 是有效的 | |||||
* @return 以下字段仅在 get 时返回完整字段 | |||||
* @throws WxErrorException 操作失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
WxMaDomainAction setWebViewDomain(WxMaDomainAction domainAction) throws WxErrorException; | |||||
/** | |||||
* 绑定微信用户为小程序体验者 | |||||
* | |||||
* @param wechatId 微信号 | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
void bindTester(String wechatId) throws WxErrorException; | |||||
/** | |||||
* 解除绑定小程序的体验者 | |||||
* | |||||
* @param wechatId 微信号 | |||||
* @throws WxErrorException 失败时抛出,具体错误码请看文档 | |||||
*/ | |||||
void unbindTester(String wechatId) throws WxErrorException; | |||||
} |
@@ -4,7 +4,7 @@ import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; | |||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | ||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | ||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.List; | import java.util.List; | ||||
@@ -3,7 +3,7 @@ package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; | import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* 用户信息相关操作接口. | * 用户信息相关操作接口. | ||||
@@ -0,0 +1,126 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaSummaryTrend; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitPage; | |||||
import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitTrend; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
import com.google.gson.JsonObject; | |||||
import com.google.gson.JsonParser; | |||||
import com.google.gson.reflect.TypeToken; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import org.apache.commons.lang3.time.DateFormatUtils; | |||||
import java.lang.reflect.Type; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
/** | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-28 | |||||
*/ | |||||
public class WxMaAnalysisServiceImpl implements WxMaAnalysisService { | |||||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||||
private WxMaService wxMaService; | |||||
public WxMaAnalysisServiceImpl(WxMaService wxMaService) { | |||||
this.wxMaService = wxMaService; | |||||
} | |||||
@Override | |||||
public List<WxMaSummaryTrend> getDailySummaryTrend(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getAnalysisResultAsList(GET_DAILY_SUMMARY_TREND_URL, beginDate, endDate, | |||||
new TypeToken<List<WxMaSummaryTrend>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public List<WxMaVisitTrend> getDailyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getAnalysisResultAsList(GET_DAILY_VISIT_TREND_URL, beginDate, endDate, | |||||
new TypeToken<List<WxMaVisitTrend>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public List<WxMaVisitTrend> getWeeklyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getAnalysisResultAsList(GET_WEEKLY_VISIT_TREND_URL, beginDate, endDate, | |||||
new TypeToken<List<WxMaVisitTrend>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public List<WxMaVisitTrend> getMonthlyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getAnalysisResultAsList(GET_MONTHLY_VISIT_TREND_URL, beginDate, endDate, | |||||
new TypeToken<List<WxMaVisitTrend>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public WxMaVisitDistribution getVisitDistribution(Date beginDate, Date endDate) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(GET_VISIT_DISTRIBUTION_URL, toJson(beginDate, endDate)); | |||||
return WxMaVisitDistribution.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public WxMaRetainInfo getDailyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getRetainInfo(beginDate, endDate, GET_DAILY_RETAIN_INFO_URL); | |||||
} | |||||
@Override | |||||
public WxMaRetainInfo getWeeklyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getRetainInfo(beginDate, endDate, GET_WEEKLY_RETAIN_INFO_URL); | |||||
} | |||||
@Override | |||||
public WxMaRetainInfo getMonthlyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getRetainInfo(beginDate, endDate, GET_MONTHLY_RETAIN_INFO_URL); | |||||
} | |||||
@Override | |||||
public List<WxMaVisitPage> getVisitPage(Date beginDate, Date endDate) throws WxErrorException { | |||||
return getAnalysisResultAsList(GET_VISIT_PAGE_URL, beginDate, endDate, | |||||
new TypeToken<List<WxMaVisitPage>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public WxMaUserPortrait getUserPortrait(Date beginDate, Date endDate) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(GET_USER_PORTRAIT_URL, toJson(beginDate, endDate)); | |||||
return WxMaUserPortrait.fromJson(responseContent); | |||||
} | |||||
private WxMaRetainInfo getRetainInfo(Date beginDate, Date endDate, String url) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(url, toJson(beginDate, endDate)); | |||||
return WxMaRetainInfo.fromJson(responseContent); | |||||
} | |||||
/** | |||||
* 获取数据分析结果并返回 List,returnType 类型 | |||||
* | |||||
* @param url 链接 | |||||
* @param returnType 返回的类型 | |||||
* @param <T> 返回的类型 | |||||
* @return List 类型的数据 | |||||
*/ | |||||
private <T> List<T> getAnalysisResultAsList(String url, Date beginDate, Date endDate, Type returnType) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(url, toJson(beginDate, endDate)); | |||||
JsonObject response = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||||
boolean hasList = response.has("list"); | |||||
if (hasList) { | |||||
return WxMaGsonBuilder.create().fromJson(response.getAsJsonArray("list"), returnType); | |||||
} else { | |||||
return null; | |||||
} | |||||
} | |||||
private static String toJson(Date beginDate, Date endDate) { | |||||
JsonObject param = new JsonObject(); | |||||
param.addProperty("begin_date", DateFormatUtils.format(beginDate, "yyyyMMdd")); | |||||
param.addProperty("end_date", DateFormatUtils.format(endDate, "yyyyMMdd")); | |||||
return param.toString(); | |||||
} | |||||
} |
@@ -0,0 +1,148 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaCodeService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCategory; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest; | |||||
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
import com.google.gson.JsonObject; | |||||
import com.google.gson.JsonParser; | |||||
import com.google.gson.reflect.TypeToken; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.util.List; | |||||
/** | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-26 20:00 | |||||
*/ | |||||
public class WxMaCodeServiceImpl implements WxMaCodeService { | |||||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||||
private WxMaService wxMaService; | |||||
public WxMaCodeServiceImpl(WxMaService wxMaService) { | |||||
this.wxMaService = wxMaService; | |||||
} | |||||
@Override | |||||
public void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException { | |||||
this.wxMaService.post(COMMIT_URL, commitRequest.toJson()); | |||||
} | |||||
@Override | |||||
public byte[] getQrCode() throws WxErrorException { | |||||
String appId = this.wxMaService.getWxMaConfig().getAppid(); | |||||
Path qrCodeFilePath = null; | |||||
try { | |||||
RequestExecutor<File, String> executor = BaseMediaDownloadRequestExecutor | |||||
.create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("weixin-java-tools-ma-" + appId).toFile()); | |||||
qrCodeFilePath = this.wxMaService.execute(executor, GET_QRCODE_URL, null).toPath(); | |||||
return Files.readAllBytes(qrCodeFilePath); | |||||
} catch (IOException e) { | |||||
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); | |||||
} finally { | |||||
if (qrCodeFilePath != null) { | |||||
try { | |||||
// 及时删除二维码文件,避免积压过多缓存文件 | |||||
Files.delete(qrCodeFilePath); | |||||
} catch (Exception ignored) { | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@Override | |||||
public List<WxMaCategory> getCategory() throws WxErrorException { | |||||
String responseContent = this.wxMaService.get(GET_CATEGORY_URL, null); | |||||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||||
boolean hasCategoryList = jsonObject.has("category_list"); | |||||
if (hasCategoryList) { | |||||
return WxMaGsonBuilder.create().fromJson(jsonObject.getAsJsonArray("category_list"), | |||||
new TypeToken<List<WxMaCategory>>() { | |||||
}.getType()); | |||||
} else { | |||||
return null; | |||||
} | |||||
} | |||||
@Override | |||||
public List<String> getPage() throws WxErrorException { | |||||
String responseContent = this.wxMaService.get(GET_PAGE_URL, null); | |||||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||||
boolean hasPageList = jsonObject.has("page_list"); | |||||
if (hasPageList) { | |||||
return WxMaGsonBuilder.create().fromJson(jsonObject.getAsJsonArray("page_list"), | |||||
new TypeToken<List<String>>() { | |||||
}.getType()); | |||||
} else { | |||||
return null; | |||||
} | |||||
} | |||||
@Override | |||||
public long submitAudit(WxMaCodeSubmitAuditRequest auditRequest) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(SUBMIT_AUDIT_URL, auditRequest.toJson()); | |||||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||||
return GsonHelper.getLong(jsonObject, "auditid"); | |||||
} | |||||
@Override | |||||
public WxMaCodeAuditStatus getAuditStatus(long auditId) throws WxErrorException { | |||||
JsonObject param = new JsonObject(); | |||||
param.addProperty("auditid", auditId); | |||||
String responseContent = this.wxMaService.post(GET_AUDIT_STATUS_URL, param.toString()); | |||||
return WxMaCodeAuditStatus.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public WxMaCodeAuditStatus getLatestAuditStatus() throws WxErrorException { | |||||
String responseContent = this.wxMaService.get(GET_LATEST_AUDIT_STATUS_URL, null); | |||||
return WxMaCodeAuditStatus.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public void release() throws WxErrorException { | |||||
this.wxMaService.post(RELEASE_URL, "{}"); | |||||
} | |||||
@Override | |||||
public void changeVisitStatus(String action) throws WxErrorException { | |||||
JsonObject param = new JsonObject(); | |||||
param.addProperty("action", action); | |||||
this.wxMaService.post(CHANGE_VISIT_STATUS_URL, param.toString()); | |||||
} | |||||
@Override | |||||
public void revertCodeRelease() throws WxErrorException { | |||||
this.wxMaService.get(REVERT_CODE_RELEASE_URL, null); | |||||
} | |||||
@Override | |||||
public WxMaCodeVersionDistribution getSupportVersion() throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(GET_SUPPORT_VERSION_URL, "{}"); | |||||
return WxMaCodeVersionDistribution.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public void setSupportVersion(String version) throws WxErrorException { | |||||
JsonObject param = new JsonObject(); | |||||
param.addProperty("version", version); | |||||
this.wxMaService.post(SET_SUPPORT_VERSION_URL, param.toString()); | |||||
} | |||||
@Override | |||||
public void undoCodeAudit() throws WxErrorException { | |||||
this.wxMaService.get(UNDO_CODE_AUDIT_URL, null); | |||||
} | |||||
} |
@@ -2,9 +2,9 @@ package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaMediaService; | import cn.binarywang.wx.miniapp.api.WxMaMediaService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
@@ -7,8 +7,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | |||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | import cn.binarywang.wx.miniapp.constant.WxMaConstants; | ||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
@@ -5,9 +5,9 @@ import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaQrcode; | import cn.binarywang.wx.miniapp.bean.WxMaQrcode; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaWxcode; | import cn.binarywang.wx.miniapp.bean.WxMaWxcode; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaWxcodeLimit; | |||||
import cn.binarywang.wx.miniapp.bean.WxaCodeUnlimit; | |||||
import cn.binarywang.wx.miniapp.util.http.QrCodeRequestExecutor; | import cn.binarywang.wx.miniapp.util.http.QrCodeRequestExecutor; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.io.File; | import java.io.File; | ||||
@@ -33,42 +33,44 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException { | |||||
public File createWxaCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException { | |||||
WxMaWxcode wxMaWxcode = new WxMaWxcode(); | WxMaWxcode wxMaWxcode = new WxMaWxcode(); | ||||
wxMaWxcode.setPath(path); | wxMaWxcode.setPath(path); | ||||
wxMaWxcode.setWidth(width); | wxMaWxcode.setWidth(width); | ||||
wxMaWxcode.setAutoColor(autoColor); | wxMaWxcode.setAutoColor(autoColor); | ||||
wxMaWxcode.setLineColor(lineColor); | wxMaWxcode.setLineColor(lineColor); | ||||
wxMaWxcode.setHyaline(isHyaline); | |||||
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | ||||
GET_WXACODE_URL, wxMaWxcode); | GET_WXACODE_URL, wxMaWxcode); | ||||
} | } | ||||
@Override | @Override | ||||
public File createWxCode(String path, int width) throws WxErrorException { | |||||
return this.createWxCode(path, width, true, null); | |||||
public File createWxaCode(String path, int width) throws WxErrorException { | |||||
return this.createWxaCode(path, width, true, null, false); | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCode(String path) throws WxErrorException { | |||||
return this.createWxCode(path, 430, true, null); | |||||
public File createWxaCode(String path) throws WxErrorException { | |||||
return this.createWxaCode(path, 430, true, null, false); | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) | |||||
public File createWxaCodeUnlimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) | |||||
throws WxErrorException { | throws WxErrorException { | ||||
WxMaWxcodeLimit wxMaWxcodeLimit = new WxMaWxcodeLimit(); | |||||
wxMaWxcodeLimit.setScene(scene); | |||||
wxMaWxcodeLimit.setPage(page); | |||||
wxMaWxcodeLimit.setWidth(width); | |||||
wxMaWxcodeLimit.setAutoColor(autoColor); | |||||
wxMaWxcodeLimit.setLineColor(lineColor); | |||||
WxaCodeUnlimit wxaCodeUnlimit = new WxaCodeUnlimit(); | |||||
wxaCodeUnlimit.setScene(scene); | |||||
wxaCodeUnlimit.setPage(page); | |||||
wxaCodeUnlimit.setWidth(width); | |||||
wxaCodeUnlimit.setAutoColor(autoColor); | |||||
wxaCodeUnlimit.setLineColor(lineColor); | |||||
wxaCodeUnlimit.setHyaline(isHyaline); | |||||
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | ||||
GET_WXACODE_UNLIMIT_URL, wxMaWxcodeLimit); | |||||
GET_WXACODE_UNLIMIT_URL, wxaCodeUnlimit); | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCodeLimit(String scene, String page) throws WxErrorException { | |||||
return this.createWxCodeLimit(scene, page, 430, true, null); | |||||
public File createWxaCodeUnlimit(String scene, String page) throws WxErrorException { | |||||
return this.createWxaCodeUnlimit(scene, page, 430, true, null, false); | |||||
} | } | ||||
} | } |
@@ -1,32 +1,21 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | package cn.binarywang.wx.miniapp.api.impl; | ||||
import java.io.IOException; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.concurrent.locks.Lock; | |||||
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.HttpGet; | |||||
import org.apache.http.impl.client.BasicResponseHandler; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaCodeService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaMediaService; | import cn.binarywang.wx.miniapp.api.WxMaMediaService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaMsgService; | import cn.binarywang.wx.miniapp.api.WxMaMsgService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaSettingService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaTemplateService; | import cn.binarywang.wx.miniapp.api.WxMaTemplateService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaUserService; | import cn.binarywang.wx.miniapp.api.WxMaUserService; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | ||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||||
import com.google.common.base.Joiner; | import com.google.common.base.Joiner; | ||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
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.crypto.SHA1; | ||||
import me.chanjar.weixin.common.util.http.HttpType; | import me.chanjar.weixin.common.util.http.HttpType; | ||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
@@ -35,6 +24,21 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | 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.ApacheHttpClientBuilder; | ||||
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | ||||
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.HttpGet; | |||||
import org.apache.http.impl.client.BasicResponseHandler; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.IOException; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.concurrent.locks.Lock; | |||||
import static cn.binarywang.wx.miniapp.constant.WxMaConstants.ErrorCode.*; | |||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
@@ -51,6 +55,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
private WxMaUserService userService = new WxMaUserServiceImpl(this); | private WxMaUserService userService = new WxMaUserServiceImpl(this); | ||||
private WxMaQrcodeService qrCodeService = new WxMaQrcodeServiceImpl(this); | private WxMaQrcodeService qrCodeService = new WxMaQrcodeServiceImpl(this); | ||||
private WxMaTemplateService templateService = new WxMaTemplateServiceImpl(this); | private WxMaTemplateService templateService = new WxMaTemplateServiceImpl(this); | ||||
private WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this); | |||||
private WxMaCodeService codeService = new WxMaCodeServiceImpl(this); | |||||
private WxMaSettingService settingService = new WxMaSettingServiceImpl(this); | |||||
private int retrySleepMillis = 1000; | private int retrySleepMillis = 1000; | ||||
private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
@@ -207,7 +214,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
throw new RuntimeException("微信服务端异常,超出重试次数"); | throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||
} | } | ||||
public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
private <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
E dataForLog = DataUtils.handleDataWithSecret(data); | |||||
if (uri.contains("access_token=")) { | if (uri.contains("access_token=")) { | ||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | ||||
} | } | ||||
@@ -217,16 +226,16 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
try { | try { | ||||
T result = executor.execute(uriWithAccessToken, data); | T result = executor.execute(uriWithAccessToken, data); | ||||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); | |||||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||||
return result; | return result; | ||||
} catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
WxError error = e.getError(); | WxError error = e.getError(); | ||||
/* | /* | ||||
* 发生以下情况时尝试刷新access_token | * 发生以下情况时尝试刷新access_token | ||||
*/ | */ | ||||
if (error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40001 | |||||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_42001 | |||||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40014) { | |||||
if (error.getErrorCode() == ERR_40001 | |||||
|| error.getErrorCode() == ERR_42001 | |||||
|| error.getErrorCode() == ERR_40014) { | |||||
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
this.getWxMaConfig().expireAccessToken(); | this.getWxMaConfig().expireAccessToken(); | ||||
if (this.getWxMaConfig().autoRefreshToken()) { | if (this.getWxMaConfig().autoRefreshToken()) { | ||||
@@ -235,12 +244,12 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
} | } | ||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); | |||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | |||||
throw new WxErrorException(error, e); | throw new WxErrorException(error, e); | ||||
} | } | ||||
return null; | return null; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); | |||||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | |||||
throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
} | } | ||||
} | } | ||||
@@ -290,4 +299,19 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
public WxMaTemplateService getTemplateService() { | public WxMaTemplateService getTemplateService() { | ||||
return this.templateService; | return this.templateService; | ||||
} | } | ||||
@Override | |||||
public WxMaAnalysisService getAnalysisService() { | |||||
return this.analysisService; | |||||
} | |||||
@Override | |||||
public WxMaCodeService getCodeService() { | |||||
return this.codeService; | |||||
} | |||||
@Override | |||||
public WxMaSettingService getSettingService() { | |||||
return this.settingService; | |||||
} | |||||
} | } |
@@ -0,0 +1,48 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaSettingService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||||
* @since 2018-04-27 15:46 | |||||
*/ | |||||
public class WxMaSettingServiceImpl implements WxMaSettingService { | |||||
private WxMaService wxMaService; | |||||
public WxMaSettingServiceImpl(WxMaService wxMaService) { | |||||
this.wxMaService = wxMaService; | |||||
} | |||||
@Override | |||||
public WxMaDomainAction modifyDomain(WxMaDomainAction domainAction) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(MODIFY_DOMAIN_URL, domainAction.toJson()); | |||||
return WxMaDomainAction.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public WxMaDomainAction setWebViewDomain(WxMaDomainAction domainAction) throws WxErrorException { | |||||
String responseContent = this.wxMaService.post(SET_WEB_VIEW_DOMAIN_URL, domainAction.toJson()); | |||||
return WxMaDomainAction.fromJson(responseContent); | |||||
} | |||||
@Override | |||||
public void bindTester(String wechatId) throws WxErrorException { | |||||
Map<String, Object> param = new HashMap<>(1); | |||||
param.put("wechatid", wechatId); | |||||
this.wxMaService.post(BIND_TESTER_URL, WxMaGsonBuilder.create().toJson(param)); | |||||
} | |||||
@Override | |||||
public void unbindTester(String wechatId) throws WxErrorException { | |||||
Map<String, Object> param = new HashMap<>(1); | |||||
param.put("wechatid", wechatId); | |||||
this.wxMaService.post(UNBIND_TESTER_URL, WxMaGsonBuilder.create().toJson(param)); | |||||
} | |||||
} |
@@ -6,8 +6,8 @@ import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; | |||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | ||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | ||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.error.WxError; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||