新增企业号工程并完成【部门管理】【成员管理】【标签管理】三个接口
This commit is contained in:
parent
f4aec9dc99
commit
5b213cd87f
12
README.md
12
README.md
@ -81,6 +81,18 @@ weixin4j
|
|||||||
* 2014-11-17
|
* 2014-11-17
|
||||||
|
|
||||||
+ **weixin4j-mp**: 新增`冲正`和`被扫支付`接口
|
+ **weixin4j-mp**: 新增`冲正`和`被扫支付`接口
|
||||||
|
|
||||||
|
* 2014-11-19
|
||||||
|
|
||||||
|
+ **weixin4j-base**: 新增`WeixinQyAccount`企业号账号信息类
|
||||||
|
|
||||||
|
+ **weixin4j-qy**: 得到`weixin4j-qy`和`weixin4j-qy-server`工程
|
||||||
|
|
||||||
|
+ **weixin4j-qy**: 新增`部门管理`接口
|
||||||
|
|
||||||
|
+ **weixin4j-qy**: 新增`用户管理`接口
|
||||||
|
|
||||||
|
+ **weixin4j-qy**: 新增`标签管理`接口
|
||||||
|
|
||||||
接下来
|
接下来
|
||||||
------
|
------
|
||||||
|
|||||||
23
pom.xml
23
pom.xml
@ -131,6 +131,29 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>${maven.assembly.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>src/main/assembly.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/java</directory>
|
<directory>src/main/java</directory>
|
||||||
|
|||||||
@ -25,4 +25,8 @@ weixin4j-base
|
|||||||
|
|
||||||
* 2014-11-15
|
* 2014-11-15
|
||||||
|
|
||||||
+ 新增`aes加密解密`函数
|
+ 新增`aes加密解密`函数
|
||||||
|
|
||||||
|
* 2014-11-19
|
||||||
|
|
||||||
|
+ 新增`WeixinQyAccount`企业号账号信息类
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<desc>system error</desc>
|
<desc>system error</desc>
|
||||||
<text>系统繁忙</text>
|
<text>系统繁忙</text>
|
||||||
</error>
|
</error>
|
||||||
<!-- 公众平台API错误 -->
|
<!-- 公众平台&企业号API错误 -->
|
||||||
<error>
|
<error>
|
||||||
<code>40001</code>
|
<code>40001</code>
|
||||||
<desc>invalid credential</desc>
|
<desc>invalid credential</desc>
|
||||||
@ -32,6 +32,14 @@
|
|||||||
<desc>invalid media type</desc>
|
<desc>invalid media type</desc>
|
||||||
<text>不合法的媒体文件类型</text>
|
<text>不合法的媒体文件类型</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40005</code>
|
||||||
|
<text>不合法的文件类型</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40006</code>
|
||||||
|
<text>不合法的文件大小</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40007</code>
|
<code>40007</code>
|
||||||
<desc>invalid media_id</desc>
|
<desc>invalid media_id</desc>
|
||||||
@ -102,6 +110,14 @@
|
|||||||
<desc>invalid button url size</desc>
|
<desc>invalid button url size</desc>
|
||||||
<text>不合法的url长度</text>
|
<text>不合法的url长度</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40021</code>
|
||||||
|
<text>不合法的菜单版本号</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40022</code>
|
||||||
|
<text>不合法的子菜单级数</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40023</code>
|
<code>40023</code>
|
||||||
<desc>invalid sub button size</desc>
|
<desc>invalid sub button size</desc>
|
||||||
@ -127,6 +143,10 @@
|
|||||||
<desc>invalid sub button url size</desc>
|
<desc>invalid sub button url size</desc>
|
||||||
<text>不合法的子菜单按钮url长度</text>
|
<text>不合法的子菜单按钮url长度</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40028</code>
|
||||||
|
<text>不合法的自定义菜单使用员工</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40029</code>
|
<code>40029</code>
|
||||||
<desc>invalid code</desc>
|
<desc>invalid code</desc>
|
||||||
@ -137,6 +157,22 @@
|
|||||||
<desc>invalid refresh_token</desc>
|
<desc>invalid refresh_token</desc>
|
||||||
<text>不合法的refresh_token</text>
|
<text>不合法的refresh_token</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40031</code>
|
||||||
|
<text>不合法的UserID列表</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40032</code>
|
||||||
|
<text>不合法的UserID列表长度</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40033</code>
|
||||||
|
<text>不合法的请求字符,不能包含\uxxxx格式的字符</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40035</code>
|
||||||
|
<text>不合法的参数</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40036</code>
|
<code>40036</code>
|
||||||
<desc>invalid template_id size</desc>
|
<desc>invalid template_id size</desc>
|
||||||
@ -147,11 +183,27 @@
|
|||||||
<desc>invalid template_id</desc>
|
<desc>invalid template_id</desc>
|
||||||
<text>不合法的template_id</text>
|
<text>不合法的template_id</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40038</code>
|
||||||
|
<text>不合法的请求格式</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40039</code>
|
<code>40039</code>
|
||||||
<desc>invalid url size</desc>
|
<desc>invalid url size</desc>
|
||||||
<text>不合法的url长度</text>
|
<text>不合法的url长度</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40040</code>
|
||||||
|
<text>不合法的插件token</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40041</code>
|
||||||
|
<text>不合法的插件id</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40042</code>
|
||||||
|
<text>不合法的插件会话</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40048</code>
|
<code>40048</code>
|
||||||
<desc>invalid url domain</desc>
|
<desc>invalid url domain</desc>
|
||||||
@ -167,10 +219,82 @@
|
|||||||
<desc>invalid button url domain</desc>
|
<desc>invalid button url domain</desc>
|
||||||
<text>不合法的菜单按钮url域名</text>
|
<text>不合法的菜单按钮url域名</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40056</code>
|
||||||
|
<text>不合法的agentid</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40057</code>
|
||||||
|
<text>不合法的callbackurl</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40058</code>
|
||||||
|
<text>不合法的红包参数</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40059</code>
|
||||||
|
<text>不合法的上报地理位置标志位</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40060</code>
|
||||||
|
<text>设置上报地理位置标志位时没有设置callbackurl</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40061</code>
|
||||||
|
<text>设置应用头像失败</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40062</code>
|
||||||
|
<text>不合法的应用模式</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40063</code>
|
||||||
|
<text>红包参数为空</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40064</code>
|
||||||
|
<text>管理组名字已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40065</code>
|
||||||
|
<text>不合法的管理组名字长度</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>40066</code>
|
<code>40066</code>
|
||||||
<desc>invalid url</desc>
|
<desc>invalid url/department</desc>
|
||||||
<text>不合法的url</text>
|
<text>不合法的url/不合法的部门列表</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40067</code>
|
||||||
|
<text>标题长度不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40068</code>
|
||||||
|
<text>不合法的标签ID</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40069</code>
|
||||||
|
<text>不合法的标签ID列表</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40070</code>
|
||||||
|
<text>列表中所有标签(用户)ID都不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40071</code>
|
||||||
|
<text>不合法的标签名字,标签名字已经存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40072</code>
|
||||||
|
<text>不合法的标签名字长度</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40073</code>
|
||||||
|
<text>不合法的openid</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>40074</code>
|
||||||
|
<text>news消息不支持指定为高保密消息</text>
|
||||||
</error>
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>41001</code>
|
<code>41001</code>
|
||||||
@ -222,6 +346,38 @@
|
|||||||
<desc>missing url</desc>
|
<desc>missing url</desc>
|
||||||
<text>缺失url参数</text>
|
<text>缺失url参数</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41011</code>
|
||||||
|
<text>缺少agentid</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41012</code>
|
||||||
|
<text>缺少应用头像mediaid</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41013</code>
|
||||||
|
<text>缺少应用名字</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41014</code>
|
||||||
|
<text>缺少应用描述</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41015</code>
|
||||||
|
<text>缺少Content</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41016</code>
|
||||||
|
<text>缺少标题</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41017</code>
|
||||||
|
<text>缺少标签ID</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>41018</code>
|
||||||
|
<text>缺少标签名字</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>42001</code>
|
<code>42001</code>
|
||||||
<desc>access_token expired</desc>
|
<desc>access_token expired</desc>
|
||||||
@ -237,6 +393,10 @@
|
|||||||
<desc>code expired</desc>
|
<desc>code expired</desc>
|
||||||
<text>code超时</text>
|
<text>code超时</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>42004</code>
|
||||||
|
<text>插件token超时</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>43001</code>
|
<code>43001</code>
|
||||||
<desc>require GET method</desc>
|
<desc>require GET method</desc>
|
||||||
@ -257,6 +417,34 @@
|
|||||||
<desc>require subscribe</desc>
|
<desc>require subscribe</desc>
|
||||||
<text>需要订阅关系</text>
|
<text>需要订阅关系</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43005</code>
|
||||||
|
<text>需要好友关系</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43006</code>
|
||||||
|
<text>需要订阅</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43007</code>
|
||||||
|
<text>需要授权</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43008</code>
|
||||||
|
<text>需要支付授权</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43009</code>
|
||||||
|
<text>需要员工已关注</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43010</code>
|
||||||
|
<text>需要处于回调模式</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>43011</code>
|
||||||
|
<text>需要企业授权</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>44001</code>
|
<code>44001</code>
|
||||||
<desc>empty media data</desc>
|
<desc>empty media data</desc>
|
||||||
@ -342,6 +530,10 @@
|
|||||||
<desc>template size out of limit</desc>
|
<desc>template size out of limit</desc>
|
||||||
<text>模板大小超过限制</text>
|
<text>模板大小超过限制</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45015</code>
|
||||||
|
<text>回复时间超过限制</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>45016</code>
|
<code>45016</code>
|
||||||
<desc>can't modify sys group</desc>
|
<desc>can't modify sys group</desc>
|
||||||
@ -357,11 +549,176 @@
|
|||||||
<desc>too many group now, no need to add new</desc>
|
<desc>too many group now, no need to add new</desc>
|
||||||
<text>组数量过多</text>
|
<text>组数量过多</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45024</code>
|
||||||
|
<text>账号数量超过上限</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>46001</code>
|
||||||
|
<text>不存在媒体数据</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>46002</code>
|
||||||
|
<text>不存在的菜单版本</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>46003</code>
|
||||||
|
<text>不存在的菜单数据</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>46004</code>
|
||||||
|
<text>不存在的员工</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>47001</code>
|
||||||
|
<text>解析JSON/XML内容错误</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>48002</code>
|
||||||
|
<text>Api禁用</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>50001</code>
|
<code>50001</code>
|
||||||
<desc>api unauthorized</desc>
|
<desc>api/redirect_uri unauthorized</desc>
|
||||||
<text>接口未授权</text>
|
<text>接口未授权</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>50002</code>
|
||||||
|
<text>员工不在权限范围</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>50003</code>
|
||||||
|
<text>应用已停用</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>50004</code>
|
||||||
|
<text>员工状态不正确(未关注状态)</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>50005</code>
|
||||||
|
<text>企业已禁用</text>
|
||||||
|
</error>
|
||||||
|
<!-- 企业号API错误 -->
|
||||||
|
<error>
|
||||||
|
<code>60001</code>
|
||||||
|
<text>部门长度不符合限制</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60002</code>
|
||||||
|
<text>部门层级深度超过限制</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60003</code>
|
||||||
|
<text>部门不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60004</code>
|
||||||
|
<text>父亲部门不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60005</code>
|
||||||
|
<text>不允许删除有成员的部门</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60006</code>
|
||||||
|
<text>不允许删除有子部门的部门</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60007</code>
|
||||||
|
<text>不允许删除根部门</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60008</code>
|
||||||
|
<text>部门名称已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60009</code>
|
||||||
|
<text>部门名称含有非法字符</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60010</code>
|
||||||
|
<text>部门存在循环关系</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60011</code>
|
||||||
|
<text>管理员权限不足(user/department/agent)无权限</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60012</code>
|
||||||
|
<text>不允许删除默认应用</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60013</code>
|
||||||
|
<text>不允许关闭应用</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60014</code>
|
||||||
|
<text>不允许开启应用</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60015</code>
|
||||||
|
<text>不允许修改默认应用可见范围</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60016</code>
|
||||||
|
<text>不允许删除存在成员的标签</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60017</code>
|
||||||
|
<text>不允许设置企业</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60102</code>
|
||||||
|
<text>UserID已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60103</code>
|
||||||
|
<text>手机号码不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60104</code>
|
||||||
|
<text>手机号码已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60105</code>
|
||||||
|
<text>邮箱不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60106</code>
|
||||||
|
<text>邮箱已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60107</code>
|
||||||
|
<text>微信号不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60108</code>
|
||||||
|
<text>微信号已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60109</code>
|
||||||
|
<text>QQ号已存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60110</code>
|
||||||
|
<text>部门个数超出限制</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60111</code>
|
||||||
|
<text>UserID不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60112</code>
|
||||||
|
<text>成员姓名不合法</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60113</code>
|
||||||
|
<text>身份认证信息(微信号/手机/邮箱)不能同时为空</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>60114</code>
|
||||||
|
<text>性别不合法</text>
|
||||||
|
</error>
|
||||||
<!-- 语义理解API错误 -->
|
<!-- 语义理解API错误 -->
|
||||||
<error>
|
<error>
|
||||||
<code>7000000</code>
|
<code>7000000</code>
|
||||||
|
|||||||
@ -11,4 +11,12 @@ public final class Consts {
|
|||||||
public static final String AES = "AES";
|
public static final String AES = "AES";
|
||||||
public static final String PROTOCOL_FILE = "file";
|
public static final String PROTOCOL_FILE = "file";
|
||||||
public static final String PROTOCOL_JAR = "jar";
|
public static final String PROTOCOL_JAR = "jar";
|
||||||
|
|
||||||
|
public static final String MP_ASSESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||||
|
public static final String QY_ASSESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
|
||||||
|
|
||||||
|
public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||||
|
public static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay";
|
||||||
|
public static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s";
|
||||||
|
public static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.foxinmy.weixin4j.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户性别
|
||||||
|
*
|
||||||
|
* @className Gender
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月5日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public enum Gender {
|
||||||
|
male, female, unknown;
|
||||||
|
}
|
||||||
@ -2,48 +2,51 @@ package com.foxinmy.weixin4j.model;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信账户信息
|
* 微信账号信息
|
||||||
*
|
*
|
||||||
* @className WeixinAccount
|
* @className WeixinAccount
|
||||||
* @author jy
|
* @author jy
|
||||||
* @date 2014年8月17日
|
* @date 2014年11月18日
|
||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class WeixinAccount implements Serializable {
|
public abstract class WeixinAccount implements Serializable {
|
||||||
private static final long serialVersionUID = 3689999353867189585L;
|
private static final long serialVersionUID = -6001008896414323534L;
|
||||||
|
|
||||||
|
// 唯一的身份标识
|
||||||
|
private String id;
|
||||||
|
// 调用接口的密钥
|
||||||
|
private String secret;
|
||||||
private String token;
|
private String token;
|
||||||
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
|
||||||
private String openId;
|
|
||||||
// 公众号身份的唯一标识
|
|
||||||
private String appId;
|
|
||||||
// 公众平台接口 API 的权限获取所需密钥 Key
|
|
||||||
private String appSecret;
|
|
||||||
// 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
|
||||||
private String paySignKey;
|
|
||||||
// 安全模式下的加密密钥
|
// 安全模式下的加密密钥
|
||||||
private String encodingAesKey;
|
private String encodingAesKey;
|
||||||
// 财付通商户身份的标识
|
|
||||||
private String partnerId;
|
|
||||||
// 财付通商户权限密钥Key
|
|
||||||
private String partnerKey;
|
|
||||||
// 微信支付商户号V3.x版本
|
|
||||||
private String mchId;
|
|
||||||
// 微信支付分配的设备号
|
|
||||||
private String deviceInfo;
|
|
||||||
// 微信支付版本号(如果无则按照mchId来做判断)
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
// 是否已经认证
|
public abstract String getTokenUrl();
|
||||||
private boolean isAlive;
|
|
||||||
// 是否是服务号
|
public WeixinAccount() {
|
||||||
private boolean isService;
|
}
|
||||||
// 是否是订阅号
|
|
||||||
private boolean isSubscribe;
|
public WeixinAccount(String id, String secret) {
|
||||||
|
this.id = id;
|
||||||
|
this.secret = secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecret() {
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecret(String secret) {
|
||||||
|
this.secret = secret;
|
||||||
|
}
|
||||||
|
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
return token;
|
return token;
|
||||||
@ -53,30 +56,6 @@ public class WeixinAccount implements Serializable {
|
|||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOpenId() {
|
|
||||||
return openId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOpenId(String openId) {
|
|
||||||
this.openId = openId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppId() {
|
|
||||||
return appId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppId(String appId) {
|
|
||||||
this.appId = appId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppSecret() {
|
|
||||||
return appSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppSecret(String appSecret) {
|
|
||||||
this.appSecret = appSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEncodingAesKey() {
|
public String getEncodingAesKey() {
|
||||||
return encodingAesKey;
|
return encodingAesKey;
|
||||||
}
|
}
|
||||||
@ -85,130 +64,9 @@ public class WeixinAccount implements Serializable {
|
|||||||
this.encodingAesKey = encodingAesKey;
|
this.encodingAesKey = encodingAesKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPaySignKey() {
|
|
||||||
return paySignKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPaySignKey(String paySignKey) {
|
|
||||||
this.paySignKey = paySignKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPartnerId() {
|
|
||||||
return partnerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPartnerId(String partnerId) {
|
|
||||||
this.partnerId = partnerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPartnerKey() {
|
|
||||||
return partnerKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPartnerKey(String partnerKey) {
|
|
||||||
this.partnerKey = partnerKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMchId() {
|
|
||||||
return mchId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMchId(String mchId) {
|
|
||||||
this.mchId = mchId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDeviceInfo() {
|
|
||||||
return deviceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeviceInfo(String deviceInfo) {
|
|
||||||
this.deviceInfo = deviceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsAlive() {
|
|
||||||
return isAlive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsAlive(Boolean isAlive) {
|
|
||||||
this.isAlive = isAlive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsService() {
|
|
||||||
return isService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsService(Boolean isService) {
|
|
||||||
this.isService = isService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsSubscribe() {
|
|
||||||
return isSubscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsSubscribe(Boolean isSubscribe) {
|
|
||||||
this.isSubscribe = isSubscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() {
|
|
||||||
if (version == 0) {
|
|
||||||
return StringUtils.isNotBlank(mchId) ? 3 : 2;
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(int version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WeixinAccount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public WeixinAccount(String appId, String appSecret) {
|
|
||||||
this.appId = appId;
|
|
||||||
this.appSecret = appSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* V3版本字段
|
|
||||||
*
|
|
||||||
* @param appId
|
|
||||||
* @param appSecret
|
|
||||||
* @param paySignKey
|
|
||||||
* @param mchId
|
|
||||||
*/
|
|
||||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
|
||||||
String mchId) {
|
|
||||||
this(appId, appSecret);
|
|
||||||
this.paySignKey = paySignKey;
|
|
||||||
this.mchId = mchId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* V2版本字段
|
|
||||||
*
|
|
||||||
* @param appId
|
|
||||||
* @param appSecret
|
|
||||||
* @param paySignKey
|
|
||||||
* @param partnerId
|
|
||||||
* @param partnerKey
|
|
||||||
*/
|
|
||||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
|
||||||
String partnerId, String partnerKey) {
|
|
||||||
this(appId, appSecret);
|
|
||||||
this.paySignKey = paySignKey;
|
|
||||||
this.partnerId = partnerId;
|
|
||||||
this.partnerKey = partnerKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "WeixinAccount [token=" + token + ", openId=" + openId
|
return "WeixinAccount [id=" + id + ", secret=" + secret + ", token="
|
||||||
+ ", appId=" + appId + ", appSecret=" + appSecret
|
+ token + ", encodingAesKey=" + encodingAesKey + "]";
|
||||||
+ ", encodingAesKey=" + encodingAesKey + ", paySignKey="
|
|
||||||
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
|
|
||||||
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
|
|
||||||
+ deviceInfo + ", isAlive=" + isAlive + ", isService="
|
|
||||||
+ isService + ", isSubscribe=" + isSubscribe + "]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,178 @@
|
|||||||
|
package com.foxinmy.weixin4j.model;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信公众平台信息
|
||||||
|
*
|
||||||
|
* @className WeixinMpAccount
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年8月17日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class WeixinMpAccount extends WeixinAccount {
|
||||||
|
private static final long serialVersionUID = 3689999353867189585L;
|
||||||
|
|
||||||
|
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
||||||
|
private String openId;
|
||||||
|
// 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
||||||
|
private String paySignKey;
|
||||||
|
// 财付通商户身份的标识
|
||||||
|
private String partnerId;
|
||||||
|
// 财付通商户权限密钥Key
|
||||||
|
private String partnerKey;
|
||||||
|
// 微信支付商户号V3.x版本
|
||||||
|
private String mchId;
|
||||||
|
// 微信支付分配的设备号
|
||||||
|
private String deviceInfo;
|
||||||
|
// 微信支付版本号(如果无则按照mchId来做判断)
|
||||||
|
private int version;
|
||||||
|
|
||||||
|
// 是否已经认证
|
||||||
|
private boolean isAlive;
|
||||||
|
// 是否是服务号
|
||||||
|
private boolean isService;
|
||||||
|
// 是否是订阅号
|
||||||
|
private boolean isSubscribe;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTokenUrl() {
|
||||||
|
return String.format(Consts.MP_ASSESS_TOKEN_URL, getId(), getSecret());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenId() {
|
||||||
|
return openId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenId(String openId) {
|
||||||
|
this.openId = openId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPaySignKey() {
|
||||||
|
return paySignKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaySignKey(String paySignKey) {
|
||||||
|
this.paySignKey = paySignKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartnerId() {
|
||||||
|
return partnerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartnerId(String partnerId) {
|
||||||
|
this.partnerId = partnerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartnerKey() {
|
||||||
|
return partnerKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartnerKey(String partnerKey) {
|
||||||
|
this.partnerKey = partnerKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMchId() {
|
||||||
|
return mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMchId(String mchId) {
|
||||||
|
this.mchId = mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceInfo() {
|
||||||
|
return deviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceInfo(String deviceInfo) {
|
||||||
|
this.deviceInfo = deviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsAlive() {
|
||||||
|
return isAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsAlive(Boolean isAlive) {
|
||||||
|
this.isAlive = isAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsService() {
|
||||||
|
return isService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsService(Boolean isService) {
|
||||||
|
this.isService = isService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsSubscribe() {
|
||||||
|
return isSubscribe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsSubscribe(Boolean isSubscribe) {
|
||||||
|
this.isSubscribe = isSubscribe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
if (version == 0) {
|
||||||
|
return StringUtils.isNotBlank(mchId) ? 3 : 2;
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(int version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeixinMpAccount() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeixinMpAccount(String appId, String appSecret) {
|
||||||
|
super(appId, appSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V3版本字段
|
||||||
|
*
|
||||||
|
* @param appId
|
||||||
|
* @param appSecret
|
||||||
|
* @param paySignKey
|
||||||
|
* @param mchId
|
||||||
|
*/
|
||||||
|
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
|
||||||
|
String mchId) {
|
||||||
|
this(appId, appSecret);
|
||||||
|
this.paySignKey = paySignKey;
|
||||||
|
this.mchId = mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V2版本字段
|
||||||
|
*
|
||||||
|
* @param appId
|
||||||
|
* @param appSecret
|
||||||
|
* @param paySignKey
|
||||||
|
* @param partnerId
|
||||||
|
* @param partnerKey
|
||||||
|
*/
|
||||||
|
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
|
||||||
|
String partnerId, String partnerKey) {
|
||||||
|
this(appId, appSecret);
|
||||||
|
this.paySignKey = paySignKey;
|
||||||
|
this.partnerId = partnerId;
|
||||||
|
this.partnerKey = partnerKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "WeixinMpAccount [openId=" + openId + ", paySignKey="
|
||||||
|
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
|
||||||
|
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
|
||||||
|
+ deviceInfo + ", version=" + version + ", isAlive=" + isAlive
|
||||||
|
+ ", isService=" + isService + ", isSubscribe=" + isSubscribe
|
||||||
|
+ ", getId()=" + getId() + ", getSecret()=" + getSecret()
|
||||||
|
+ ", getToken()=" + getToken() + ", getEncodingAesKey()="
|
||||||
|
+ getEncodingAesKey() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.foxinmy.weixin4j.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信企业号信息
|
||||||
|
*
|
||||||
|
* @className WeixinQyAccount
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class WeixinQyAccount extends WeixinAccount {
|
||||||
|
private static final long serialVersionUID = 3689999353867189585L;
|
||||||
|
|
||||||
|
public WeixinQyAccount() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeixinQyAccount(String corpid, String corpsecret) {
|
||||||
|
super(corpid, corpsecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTokenUrl() {
|
||||||
|
return String.format(Consts.QY_ASSESS_TOKEN_URL, getId(), getSecret());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "WeixinQyAccount [getTokenUrl()=" + getTokenUrl() + ", getId()="
|
||||||
|
+ getId() + ", getSecret()=" + getSecret() + ", getToken()="
|
||||||
|
+ getToken() + ", getEncodingAesKey()=" + getEncodingAesKey()
|
||||||
|
+ "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +1,8 @@
|
|||||||
package com.foxinmy.weixin4j.msg;
|
package com.foxinmy.weixin4j.msg;
|
||||||
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.BaseMsg;
|
import com.foxinmy.weixin4j.model.BaseMsg;
|
||||||
import com.foxinmy.weixin4j.type.MessageType;
|
import com.foxinmy.weixin4j.type.MessageType;
|
||||||
import com.foxinmy.weixin4j.util.ClassUtil;
|
|
||||||
import com.foxinmy.weixin4j.xml.XStream;
|
|
||||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
|
||||||
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
|
|
||||||
import com.thoughtworks.xstream.io.json.JsonWriter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 普通消息基类
|
* 普通消息基类
|
||||||
@ -26,32 +19,12 @@ import com.thoughtworks.xstream.io.json.JsonWriter;
|
|||||||
public class BaseMessage extends BaseMsg {
|
public class BaseMessage extends BaseMsg {
|
||||||
|
|
||||||
private static final long serialVersionUID = 7761192742840031607L;
|
private static final long serialVersionUID = 7761192742840031607L;
|
||||||
private final static XStream xmlStream = XStream.get();
|
|
||||||
private final static XStream jsonStream = new XStream(
|
|
||||||
new JsonHierarchicalStreamDriver() {
|
|
||||||
public HierarchicalStreamWriter createWriter(Writer writer) {
|
|
||||||
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@XStreamAlias("MsgType")
|
@XStreamAlias("MsgType")
|
||||||
private MessageType msgType; // 消息类型
|
private MessageType msgType; // 消息类型
|
||||||
@XStreamAlias("MsgId")
|
@XStreamAlias("MsgId")
|
||||||
private long msgId; // 消息ID
|
private long msgId; // 消息ID
|
||||||
|
|
||||||
static {
|
|
||||||
Class<?>[] classes = ClassUtil.getClasses(
|
|
||||||
TextMessage.class.getPackage()).toArray(new Class[0]);
|
|
||||||
|
|
||||||
xmlStream.processAnnotations(classes);
|
|
||||||
xmlStream.omitField(BaseMessage.class, "msgId");
|
|
||||||
|
|
||||||
jsonStream.setMode(XStream.NO_REFERENCES);
|
|
||||||
jsonStream.autodetectAnnotations(true);
|
|
||||||
jsonStream.processAnnotations(classes);
|
|
||||||
jsonStream.omitField(BaseMessage.class, "msgId");
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseMessage(MessageType msgType) {
|
public BaseMessage(MessageType msgType) {
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
}
|
}
|
||||||
@ -79,25 +52,4 @@ public class BaseMessage extends BaseMsg {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息对象转换为微信服务器接受的xml格式消息
|
|
||||||
*
|
|
||||||
* @return xml字符串
|
|
||||||
*/
|
|
||||||
public String toXml() {
|
|
||||||
Class<? extends BaseMessage> targetClass = getMsgType()
|
|
||||||
.getMessageClass();
|
|
||||||
xmlStream.alias("xml", targetClass);
|
|
||||||
return xmlStream.toXML(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息对象转换为微信服务器接受的json格式字符串
|
|
||||||
*
|
|
||||||
* @return json字符串
|
|
||||||
*/
|
|
||||||
public String toJson() {
|
|
||||||
return jsonStream.toXML(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package com.foxinmy.weixin4j.token;
|
|||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取weixin.properties中的appid&appsecret信息
|
* 获取weixin.properties中的id&secret信息
|
||||||
*
|
*
|
||||||
* @className AbstractTokenHolder
|
* @className AbstractTokenHolder
|
||||||
* @author jy
|
* @author jy
|
||||||
@ -14,12 +15,18 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
|||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractTokenHolder implements TokenHolder {
|
public abstract class AbstractTokenHolder implements TokenHolder {
|
||||||
protected final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
|
||||||
protected final HttpRequest request = new HttpRequest();
|
|
||||||
private final WeixinAccount weixinAccount;
|
|
||||||
|
|
||||||
public AbstractTokenHolder() {
|
protected final HttpRequest request = new HttpRequest();
|
||||||
this.weixinAccount = ConfigUtil.getWeixinAccount();
|
protected final WeixinAccount weixinAccount;
|
||||||
|
|
||||||
|
public AbstractTokenHolder(AccountType accountType) {
|
||||||
|
if (accountType == AccountType.MP) {
|
||||||
|
this.weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
|
} else if (accountType == AccountType.QY) {
|
||||||
|
this.weixinAccount = ConfigUtil.getWeixinQyAccount();
|
||||||
|
} else {
|
||||||
|
this.weixinAccount = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractTokenHolder(WeixinAccount weixinAccount) {
|
public AbstractTokenHolder(WeixinAccount weixinAccount) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
|
|||||||
import com.foxinmy.weixin4j.http.Response;
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
import com.foxinmy.weixin4j.model.Token;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
import com.foxinmy.weixin4j.xml.XStream;
|
import com.foxinmy.weixin4j.xml.XStream;
|
||||||
|
|
||||||
@ -24,23 +25,20 @@ import com.foxinmy.weixin4j.xml.XStream;
|
|||||||
* @date 2014年9月27日
|
* @date 2014年9月27日
|
||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see <a
|
* @see <a
|
||||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明</a>
|
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明</a>
|
||||||
|
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8">微信企业号获取token说明</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Token
|
* @see com.foxinmy.weixin4j.model.Token
|
||||||
*/
|
*/
|
||||||
public class FileTokenHolder extends AbstractTokenHolder {
|
public class FileTokenHolder extends AbstractTokenHolder {
|
||||||
|
|
||||||
public FileTokenHolder() {
|
public FileTokenHolder(AccountType accountType) {
|
||||||
super();
|
super(accountType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileTokenHolder(WeixinAccount weixinAccount) {
|
public FileTokenHolder(WeixinAccount weixinAccount) {
|
||||||
super(weixinAccount);
|
super(weixinAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileTokenHolder(String appid, String appsecret) {
|
|
||||||
this(new WeixinAccount(appid, appsecret));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取token
|
* 获取token
|
||||||
* <p>
|
* <p>
|
||||||
@ -55,14 +53,13 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Token getToken() throws WeixinException {
|
public Token getToken() throws WeixinException {
|
||||||
String appid = getAccount().getAppId();
|
String id = weixinAccount.getId();
|
||||||
String appsecret = getAccount().getAppSecret();
|
if (StringUtils.isBlank(id) || StringUtils.isBlank(weixinAccount.getSecret())) {
|
||||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"appid or appsecret not be null!");
|
"id or secret not be null!");
|
||||||
}
|
}
|
||||||
File token_file = new File(String.format("%s/token_%s.xml",
|
File token_file = new File(String.format("%s/token_%s.xml",
|
||||||
ConfigUtil.getValue("token_path"), appid));
|
ConfigUtil.getValue("token_path"), id));
|
||||||
Token token = null;
|
Token token = null;
|
||||||
Calendar ca = Calendar.getInstance();
|
Calendar ca = Calendar.getInstance();
|
||||||
long now_time = ca.getTimeInMillis();
|
long now_time = ca.getTimeInMillis();
|
||||||
@ -78,8 +75,7 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
|||||||
} else {
|
} else {
|
||||||
token_file.createNewFile();
|
token_file.createNewFile();
|
||||||
}
|
}
|
||||||
String api_token_uri = String.format(tokenUrl, appid, appsecret);
|
Response response = request.get(weixinAccount.getTokenUrl());
|
||||||
Response response = request.get(api_token_uri);
|
|
||||||
token = response.getAsObject(new TypeReference<Token>() {
|
token = response.getAsObject(new TypeReference<Token>() {
|
||||||
});
|
});
|
||||||
token.setTime(now_time);
|
token.setTime(now_time);
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import com.alibaba.fastjson.TypeReference;
|
|||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.model.Token;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于redis保存的Token获取类
|
* 基于redis保存的Token获取类
|
||||||
@ -20,7 +21,10 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
|
|||||||
* @date 2014年9月27日
|
* @date 2014年9月27日
|
||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see <a
|
* @see <a
|
||||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明</a>
|
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明</a>
|
||||||
|
* @see <a href=
|
||||||
|
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8"
|
||||||
|
* >微信企业号获取token说明</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Token
|
* @see com.foxinmy.weixin4j.model.Token
|
||||||
*/
|
*/
|
||||||
public class RedisTokenHolder extends AbstractTokenHolder {
|
public class RedisTokenHolder extends AbstractTokenHolder {
|
||||||
@ -37,47 +41,39 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
|||||||
this.jedisPool = new JedisPool(poolConfig, host, port);
|
this.jedisPool = new JedisPool(poolConfig, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RedisTokenHolder() {
|
public RedisTokenHolder(String host, int port, AccountType accountType) {
|
||||||
this("localhost", 6379);
|
super(accountType);
|
||||||
}
|
|
||||||
|
|
||||||
public RedisTokenHolder(String host, int port) {
|
|
||||||
super();
|
|
||||||
createPool(host, port);
|
createPool(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RedisTokenHolder(AccountType accountType) {
|
||||||
|
this("localhost", 6379, accountType);
|
||||||
|
}
|
||||||
|
|
||||||
public RedisTokenHolder(WeixinAccount weixinAccount) {
|
public RedisTokenHolder(WeixinAccount weixinAccount) {
|
||||||
this(weixinAccount, "localhost", 6379);
|
this("localhost", 6379, weixinAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RedisTokenHolder(String appId, String appSecret, String host,
|
public RedisTokenHolder(String host, int port, WeixinAccount weixinAccount) {
|
||||||
int port) {
|
|
||||||
this(new WeixinAccount(appId, appSecret), host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RedisTokenHolder(WeixinAccount weixinAccount, String host, int port) {
|
|
||||||
super(weixinAccount);
|
super(weixinAccount);
|
||||||
createPool(host, port);
|
createPool(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Token getToken() throws WeixinException {
|
public Token getToken() throws WeixinException {
|
||||||
String appid = getAccount().getAppId();
|
String id = weixinAccount.getId();
|
||||||
String appsecret = getAccount().getAppSecret();
|
if (StringUtils.isBlank(id)
|
||||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
|| StringUtils.isBlank(weixinAccount.getSecret())) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("id or secret not be null!");
|
||||||
"appid or appsecret not be null!");
|
|
||||||
}
|
}
|
||||||
Token token = null;
|
Token token = null;
|
||||||
Jedis jedis = null;
|
Jedis jedis = null;
|
||||||
try {
|
try {
|
||||||
jedis = jedisPool.getResource();
|
jedis = jedisPool.getResource();
|
||||||
String key = String.format("token:%s", appid);
|
String key = String.format("token:%s", id);
|
||||||
String accessToken = jedis.get(key);
|
String accessToken = jedis.get(key);
|
||||||
if (StringUtils.isBlank(accessToken)) {
|
if (StringUtils.isBlank(accessToken)) {
|
||||||
String api_token_uri = String
|
token = request.get(weixinAccount.getTokenUrl()).getAsObject(
|
||||||
.format(tokenUrl, appid, appsecret);
|
|
||||||
token = request.get(api_token_uri).getAsObject(
|
|
||||||
new TypeReference<Token>() {
|
new TypeReference<Token>() {
|
||||||
});
|
});
|
||||||
jedis.setex(key, token.getExpiresIn() - 3,
|
jedis.setex(key, token.getExpiresIn() - 3,
|
||||||
|
|||||||
@ -18,6 +18,5 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
|
|||||||
*/
|
*/
|
||||||
public interface TokenHolder {
|
public interface TokenHolder {
|
||||||
public WeixinAccount getAccount();
|
public WeixinAccount getAccount();
|
||||||
|
|
||||||
public Token getToken() throws WeixinException;
|
public Token getToken() throws WeixinException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.foxinmy.weixin4j.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号类型
|
||||||
|
*
|
||||||
|
* @className AccountType
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public enum AccountType {
|
||||||
|
MP, QY
|
||||||
|
}
|
||||||
@ -5,7 +5,8 @@ import java.util.ResourceBundle;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
|
import com.foxinmy.weixin4j.model.WeixinQyAccount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商户配置工具类
|
* 商户配置工具类
|
||||||
@ -33,8 +34,13 @@ public class ConfigUtil {
|
|||||||
return weixinBundle.getString(key);
|
return weixinBundle.getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WeixinAccount getWeixinAccount() {
|
public static WeixinMpAccount getWeixinMpAccount() {
|
||||||
String text = getValue("account");
|
String text = getValue("account");
|
||||||
return JSON.parseObject(text, WeixinAccount.class);
|
return JSON.parseObject(text, WeixinMpAccount.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WeixinQyAccount getWeixinQyAccount() {
|
||||||
|
String text = getValue("account");
|
||||||
|
return JSON.parseObject(text, WeixinQyAccount.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,29 +19,6 @@
|
|||||||
</modules>
|
</modules>
|
||||||
<build>
|
<build>
|
||||||
<finalName>weixin4j-mp</finalName>
|
<finalName>weixin4j-mp</finalName>
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<version>${maven.assembly.plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>src/main/assembly.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>make-assembly</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ weixin.properties说明
|
|||||||
|
|
||||||
示例(properties中换行用右斜杆\\)
|
示例(properties中换行用右斜杆\\)
|
||||||
|
|
||||||
> account={"appId":"appId","appSecret":"appSecret",
|
> account={"id":"appId","secret":"appSecret",
|
||||||
> "token":"开放者的token 非必须","openId":"公众号的openid 非必须",
|
> "token":"开放者的token 非必须","openId":"公众号的openid 非必须",
|
||||||
> "encodingAesKey":"公众号设置了加密方式且为「安全模式」需要填入",
|
> "encodingAesKey":"公众号设置了加密方式且为「安全模式」需要填入",
|
||||||
> "mchId":"V3.x版本下的微信商户号",
|
> "mchId":"V3.x版本下的微信商户号",
|
||||||
@ -69,7 +69,6 @@ weixin.properties说明
|
|||||||
3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`.
|
3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`.
|
||||||
|
|
||||||
WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder());
|
WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder());
|
||||||
// weixinProxy = new WeixinProxy(new RedisTokenHolder(appid,appsecret));
|
|
||||||
// weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount));
|
// weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount));
|
||||||
|
|
||||||
4.`mvn package`.
|
4.`mvn package`.
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<artifactId>weixin4j-mp-api</artifactId>
|
<artifactId>weixin4j-mp-api</artifactId>
|
||||||
<name>weixin4j-mp-api</name>
|
<name>weixin4j-mp-api</name>
|
||||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-api</url>
|
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-mp-api</url>
|
||||||
<description>微信公众号API</description>
|
<description>微信公众号API</description>
|
||||||
<build>
|
<build>
|
||||||
<finalName>weixin4j-mp-api</finalName>
|
<finalName>weixin4j-mp-api</finalName>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.JsonResult;
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
import com.foxinmy.weixin4j.http.XmlResult;
|
import com.foxinmy.weixin4j.http.XmlResult;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
||||||
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
||||||
import com.foxinmy.weixin4j.mp.api.HelperApi;
|
import com.foxinmy.weixin4j.mp.api.HelperApi;
|
||||||
@ -45,10 +45,11 @@ import com.foxinmy.weixin4j.mp.type.BillType;
|
|||||||
import com.foxinmy.weixin4j.mp.type.IdQuery;
|
import com.foxinmy.weixin4j.mp.type.IdQuery;
|
||||||
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
||||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
import com.foxinmy.weixin4j.type.MediaType;
|
import com.foxinmy.weixin4j.type.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信服务实现
|
* 微信公众平台接口实现
|
||||||
*
|
*
|
||||||
* @className WeixinProxy
|
* @className WeixinProxy
|
||||||
* @author jy.hu
|
* @author jy.hu
|
||||||
@ -74,18 +75,18 @@ public class WeixinProxy {
|
|||||||
* 默认采用文件存放Token信息
|
* 默认采用文件存放Token信息
|
||||||
*/
|
*/
|
||||||
public WeixinProxy() {
|
public WeixinProxy() {
|
||||||
this(new FileTokenHolder());
|
this(new FileTokenHolder(AccountType.MP));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* appid,appsecret<br/>
|
* appid,appsecret<br>
|
||||||
* <font color="red">将无法调用支付相关接口</font>
|
* <font color="red">将无法调用支付相关接口</font>
|
||||||
*
|
*
|
||||||
* @param appid
|
* @param appid
|
||||||
* @param appsecret
|
* @param appsecret
|
||||||
*/
|
*/
|
||||||
public WeixinProxy(String appid, String appsecret) {
|
public WeixinProxy(String appid, String appsecret) {
|
||||||
this(new FileTokenHolder(appid, appsecret));
|
this(new WeixinMpAccount(appid, appsecret));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +94,7 @@ public class WeixinProxy {
|
|||||||
*
|
*
|
||||||
* @param weixinAccount
|
* @param weixinAccount
|
||||||
*/
|
*/
|
||||||
public WeixinProxy(WeixinAccount weixinAccount) {
|
public WeixinProxy(WeixinMpAccount weixinAccount) {
|
||||||
this(new FileTokenHolder(weixinAccount));
|
this(new FileTokenHolder(weixinAccount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,7 +794,7 @@ public class WeixinProxy {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||||
*/
|
*/
|
||||||
public Order orderQueryV2(WeixinAccount weixinAccount, String outTradeNo)
|
public Order orderQueryV2(WeixinMpAccount weixinAccount, String outTradeNo)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return payApi.orderQueryV2(outTradeNo);
|
return payApi.orderQueryV2(outTradeNo);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import com.alibaba.fastjson.TypeReference;
|
|||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.Response;
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
import com.foxinmy.weixin4j.model.Token;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.model.SemQuery;
|
import com.foxinmy.weixin4j.mp.model.SemQuery;
|
||||||
import com.foxinmy.weixin4j.mp.model.SemResult;
|
import com.foxinmy.weixin4j.mp.model.SemResult;
|
||||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
@ -65,10 +65,10 @@ public class HelperApi extends BaseApi {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public SemResult semantic(SemQuery semQuery) throws WeixinException {
|
public SemResult semantic(SemQuery semQuery) throws WeixinException {
|
||||||
WeixinAccount weixinAccount = tokenHolder.getAccount();
|
WeixinMpAccount weixinAccount = (WeixinMpAccount) tokenHolder.getAccount();
|
||||||
String semantic_uri = getRequestUri("semantic_uri");
|
String semantic_uri = getRequestUri("semantic_uri");
|
||||||
Token token = tokenHolder.getToken();
|
Token token = tokenHolder.getToken();
|
||||||
semQuery.appid(weixinAccount.getAppId());
|
semQuery.appid(weixinAccount.getId());
|
||||||
Response response = request.post(
|
Response response = request.post(
|
||||||
String.format(semantic_uri, token.getAccessToken()),
|
String.format(semantic_uri, token.getAccessToken()),
|
||||||
semQuery.toJson());
|
semQuery.toJson());
|
||||||
|
|||||||
@ -41,7 +41,7 @@ import com.foxinmy.weixin4j.http.Response;
|
|||||||
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
||||||
import com.foxinmy.weixin4j.http.XmlResult;
|
import com.foxinmy.weixin4j.http.XmlResult;
|
||||||
import com.foxinmy.weixin4j.model.Token;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||||
import com.foxinmy.weixin4j.mp.payment.Refund;
|
import com.foxinmy.weixin4j.mp.payment.Refund;
|
||||||
@ -70,11 +70,11 @@ import com.foxinmy.weixin4j.util.RandomUtil;
|
|||||||
*/
|
*/
|
||||||
public class PayApi extends BaseApi {
|
public class PayApi extends BaseApi {
|
||||||
private final TokenHolder tokenHolder;
|
private final TokenHolder tokenHolder;
|
||||||
private final WeixinAccount weixinAccount;
|
private final WeixinMpAccount weixinAccount;
|
||||||
|
|
||||||
public PayApi(TokenHolder tokenHolder) {
|
public PayApi(TokenHolder tokenHolder) {
|
||||||
this.tokenHolder = tokenHolder;
|
this.tokenHolder = tokenHolder;
|
||||||
this.weixinAccount = tokenHolder.getAccount();
|
this.weixinAccount = (WeixinMpAccount) tokenHolder.getAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,7 +101,7 @@ public class PayApi extends BaseApi {
|
|||||||
Token token = tokenHolder.getToken();
|
Token token = tokenHolder.getToken();
|
||||||
|
|
||||||
Map<String, String> param = new HashMap<String, String>();
|
Map<String, String> param = new HashMap<String, String>();
|
||||||
param.put("appid", weixinAccount.getAppId());
|
param.put("appid", weixinAccount.getId());
|
||||||
param.put("appkey", weixinAccount.getPaySignKey());
|
param.put("appkey", weixinAccount.getPaySignKey());
|
||||||
param.put("openid", openId);
|
param.put("openid", openId);
|
||||||
param.put("transid", transid);
|
param.put("transid", transid);
|
||||||
@ -142,14 +142,14 @@ public class PayApi extends BaseApi {
|
|||||||
|
|
||||||
String timestamp = DateUtil.timestamp2string();
|
String timestamp = DateUtil.timestamp2string();
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("appid", weixinAccount.getAppId());
|
obj.put("appid", weixinAccount.getId());
|
||||||
obj.put("appkey", weixinAccount.getPaySignKey());
|
obj.put("appkey", weixinAccount.getPaySignKey());
|
||||||
obj.put("package", sb.toString());
|
obj.put("package", sb.toString());
|
||||||
obj.put("timestamp", timestamp);
|
obj.put("timestamp", timestamp);
|
||||||
String signature = PayUtil.paysignSha(obj, null);
|
String signature = PayUtil.paysignSha(obj, null);
|
||||||
|
|
||||||
obj.clear();
|
obj.clear();
|
||||||
obj.put("appid", weixinAccount.getAppId());
|
obj.put("appid", weixinAccount.getId());
|
||||||
obj.put("package", sb.toString());
|
obj.put("package", sb.toString());
|
||||||
obj.put("timestamp", timestamp);
|
obj.put("timestamp", timestamp);
|
||||||
obj.put("app_signature", signature);
|
obj.put("app_signature", signature);
|
||||||
@ -494,7 +494,7 @@ public class PayApi extends BaseApi {
|
|||||||
String _billDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
String _billDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
||||||
String bill_path = ConfigUtil.getValue("bill_path");
|
String bill_path = ConfigUtil.getValue("bill_path");
|
||||||
String fileName = String.format("%s_%s_%s.xls", _billDate, billType
|
String fileName = String.format("%s_%s_%s.xls", _billDate, billType
|
||||||
.name().toLowerCase(), weixinAccount.getAppId());
|
.name().toLowerCase(), weixinAccount.getId());
|
||||||
File file = new File(String.format("%s/%s", bill_path, fileName));
|
File file = new File(String.format("%s/%s", bill_path, fileName));
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return file;
|
return file;
|
||||||
@ -592,7 +592,7 @@ public class PayApi extends BaseApi {
|
|||||||
*/
|
*/
|
||||||
private Map<String, String> baseMapV3(IdQuery idQuery) {
|
private Map<String, String> baseMapV3(IdQuery idQuery) {
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
map.put("appid", weixinAccount.getAppId());
|
map.put("appid", weixinAccount.getId());
|
||||||
map.put("mch_id", weixinAccount.getMchId());
|
map.put("mch_id", weixinAccount.getMchId());
|
||||||
map.put("nonce_str", RandomUtil.generateString(16));
|
map.put("nonce_str", RandomUtil.generateString(16));
|
||||||
if (StringUtils.isNotBlank(weixinAccount.getDeviceInfo())) {
|
if (StringUtils.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.foxinmy.weixin4j.mp.api;
|
package com.foxinmy.weixin4j.mp.api;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.JsonResult;
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
import com.foxinmy.weixin4j.http.Response;
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
@ -39,9 +40,9 @@ public class TmplApi extends BaseApi {
|
|||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
Token token = tokenHolder.getToken();
|
Token token = tokenHolder.getToken();
|
||||||
String template_send_uri = getRequestUri("template_send_uri");
|
String template_send_uri = getRequestUri("template_send_uri");
|
||||||
|
String para = JSON.toJSONString(tplMessage);
|
||||||
Response response = request.post(
|
Response response = request.post(
|
||||||
String.format(template_send_uri, token.getAccessToken()),
|
String.format(template_send_uri, token.getAccessToken()), para);
|
||||||
tplMessage.toJson());
|
|
||||||
|
|
||||||
return response.getAsJsonResult();
|
return response.getAsJsonResult();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class UserApi extends BaseApi {
|
|||||||
WeixinAccount weixinAccount = tokenHolder.getAccount();
|
WeixinAccount weixinAccount = tokenHolder.getAccount();
|
||||||
String user_token_uri = getRequestUri("sns_user_token_uri");
|
String user_token_uri = getRequestUri("sns_user_token_uri");
|
||||||
Response response = request.get(String.format(user_token_uri,
|
Response response = request.get(String.format(user_token_uri,
|
||||||
weixinAccount.getAppId(), weixinAccount.getAppSecret(), code));
|
weixinAccount.getId(), weixinAccount.getSecret(), code));
|
||||||
|
|
||||||
return response.getAsObject(new TypeReference<OauthToken>() {
|
return response.getAsObject(new TypeReference<OauthToken>() {
|
||||||
});
|
});
|
||||||
|
|||||||
@ -55,11 +55,10 @@ public class Group implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 返回创建分组所需的json格式字符串
|
* 返回创建分组所需的json格式字符串
|
||||||
*
|
*
|
||||||
* @return {"group": {"id": 107, "name": "test"}}
|
* @return {"group": {"name": "test"}}
|
||||||
*/
|
*/
|
||||||
public String toCreateJson() {
|
public String toCreateJson() {
|
||||||
return String.format("{\"group\":{\"id\":%s,\"name\":\"%s\"}}", id,
|
return String.format("{\"group\":{\"name\":\"%s\"}}", name);
|
||||||
name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import java.io.Serializable;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.model.Gender;
|
||||||
import com.foxinmy.weixin4j.mp.type.FaceSize;
|
import com.foxinmy.weixin4j.mp.type.FaceSize;
|
||||||
import com.foxinmy.weixin4j.mp.type.Gender;
|
|
||||||
import com.foxinmy.weixin4j.mp.type.Lang;
|
import com.foxinmy.weixin4j.mp.type.Lang;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import java.io.Serializable;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.mp.type.ResponseType;
|
import com.foxinmy.weixin4j.mp.type.ResponseType;
|
||||||
|
import com.foxinmy.weixin4j.util.ClassUtil;
|
||||||
import com.foxinmy.weixin4j.xml.XStream;
|
import com.foxinmy.weixin4j.xml.XStream;
|
||||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||||
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
|
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
|
||||||
@ -22,6 +23,21 @@ public class BaseNotify implements Serializable {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 7190233634431087729L;
|
private static final long serialVersionUID = 7190233634431087729L;
|
||||||
|
|
||||||
|
private final static XStream jsonStream = new XStream(
|
||||||
|
new JsonHierarchicalStreamDriver() {
|
||||||
|
public HierarchicalStreamWriter createWriter(Writer writer) {
|
||||||
|
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
static {
|
||||||
|
Class<?>[] classes = ClassUtil
|
||||||
|
.getClasses(BaseNotify.class.getPackage())
|
||||||
|
.toArray(new Class[0]);
|
||||||
|
|
||||||
|
jsonStream.setMode(XStream.NO_REFERENCES);
|
||||||
|
jsonStream.autodetectAnnotations(true);
|
||||||
|
jsonStream.processAnnotations(classes);
|
||||||
|
}
|
||||||
private String touser;
|
private String touser;
|
||||||
private ResponseType msgtype;
|
private ResponseType msgtype;
|
||||||
|
|
||||||
@ -56,15 +72,7 @@ public class BaseNotify implements Serializable {
|
|||||||
* @return {"touser": "to","msgtype": "text","text": {"content": "123"}}
|
* @return {"touser": "to","msgtype": "text","text": {"content": "123"}}
|
||||||
*/
|
*/
|
||||||
public String toJson() {
|
public String toJson() {
|
||||||
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
|
return jsonStream.toXML(this);
|
||||||
public HierarchicalStreamWriter createWriter(Writer writer) {
|
|
||||||
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
xstream.setMode(XStream.NO_REFERENCES);
|
|
||||||
xstream.autodetectAnnotations(true);
|
|
||||||
xstream.processAnnotations(this.getClass());
|
|
||||||
return xstream.toXML(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
|
|
||||||
@ -33,10 +33,10 @@ public class MicroPayPackage extends PayPackage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MicroPayPackage(WeixinAccount weixinAccount, String body,
|
public MicroPayPackage(WeixinMpAccount weixinAccount, String body,
|
||||||
String attach, String out_trade_no, double total_fee,
|
String attach, String out_trade_no, double total_fee,
|
||||||
String spbill_create_ip, String auth_code) {
|
String spbill_create_ip, String auth_code) {
|
||||||
this(weixinAccount.getAppId(), weixinAccount.getMchId(), weixinAccount
|
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
|
||||||
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
||||||
out_trade_no, total_fee, spbill_create_ip, null, null, null,
|
out_trade_no, total_fee, spbill_create_ip, null, null, null,
|
||||||
auth_code);
|
auth_code);
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.foxinmy.weixin4j.exception.PayException;
|
import com.foxinmy.weixin4j.exception.PayException;
|
||||||
import com.foxinmy.weixin4j.http.XmlResult;
|
import com.foxinmy.weixin4j.http.XmlResult;
|
||||||
import com.foxinmy.weixin4j.model.Consts;
|
import com.foxinmy.weixin4j.model.Consts;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayNotifyV2;
|
import com.foxinmy.weixin4j.mp.payment.v2.NativePayNotifyV2;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.PayFeedback;
|
import com.foxinmy.weixin4j.mp.payment.v2.PayFeedback;
|
||||||
@ -46,7 +46,7 @@ public class PayAction {
|
|||||||
public JSONObject jsPay() {
|
public JSONObject jsPay() {
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
PayPackage payPackage = null;
|
PayPackage payPackage = null;
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
// V3 支付
|
// V3 支付
|
||||||
payPackage = new PayPackageV3(weixinAccount, "用户openid", "商品描述",
|
payPackage = new PayPackageV3(weixinAccount, "用户openid", "商品描述",
|
||||||
"系统内部订单号", 1d, "IP地址", TradeType.JSAPI);
|
"系统内部订单号", 1d, "IP地址", TradeType.JSAPI);
|
||||||
@ -111,7 +111,7 @@ public class PayAction {
|
|||||||
log.info("jspay_notify_orderinfo,{}", objMap);
|
log.info("jspay_notify_orderinfo,{}", objMap);
|
||||||
JsPayNotify payNotify = XStream.get(inputStream, JsPayNotify.class);
|
JsPayNotify payNotify = XStream.get(inputStream, JsPayNotify.class);
|
||||||
log.info("jspay_notify_userinfo,{}", payNotify);
|
log.info("jspay_notify_userinfo,{}", payNotify);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
// 验证财付通签名
|
// 验证财付通签名
|
||||||
String sign = objMap.get("sign");
|
String sign = objMap.get("sign");
|
||||||
objMap.remove("sign");
|
objMap.remove("sign");
|
||||||
@ -153,7 +153,7 @@ public class PayAction {
|
|||||||
log.info("jaapi_notify_order_info:", order);
|
log.info("jaapi_notify_order_info:", order);
|
||||||
String sign = order.getSign();
|
String sign = order.getSign();
|
||||||
order.setSign(null);
|
order.setSign(null);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String valid_sign = PayUtil.paysignMd5(order,
|
String valid_sign = PayUtil.paysignMd5(order,
|
||||||
weixinAccount.getPaySignKey());
|
weixinAccount.getPaySignKey());
|
||||||
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
||||||
@ -187,7 +187,7 @@ public class PayAction {
|
|||||||
NativePayNotifyV2 payNotify = XStream.get(inputStream,
|
NativePayNotifyV2 payNotify = XStream.get(inputStream,
|
||||||
NativePayNotifyV2.class);
|
NativePayNotifyV2.class);
|
||||||
log.info("native_pay_notify,{}", payNotify);
|
log.info("native_pay_notify,{}", payNotify);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String sign = payNotify.getPaySign();
|
String sign = payNotify.getPaySign();
|
||||||
payNotify.setPaySign(null);
|
payNotify.setPaySign(null);
|
||||||
payNotify.setSignType(null);
|
payNotify.setSignType(null);
|
||||||
@ -227,7 +227,7 @@ public class PayAction {
|
|||||||
NativePayNotifyV3.class);
|
NativePayNotifyV3.class);
|
||||||
String sign = payNotify.getSign();
|
String sign = payNotify.getSign();
|
||||||
payNotify.setSign(null);
|
payNotify.setSign(null);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String valid_sign = PayUtil.paysignMd5(payNotify,
|
String valid_sign = PayUtil.paysignMd5(payNotify,
|
||||||
weixinAccount.getPaySignKey());
|
weixinAccount.getPaySignKey());
|
||||||
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
||||||
@ -272,7 +272,7 @@ public class PayAction {
|
|||||||
public String warning(InputStream inputStream) {
|
public String warning(InputStream inputStream) {
|
||||||
PayWarn payWarn = XStream.get(inputStream, PayWarn.class);
|
PayWarn payWarn = XStream.get(inputStream, PayWarn.class);
|
||||||
log.info("pay_warning,{}", payWarn);
|
log.info("pay_warning,{}", payWarn);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String sign = payWarn.getPaySign();
|
String sign = payWarn.getPaySign();
|
||||||
payWarn.setPaySign(null);
|
payWarn.setPaySign(null);
|
||||||
payWarn.setSignType(null);
|
payWarn.setSignType(null);
|
||||||
@ -293,7 +293,7 @@ public class PayAction {
|
|||||||
public String feedback(InputStream inputStream) {
|
public String feedback(InputStream inputStream) {
|
||||||
PayFeedback feedback = XStream.get(inputStream, PayFeedback.class);
|
PayFeedback feedback = XStream.get(inputStream, PayFeedback.class);
|
||||||
log.info("pay_feedback_info:{}", feedback);
|
log.info("pay_feedback_info:{}", feedback);
|
||||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
// 验证微信签名
|
// 验证微信签名
|
||||||
Map<String, String> obj = new HashMap<String, String>();
|
Map<String, String> obj = new HashMap<String, String>();
|
||||||
obj.put("openid", feedback.getOpenId());
|
obj.put("openid", feedback.getOpenId());
|
||||||
|
|||||||
@ -13,7 +13,8 @@ import com.foxinmy.weixin4j.exception.PayException;
|
|||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||||
import com.foxinmy.weixin4j.http.Response;
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.Consts;
|
||||||
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.JsPayRequestV2;
|
import com.foxinmy.weixin4j.mp.payment.v2.JsPayRequestV2;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
||||||
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
|
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
|
||||||
@ -37,11 +38,6 @@ import com.foxinmy.weixin4j.xml.XStream;
|
|||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class PayUtil {
|
public class PayUtil {
|
||||||
private static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
|
||||||
private static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay";
|
|
||||||
private static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s";
|
|
||||||
private static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成JSAPI字符串
|
* 生成JSAPI字符串
|
||||||
*
|
*
|
||||||
@ -53,7 +49,7 @@ public class PayUtil {
|
|||||||
* @throws PayException
|
* @throws PayException
|
||||||
*/
|
*/
|
||||||
public static String createPayJsRequestJson(PayPackage payPackage,
|
public static String createPayJsRequestJson(PayPackage payPackage,
|
||||||
WeixinAccount weixinAccount) throws PayException {
|
WeixinMpAccount weixinAccount) throws PayException {
|
||||||
if (payPackage instanceof PayPackageV2) {
|
if (payPackage instanceof PayPackageV2) {
|
||||||
return createPayJsRequestJsonV2((PayPackageV2) payPackage,
|
return createPayJsRequestJsonV2((PayPackageV2) payPackage,
|
||||||
weixinAccount);
|
weixinAccount);
|
||||||
@ -74,7 +70,7 @@ public class PayUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String createPayJsRequestJsonV2(PayPackageV2 payPackage,
|
public static String createPayJsRequestJsonV2(PayPackageV2 payPackage,
|
||||||
WeixinAccount weixinAccount) {
|
WeixinMpAccount weixinAccount) {
|
||||||
if (StringUtils.isBlank(payPackage.getPartner())) {
|
if (StringUtils.isBlank(payPackage.getPartner())) {
|
||||||
payPackage.setPartner(weixinAccount.getPartnerId());
|
payPackage.setPartner(weixinAccount.getPartnerId());
|
||||||
}
|
}
|
||||||
@ -101,7 +97,7 @@ public class PayUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String createPayJsRequestJsonV2(String body, String orderNo,
|
public static String createPayJsRequestJsonV2(String body, String orderNo,
|
||||||
double orderFee, String ip, WeixinAccount weixinAccount) {
|
double orderFee, String ip, WeixinMpAccount weixinAccount) {
|
||||||
PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee, ip);
|
PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee, ip);
|
||||||
payPackage.setPartner(weixinAccount.getPartnerId());
|
payPackage.setPartner(weixinAccount.getPartnerId());
|
||||||
return createPayJsRequestJsonV2(payPackage, weixinAccount);
|
return createPayJsRequestJsonV2(payPackage, weixinAccount);
|
||||||
@ -168,7 +164,7 @@ public class PayUtil {
|
|||||||
*/
|
*/
|
||||||
public static String createPayJsRequestJsonV3(String openId, String body,
|
public static String createPayJsRequestJsonV3(String openId, String body,
|
||||||
String orderNo, double orderFee, String ip, String notifyUrl,
|
String orderNo, double orderFee, String ip, String notifyUrl,
|
||||||
WeixinAccount weixinAccount) throws PayException {
|
WeixinMpAccount weixinAccount) throws PayException {
|
||||||
PayPackageV3 payPackage = new PayPackageV3(weixinAccount, openId, body,
|
PayPackageV3 payPackage = new PayPackageV3(weixinAccount, openId, body,
|
||||||
orderNo, orderFee, ip, TradeType.JSAPI);
|
orderNo, orderFee, ip, TradeType.JSAPI);
|
||||||
payPackage.setNotify_url(notifyUrl);
|
payPackage.setNotify_url(notifyUrl);
|
||||||
@ -186,7 +182,7 @@ public class PayUtil {
|
|||||||
* @throws PayException
|
* @throws PayException
|
||||||
*/
|
*/
|
||||||
public static String createPayJsRequestJsonV3(PayPackageV3 payPackage,
|
public static String createPayJsRequestJsonV3(PayPackageV3 payPackage,
|
||||||
WeixinAccount weixinAccount) throws PayException {
|
WeixinMpAccount weixinAccount) throws PayException {
|
||||||
String paySignKey = weixinAccount.getPaySignKey();
|
String paySignKey = weixinAccount.getPaySignKey();
|
||||||
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
||||||
PrePay prePay = createPrePay(payPackage);
|
PrePay prePay = createPrePay(payPackage);
|
||||||
@ -201,7 +197,7 @@ public class PayUtil {
|
|||||||
String payJsRequestXml = XStream.to(payPackage).replaceAll("__", "_");
|
String payJsRequestXml = XStream.to(payPackage).replaceAll("__", "_");
|
||||||
HttpRequest request = new HttpRequest();
|
HttpRequest request = new HttpRequest();
|
||||||
try {
|
try {
|
||||||
Response response = request.post(UNIFIEDORDER, payJsRequestXml);
|
Response response = request.post(Consts.UNIFIEDORDER, payJsRequestXml);
|
||||||
prePay = response.getAsObject(new TypeReference<PrePay>() {
|
prePay = response.getAsObject(new TypeReference<PrePay>() {
|
||||||
});
|
});
|
||||||
} catch (WeixinException e) {
|
} catch (WeixinException e) {
|
||||||
@ -263,17 +259,17 @@ public class PayUtil {
|
|||||||
* 与订单ID等价
|
* 与订单ID等价
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String createNativePayRequestURLV2(WeixinAccount weixinAccount,
|
public String createNativePayRequestURLV2(WeixinMpAccount weixinAccount,
|
||||||
String productId) {
|
String productId) {
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
String timestamp = DateUtil.timestamp2string();
|
String timestamp = DateUtil.timestamp2string();
|
||||||
String noncestr = RandomUtil.generateString(16);
|
String noncestr = RandomUtil.generateString(16);
|
||||||
map.put("appid", weixinAccount.getAppId());
|
map.put("appid", weixinAccount.getId());
|
||||||
map.put("timestamp", timestamp);
|
map.put("timestamp", timestamp);
|
||||||
map.put("noncestr", noncestr);
|
map.put("noncestr", noncestr);
|
||||||
map.put("productid", productId);
|
map.put("productid", productId);
|
||||||
String sign = paysignSha(map, weixinAccount.getPaySignKey());
|
String sign = paysignSha(map, weixinAccount.getPaySignKey());
|
||||||
return String.format(NATIVEURLV2, sign, weixinAccount.getAppId(),
|
return String.format(Consts.NATIVEURLV2, sign, weixinAccount.getId(),
|
||||||
productId, timestamp, noncestr);
|
productId, timestamp, noncestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,29 +282,29 @@ public class PayUtil {
|
|||||||
* 与订单ID等价
|
* 与订单ID等价
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String createNativePayRequestURLV3(WeixinAccount weixinAccount,
|
public String createNativePayRequestURLV3(WeixinMpAccount weixinAccount,
|
||||||
String productId) {
|
String productId) {
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
String timestamp = DateUtil.timestamp2string();
|
String timestamp = DateUtil.timestamp2string();
|
||||||
String noncestr = RandomUtil.generateString(16);
|
String noncestr = RandomUtil.generateString(16);
|
||||||
map.put("appid", weixinAccount.getAppId());
|
map.put("appid", weixinAccount.getId());
|
||||||
map.put("mch_id", weixinAccount.getMchId());
|
map.put("mch_id", weixinAccount.getMchId());
|
||||||
map.put("time_stamp", timestamp);
|
map.put("time_stamp", timestamp);
|
||||||
map.put("nonce_str", noncestr);
|
map.put("nonce_str", noncestr);
|
||||||
map.put("product_id", productId);
|
map.put("product_id", productId);
|
||||||
String sign = paysignMd5(map, weixinAccount.getPaySignKey());
|
String sign = paysignMd5(map, weixinAccount.getPaySignKey());
|
||||||
return String.format(NATIVEURLV3, sign, weixinAccount.getAppId(),
|
return String.format(Consts.NATIVEURLV3, sign, weixinAccount.getId(),
|
||||||
weixinAccount.getMchId(), productId, timestamp, noncestr);
|
weixinAccount.getMchId(), productId, timestamp, noncestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createNativePayRequestV2(WeixinAccount weixinAccount,
|
public static String createNativePayRequestV2(WeixinMpAccount weixinAccount,
|
||||||
PayPackageV2 payPackage) {
|
PayPackageV2 payPackage) {
|
||||||
NativePayResponseV2 payRequest = new NativePayResponseV2(weixinAccount,
|
NativePayResponseV2 payRequest = new NativePayResponseV2(weixinAccount,
|
||||||
payPackage);
|
payPackage);
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
String timestamp = DateUtil.timestamp2string();
|
String timestamp = DateUtil.timestamp2string();
|
||||||
String noncestr = RandomUtil.generateString(16);
|
String noncestr = RandomUtil.generateString(16);
|
||||||
map.put("appid", weixinAccount.getAppId());
|
map.put("appid", weixinAccount.getId());
|
||||||
map.put("timestamp", timestamp);
|
map.put("timestamp", timestamp);
|
||||||
map.put("noncestr", noncestr);
|
map.put("noncestr", noncestr);
|
||||||
map.put("package", payRequest.getPackageInfo());
|
map.put("package", payRequest.getPackageInfo());
|
||||||
@ -336,12 +332,12 @@ public class PayUtil {
|
|||||||
* @param weixinAccount
|
* @param weixinAccount
|
||||||
* 商户信息
|
* 商户信息
|
||||||
* @return 返回数据
|
* @return 返回数据
|
||||||
* @see {@link com.foxinmy.weixin4j.mp.payment.PayUtil#createMicroPay(MicroPayPackage, WeixinAccount)}
|
* @see {@link com.foxinmy.weixin4j.mp.payment.PayUtil#createMicroPay(MicroPayPackage, WeixinMpAccount)}
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay(
|
public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay(
|
||||||
String authCode, String body, String attach, String orderNo,
|
String authCode, String body, String attach, String orderNo,
|
||||||
double orderFee, String ip, WeixinAccount weixinAccount)
|
double orderFee, String ip, WeixinMpAccount weixinAccount)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
MicroPayPackage payPackage = new MicroPayPackage(weixinAccount, body,
|
MicroPayPackage payPackage = new MicroPayPackage(weixinAccount, body,
|
||||||
attach, orderNo, orderFee, ip, authCode);
|
attach, orderNo, orderFee, ip, authCode);
|
||||||
@ -359,13 +355,13 @@ public class PayUtil {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay(
|
public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay(
|
||||||
MicroPayPackage payPackage, WeixinAccount weixinAccount)
|
MicroPayPackage payPackage, WeixinMpAccount weixinAccount)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
|
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
|
||||||
payPackage.setSign(sign);
|
payPackage.setSign(sign);
|
||||||
String para = XStream.to(payPackage).replaceAll("__", "_");
|
String para = XStream.to(payPackage).replaceAll("__", "_");
|
||||||
HttpRequest request = new HttpRequest();
|
HttpRequest request = new HttpRequest();
|
||||||
Response response = request.post(MICROPAYURL, para);
|
Response response = request.post(Consts.MICROPAYURL, para);
|
||||||
return response
|
return response
|
||||||
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
|
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import java.beans.Transient;
|
|||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.payment.PayRequest;
|
import com.foxinmy.weixin4j.mp.payment.PayRequest;
|
||||||
import com.foxinmy.weixin4j.util.MapUtil;
|
import com.foxinmy.weixin4j.util.MapUtil;
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ public class JsPayRequestV2 extends PayRequest {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -5972173459255255197L;
|
private static final long serialVersionUID = -5972173459255255197L;
|
||||||
|
|
||||||
public JsPayRequestV2(WeixinAccount weixinAccount, PayPackageV2 payPackage) {
|
public JsPayRequestV2(WeixinMpAccount weixinAccount, PayPackageV2 payPackage) {
|
||||||
this.setAppId(weixinAccount.getAppId());
|
this.setAppId(weixinAccount.getId());
|
||||||
this.setPackageInfo(package2string(payPackage,
|
this.setPackageInfo(package2string(payPackage,
|
||||||
weixinAccount.getPartnerKey()));
|
weixinAccount.getPartnerKey()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +21,7 @@ public class NativePayResponseV2 extends JsPayRequestV2 {
|
|||||||
@XStreamAlias("RetErrMsg")
|
@XStreamAlias("RetErrMsg")
|
||||||
private String retMsg;
|
private String retMsg;
|
||||||
|
|
||||||
public NativePayResponseV2(WeixinAccount weixinAccount,
|
public NativePayResponseV2(WeixinMpAccount weixinAccount,
|
||||||
PayPackageV2 payPackage) {
|
PayPackageV2 payPackage) {
|
||||||
super(weixinAccount, payPackage);
|
super(weixinAccount, payPackage);
|
||||||
this.retCode = "0";
|
this.retCode = "0";
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.payment.PayPackage;
|
import com.foxinmy.weixin4j.mp.payment.PayPackage;
|
||||||
import com.foxinmy.weixin4j.mp.type.TradeType;
|
import com.foxinmy.weixin4j.mp.type.TradeType;
|
||||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||||
@ -38,17 +38,17 @@ public class PayPackageV3 extends PayPackage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PayPackageV3(WeixinAccount weixinAccount, String openId,
|
public PayPackageV3(WeixinMpAccount weixinAccount, String openId,
|
||||||
String body, String out_trade_no, double total_fee,
|
String body, String out_trade_no, double total_fee,
|
||||||
String spbill_create_ip, TradeType tradeType) {
|
String spbill_create_ip, TradeType tradeType) {
|
||||||
this(weixinAccount, openId, body, null, out_trade_no, total_fee,
|
this(weixinAccount, openId, body, null, out_trade_no, total_fee,
|
||||||
spbill_create_ip, null, tradeType);
|
spbill_create_ip, null, tradeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PayPackageV3(WeixinAccount weixinAccount, String openId,
|
public PayPackageV3(WeixinMpAccount weixinAccount, String openId,
|
||||||
String body, String attach, String out_trade_no, double total_fee,
|
String body, String attach, String out_trade_no, double total_fee,
|
||||||
String spbill_create_ip, String notify_url, TradeType tradeType) {
|
String spbill_create_ip, String notify_url, TradeType tradeType) {
|
||||||
this(weixinAccount.getAppId(), weixinAccount.getMchId(), weixinAccount
|
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
|
||||||
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
||||||
out_trade_no, total_fee, spbill_create_ip, null, null, null,
|
out_trade_no, total_fee, spbill_create_ip, null, null, null,
|
||||||
notify_url, tradeType, openId, null);
|
notify_url, tradeType, openId, null);
|
||||||
|
|||||||
@ -1,16 +1,11 @@
|
|||||||
package com.foxinmy.weixin4j.mp.response;
|
package com.foxinmy.weixin4j.mp.response;
|
||||||
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.BaseMsg;
|
import com.foxinmy.weixin4j.model.BaseMsg;
|
||||||
import com.foxinmy.weixin4j.mp.type.ResponseType;
|
import com.foxinmy.weixin4j.mp.type.ResponseType;
|
||||||
import com.foxinmy.weixin4j.msg.BaseMessage;
|
import com.foxinmy.weixin4j.msg.BaseMessage;
|
||||||
import com.foxinmy.weixin4j.util.ClassUtil;
|
import com.foxinmy.weixin4j.util.ClassUtil;
|
||||||
import com.foxinmy.weixin4j.xml.XStream;
|
import com.foxinmy.weixin4j.xml.XStream;
|
||||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
|
||||||
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
|
|
||||||
import com.thoughtworks.xstream.io.json.JsonWriter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应消息基类
|
* 响应消息基类
|
||||||
@ -28,26 +23,15 @@ public class BaseResponse extends BaseMsg {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 7761192742840031607L;
|
private static final long serialVersionUID = 7761192742840031607L;
|
||||||
protected final static XStream xmlStream = XStream.get();
|
protected final static XStream xmlStream = XStream.get();
|
||||||
private final static XStream jsonStream = new XStream(
|
|
||||||
new JsonHierarchicalStreamDriver() {
|
|
||||||
public HierarchicalStreamWriter createWriter(Writer writer) {
|
|
||||||
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@XStreamAlias("MsgType")
|
|
||||||
private ResponseType msgType; // 消息类型
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Class<?>[] classes = ClassUtil.getClasses(
|
Class<?>[] classes = ClassUtil.getClasses(
|
||||||
BaseResponse.class.getPackage()).toArray(new Class[0]);
|
BaseResponse.class.getPackage()).toArray(new Class[0]);
|
||||||
|
|
||||||
|
xmlStream.autodetectAnnotations(true);
|
||||||
xmlStream.processAnnotations(classes);
|
xmlStream.processAnnotations(classes);
|
||||||
|
|
||||||
jsonStream.setMode(XStream.NO_REFERENCES);
|
|
||||||
jsonStream.autodetectAnnotations(true);
|
|
||||||
jsonStream.processAnnotations(classes);
|
|
||||||
}
|
}
|
||||||
|
@XStreamAlias("MsgType")
|
||||||
|
private ResponseType msgType; // 消息类型
|
||||||
|
|
||||||
public BaseResponse(ResponseType msgType) {
|
public BaseResponse(ResponseType msgType) {
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
@ -59,7 +43,7 @@ public class BaseResponse extends BaseMsg {
|
|||||||
|
|
||||||
public BaseResponse(ResponseType msgType, String toUserName,
|
public BaseResponse(ResponseType msgType, String toUserName,
|
||||||
String fromUserName) {
|
String fromUserName) {
|
||||||
super(toUserName,fromUserName);
|
super(toUserName, fromUserName);
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -78,17 +62,6 @@ public class BaseResponse extends BaseMsg {
|
|||||||
* @return xml字符串
|
* @return xml字符串
|
||||||
*/
|
*/
|
||||||
public String toXml() {
|
public String toXml() {
|
||||||
Class<? extends BaseResponse> targetClass = msgType.getMessageClass();
|
|
||||||
xmlStream.alias("xml", targetClass);
|
|
||||||
return xmlStream.toXML(this);
|
return xmlStream.toXML(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息对象转换为微信服务器接受的json格式字符串
|
|
||||||
*
|
|
||||||
* @return json字符串
|
|
||||||
*/
|
|
||||||
public String toJson() {
|
|
||||||
return jsonStream.toXML(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
package com.foxinmy.weixin4j.mp.response;
|
package com.foxinmy.weixin4j.mp.response;
|
||||||
|
|
||||||
import java.beans.Transient;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板消息
|
* 模板消息
|
||||||
*
|
*
|
||||||
@ -115,10 +111,4 @@ public class TemplateMessage implements Serializable {
|
|||||||
+ template_id + ", url=" + url + ", topcolor=" + topcolor
|
+ template_id + ", url=" + url + ", topcolor=" + topcolor
|
||||||
+ ", data=" + data + "]";
|
+ ", data=" + data + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
public String toJson() {
|
|
||||||
return JSON.toJSONString(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
package com.foxinmy.weixin4j.mp.type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户性别
|
|
||||||
* @className Gender
|
|
||||||
* @author jy
|
|
||||||
* @date 2014年11月5日
|
|
||||||
* @since JDK 1.7
|
|
||||||
* @see
|
|
||||||
*/
|
|
||||||
public enum Gender {
|
|
||||||
male(1), female(2), unknown(0);
|
|
||||||
|
|
||||||
private int sex;
|
|
||||||
|
|
||||||
Gender(int sex) {
|
|
||||||
this.sex = sex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt() {
|
|
||||||
return sex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||||
# \u516c\u4f17\u53f7\u4fe1\u606f
|
# \u516c\u4f17\u53f7\u4fe1\u606f
|
||||||
account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
||||||
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
|
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
|
||||||
"encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u65f6\u9700\u8981\u586b\u5165",\
|
"encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u65f6\u9700\u8981\u586b\u5165",\
|
||||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
|
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import org.junit.Test;
|
|||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
||||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* token测试
|
* token测试
|
||||||
@ -22,7 +23,7 @@ public class TokenTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
tokenHolder = new FileTokenHolder();
|
tokenHolder = new FileTokenHolder(AccountType.MP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
weixin4j-mp-server
|
weixin4j-mp-server
|
||||||
==================
|
==================
|
||||||
|
|
||||||
微信netty服务
|
微信公众平台netty服务
|
||||||
------------
|
------------
|
||||||
|
|
||||||
功能列表
|
功能列表
|
||||||
@ -26,7 +26,7 @@ weixin4j-mp-server
|
|||||||
|
|
||||||
示例(properties中换行用右斜杆\\)
|
示例(properties中换行用右斜杆\\)
|
||||||
|
|
||||||
> account={"appId":"appId","appSecret":"appSecret",
|
> account={"id":"appId","secret":"appSecret",
|
||||||
> "token":"开放者的token 非必须","openId":"公众号的openid 非必须",
|
> "token":"开放者的token 非必须","openId":"公众号的openid 非必须",
|
||||||
> "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入",
|
> "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入",
|
||||||
> "mchId":"V3.x版本下的微信商户号",
|
> "mchId":"V3.x版本下的微信商户号",
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<artifactId>weixin4j-mp-server</artifactId>
|
<artifactId>weixin4j-mp-server</artifactId>
|
||||||
<name>weixin4j-mp-server</name>
|
<name>weixin4j-mp-server</name>
|
||||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-server</url>
|
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-mp-server</url>
|
||||||
<description>微信公众号服务</description>
|
<description>微信公众号服务</description>
|
||||||
<build>
|
<build>
|
||||||
<finalName>weixin-mp-server</finalName>
|
<finalName>weixin-mp-server</finalName>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import org.apache.http.Consts;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.model.HttpWeixinMessage;
|
import com.foxinmy.weixin4j.mp.model.HttpWeixinMessage;
|
||||||
import com.foxinmy.weixin4j.mp.type.EncryptType;
|
import com.foxinmy.weixin4j.mp.type.EncryptType;
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
@ -37,7 +37,7 @@ public class WeixinMessageDecoder extends
|
|||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, FullHttpRequest req,
|
protected void decode(ChannelHandlerContext ctx, FullHttpRequest req,
|
||||||
List<Object> out) throws Exception {
|
List<Object> out) throws Exception {
|
||||||
WeixinAccount account = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount mpAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String xmlContent = req.content().toString(Consts.UTF_8);
|
String xmlContent = req.content().toString(Consts.UTF_8);
|
||||||
HttpWeixinMessage message = new HttpWeixinMessage();
|
HttpWeixinMessage message = new HttpWeixinMessage();
|
||||||
if (StringUtils.isNotBlank(xmlContent)) {
|
if (StringUtils.isNotBlank(xmlContent)) {
|
||||||
@ -72,10 +72,10 @@ public class WeixinMessageDecoder extends
|
|||||||
|
|
||||||
message.setXmlContent(xmlContent);
|
message.setXmlContent(xmlContent);
|
||||||
if (message.getEncryptType() == EncryptType.AES) {
|
if (message.getEncryptType() == EncryptType.AES) {
|
||||||
message.setXmlContent(MessageUtil.aesDecrypt(account.getAppId(),
|
message.setXmlContent(MessageUtil.aesDecrypt(mpAccount.getId(),
|
||||||
account.getEncodingAesKey(), message.getEncryptContent()));
|
mpAccount.getEncodingAesKey(), message.getEncryptContent()));
|
||||||
}
|
}
|
||||||
message.setToken(account.getToken());
|
message.setToken(mpAccount.getToken());
|
||||||
out.add(message);
|
out.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import java.util.Map;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||||
import com.foxinmy.weixin4j.mp.response.BaseResponse;
|
import com.foxinmy.weixin4j.mp.response.BaseResponse;
|
||||||
import com.foxinmy.weixin4j.mp.util.HttpUtil;
|
import com.foxinmy.weixin4j.mp.util.HttpUtil;
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
@ -45,13 +45,13 @@ public class WeixinMessageEncoder extends MessageToMessageEncoder<BaseResponse>
|
|||||||
@Override
|
@Override
|
||||||
protected void encode(ChannelHandlerContext ctx, BaseResponse response,
|
protected void encode(ChannelHandlerContext ctx, BaseResponse response,
|
||||||
List<Object> out) throws Exception {
|
List<Object> out) throws Exception {
|
||||||
WeixinAccount account = ConfigUtil.getWeixinAccount();
|
WeixinMpAccount mpAccount = ConfigUtil.getWeixinMpAccount();
|
||||||
String xmlContent = response.toXml();
|
String xmlContent = response.toXml();
|
||||||
String nonce = RandomUtil.generateString(32);
|
String nonce = RandomUtil.generateString(32);
|
||||||
String timestamp = DateUtil.timestamp2string();
|
String timestamp = DateUtil.timestamp2string();
|
||||||
String encrtypt = MessageUtil.aesEncrypt(account.getAppId(),
|
String encrtypt = MessageUtil.aesEncrypt(mpAccount.getId(),
|
||||||
account.getEncodingAesKey(), xmlContent);
|
mpAccount.getEncodingAesKey(), xmlContent);
|
||||||
String msgSignature = MessageUtil.signature(account.getToken(), nonce,
|
String msgSignature = MessageUtil.signature(mpAccount.getToken(), nonce,
|
||||||
timestamp, encrtypt);
|
timestamp, encrtypt);
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
map.put("Encrypt", encrtypt);
|
map.put("Encrypt", encrtypt);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
# \u516c\u4f17\u53f7\u4fe1\u606f
|
# \u516c\u4f17\u53f7\u4fe1\u606f
|
||||||
account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
||||||
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
|
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
|
||||||
"encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u9700\u8981\u586b\u5165",\
|
"encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u9700\u8981\u586b\u5165",\
|
||||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
|
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
|
||||||
|
|||||||
@ -1,17 +1,27 @@
|
|||||||
weixin4j-qy
|
weixin4j-qy
|
||||||
===========
|
===========
|
||||||
|
|
||||||
@(weixin4j)[企业号]
|
[微信企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包
|
||||||
|
|
||||||
微信[企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
|
|
||||||
功能列表
|
功能列表
|
||||||
-------
|
-------
|
||||||
|
* **weixin4j-qy-api**
|
||||||
|
|
||||||
如何使用
|
+ DepartApi `部门管理API`
|
||||||
--------
|
|
||||||
|
+ UserApi `成员管理API`
|
||||||
|
|
||||||
|
+ TagApi `标签管理API`
|
||||||
|
|
||||||
更新LOG
|
更新LOG
|
||||||
-------
|
-------
|
||||||
|
* 2014-11-19
|
||||||
|
|
||||||
|
+ 得到`weixin4j-qy-api`和`weixin4j-qy-server`工程
|
||||||
|
|
||||||
|
+ **weixin4j-qy-api**: 新增部门管理接口
|
||||||
|
|
||||||
|
+ **weixin4j-qy-api**: 新增用户管理接口
|
||||||
|
|
||||||
|
+ **weixin4j-qy-api**: 新增标签管理接口
|
||||||
|
|||||||
@ -10,6 +10,18 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<artifactId>weixin4j-qy</artifactId>
|
<artifactId>weixin4j-qy</artifactId>
|
||||||
<name>weixin4j-qy</name>
|
<name>weixin4j-qy</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy</url>
|
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy</url>
|
||||||
<description>微信企业号工具包</description>
|
<description>微信企业号工具包</description>
|
||||||
|
<modules>
|
||||||
|
<module>weixin4j-qy-api</module>
|
||||||
|
<module>weixin4j-qy-server</module>
|
||||||
|
</modules>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.foxinmy.weixin4j</groupId>
|
||||||
|
<artifactId>weixin4j-base</artifactId>
|
||||||
|
<version>${weixin4j.base.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
28
weixin4j-qy/weixin4j-qy-api/.gitignore
vendored
Normal file
28
weixin4j-qy/weixin4j-qy-api/.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# eclipse ignore
|
||||||
|
*.settings/*
|
||||||
|
/.project
|
||||||
|
/.classpath
|
||||||
|
/.tomcatplugin
|
||||||
|
|
||||||
|
# maven ignore
|
||||||
|
target/*
|
||||||
|
|
||||||
|
# other ignore
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
Thumbs.db
|
||||||
|
/target/
|
||||||
|
.DS_Store
|
||||||
56
weixin4j-qy/weixin4j-qy-api/README.md
Normal file
56
weixin4j-qy/weixin4j-qy-api/README.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
weixin4j-qy-api
|
||||||
|
===============
|
||||||
|
|
||||||
|
[微信企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包
|
||||||
|
---------------------------------------------------------------
|
||||||
|
|
||||||
|
功能列表
|
||||||
|
-------
|
||||||
|
|
||||||
|
* DepartApi `部门管理API`
|
||||||
|
|
||||||
|
* UserApi `成员管理API`
|
||||||
|
|
||||||
|
* TagApi `标签管理API`
|
||||||
|
|
||||||
|
如何使用
|
||||||
|
--------
|
||||||
|
1.API工程可以单独打包到其他项目中使用,需新增或拷贝`weixin.properties`文件到项目的`classpath`中
|
||||||
|
|
||||||
|
weixin.properties说明
|
||||||
|
|
||||||
|
| 属性名 | 说明 |
|
||||||
|
| :---------- | :-------------- |
|
||||||
|
| account | 微信企业号信息 `json格式` |
|
||||||
|
| token_path | 使用FileTokenHolder时token保存的物理路径 |
|
||||||
|
|
||||||
|
示例(properties中换行用右斜杆\\)
|
||||||
|
|
||||||
|
> account={"id":"corpid","secret":"corpsecret",
|
||||||
|
> "token":"开放者的token 非必须",
|
||||||
|
> "encodingAesKey":"AES加密密钥"}
|
||||||
|
> token_path=/tmp/weixin/token <br/>
|
||||||
|
|
||||||
|
2.实例化一个`WeixinProxy`对象,调用API
|
||||||
|
|
||||||
|
WeixinProxy weixinProxy = new WeixinProxy();
|
||||||
|
// weixinProxy = new WeixinProxy(corpid,corpsecret);
|
||||||
|
// weixinProxy = new WeixinProxy(weixinAccount);
|
||||||
|
weixinProxy.getUser(userid);
|
||||||
|
|
||||||
|
3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`.
|
||||||
|
|
||||||
|
WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder());
|
||||||
|
// weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount));
|
||||||
|
|
||||||
|
4.`mvn package`.
|
||||||
|
|
||||||
|
更新LOG
|
||||||
|
-------
|
||||||
|
* 2014-11-19
|
||||||
|
|
||||||
|
+ 新增`部门管理`接口
|
||||||
|
|
||||||
|
+ 新增`用户管理`接口
|
||||||
|
|
||||||
|
+ 新增`标签管理`接口
|
||||||
24
weixin4j-qy/weixin4j-qy-api/pom.xml
Normal file
24
weixin4j-qy/weixin4j-qy-api/pom.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.foxinmy.weixin4j</groupId>
|
||||||
|
<artifactId>weixin4j-qy</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>weixin4j-qy-api</artifactId>
|
||||||
|
<name>weixin4j-qy-api</name>
|
||||||
|
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy/weixin4j-qy-api</url>
|
||||||
|
<description>微信企业号API</description>
|
||||||
|
<build>
|
||||||
|
<finalName>weixin4j-qy-api</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
31
weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml
Normal file
31
weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||||
|
<id>full</id>
|
||||||
|
<formats>
|
||||||
|
<format>jar</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/classes</directory>
|
||||||
|
<outputDirectory>/</outputDirectory>
|
||||||
|
<includes>
|
||||||
|
<include>/**</include>
|
||||||
|
</includes>
|
||||||
|
<excludes>
|
||||||
|
<exclude>*.properties</exclude>
|
||||||
|
<exclude>*.xml</exclude>
|
||||||
|
</excludes>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
<dependencySets>
|
||||||
|
<dependencySet>
|
||||||
|
<unpack>true</unpack>
|
||||||
|
<includes>
|
||||||
|
<include>com.foxinmy.weixin4j:weixin4j-base</include>
|
||||||
|
</includes>
|
||||||
|
</dependencySet>
|
||||||
|
</dependencySets>
|
||||||
|
</assembly>
|
||||||
@ -0,0 +1,344 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.model.WeixinQyAccount;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.DepartApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.TagApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.UserApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.Department;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||||
|
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信企业号接口实现
|
||||||
|
*
|
||||||
|
* @className WeixinProxy
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月19日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php">api文档</a>
|
||||||
|
*/
|
||||||
|
public class WeixinProxy {
|
||||||
|
private final DepartApi departApi;
|
||||||
|
private final UserApi userApi;
|
||||||
|
private final TagApi tagApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认采用文件存放Token信息
|
||||||
|
*/
|
||||||
|
public WeixinProxy() {
|
||||||
|
this(new FileTokenHolder(AccountType.QY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* appid,appsecret
|
||||||
|
*
|
||||||
|
* @param appid
|
||||||
|
* @param appsecret
|
||||||
|
*/
|
||||||
|
public WeixinProxy(String corpid, String corpsecret) {
|
||||||
|
this(new WeixinQyAccount(corpid, corpsecret));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WeixinAccount对象
|
||||||
|
*
|
||||||
|
* @param weixinAccount
|
||||||
|
*/
|
||||||
|
public WeixinProxy(WeixinQyAccount weixinAccount) {
|
||||||
|
this(new FileTokenHolder(weixinAccount));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TokenHolder对象
|
||||||
|
*
|
||||||
|
* @param tokenHolder
|
||||||
|
*/
|
||||||
|
public WeixinProxy(TokenHolder tokenHolder) {
|
||||||
|
this.departApi = new DepartApi(tokenHolder);
|
||||||
|
this.userApi = new UserApi(tokenHolder);
|
||||||
|
this.tagApi = new TagApi(tokenHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门(根部门的parentid为1)
|
||||||
|
*
|
||||||
|
* @param depart
|
||||||
|
* 部门对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E5.88.9B.E5.BB.BA.E9.83.A8.E9.97.A8">创建部门说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.DepartApi
|
||||||
|
* @return 部门ID
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public int createDepart(Department depart) throws WeixinException {
|
||||||
|
return departApi.createDepart(depart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新部门(如果非必须的字段未指定 则不更新该字段之前的设置值)
|
||||||
|
*
|
||||||
|
* @param depart
|
||||||
|
* 部门对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E6.9B.B4.E6.96.B0.E9.83.A8.E9.97.A8">更新部门说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.DepartApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateDepart(Department depart) throws WeixinException {
|
||||||
|
return departApi.updateDepart(depart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询部门列表(以部门的order字段从小到大排列)
|
||||||
|
*
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E5.88.97.E8.A1.A8">获取部门列表</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.DepartApi
|
||||||
|
* @return 部门列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<Department> listDepart() throws WeixinException {
|
||||||
|
return departApi.listDepart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除部门(不能删除根部门;不能删除含有子部门、成员的部门)
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E5.88.A0.E9.99.A4.E9.83.A8.E9.97.A8">删除部门说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.DepartApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteDepart(int departId) throws WeixinException {
|
||||||
|
return departApi.deleteDepart(departId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建成员
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* 成员对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E5.88.9B.E5.BB.BA.E6.88.90.E5.91.98">创建成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult createUser(User user) throws WeixinException {
|
||||||
|
return userApi.createUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值)
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* 成员对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E6.9B.B4.E6.96.B0.E6.88.90.E5.91.98">更新成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateUser(User user) throws WeixinException {
|
||||||
|
return userApi.updateUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取成员
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* 成员唯一ID
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E8.8E.B7.E5.8F.96.E6.88.90.E5.91.98">获取成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 成员对象
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public User getUser(String userid) throws WeixinException {
|
||||||
|
return userApi.getUser(userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门成员
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID 必须
|
||||||
|
* @param fetchChild
|
||||||
|
* 是否递归获取子部门下面的成员 非必须
|
||||||
|
* @param userStatus
|
||||||
|
* 成员状态 status可叠加 非必须
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98">获取部门成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> listUser(int departId, boolean fetchChild,
|
||||||
|
UserStatus userStatus) throws WeixinException {
|
||||||
|
return userApi.listUser(departId, fetchChild, userStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门下所有状态成员(不进行递归)
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID
|
||||||
|
* @see {@link com.foxinmy.weixin4j.qy.WeixinProxy#listUser(int, boolean,UserStatus)}
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> listUser(int departId) throws WeixinException {
|
||||||
|
return userApi.listUser(departId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除成员
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E5.88.A0.E9.99.A4.E6.88.90.E5.91.98">删除成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.UserApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteUser(String userid) throws WeixinException {
|
||||||
|
return userApi.deleteUser(userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建标签(创建的标签属于管理组;默认为未加锁状态)
|
||||||
|
*
|
||||||
|
* @param tagName
|
||||||
|
* 标签名称
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.9B.E5.BB.BA.E6.A0.87.E7.AD.BE">创建标签说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 标签ID
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public int createTag(String tagName) throws WeixinException {
|
||||||
|
return tagApi.createTag(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新标签(管理组必须是指定标签的创建者)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param tagName
|
||||||
|
* 标签名称
|
||||||
|
* @see <a href=
|
||||||
|
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E6.9B.B4.E6.96.B0.E6.A0.87.E7.AD.BE.E5.90.8D.E5.AD.97"
|
||||||
|
* >更新标签说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateTag(int tagId, String tagName)
|
||||||
|
throws WeixinException {
|
||||||
|
return tagApi.updateTag(tagId, tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标签(管理组必须是指定标签的创建者 并且标签的成员列表为空)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @return 处理结果
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.A0.E9.99.A4.E6.A0.87.E7.AD.BE">删除标签说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteTag(int tagId) throws WeixinException {
|
||||||
|
return tagApi.deleteTag(tagId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签列表
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E8.8E.B7.E5.8F.96.E6.A0.87.E7.AD.BE.E5.88.97.E8.A1.A8">获取标签列表说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 标签列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JSONArray listTag() throws WeixinException {
|
||||||
|
return tagApi.listTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签成员(管理组须拥有“获取标签成员”的接口权限,标签须对管理组可见;返回列表仅包含管理组管辖范围的成员)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E8.8E.B7.E5.8F.96.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">获取标签成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> getTagUsers(int tagId) throws WeixinException {
|
||||||
|
return tagApi.getTagUsers(tagId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)<br>
|
||||||
|
* <font color="red">若部分userid非法,则在text中体现</font>
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param userIds
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.A2.9E.E5.8A.A0.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">新增标签成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult addTagUsers(int tagId, List<String> userIds)
|
||||||
|
throws WeixinException {
|
||||||
|
return tagApi.addTagUsers(tagId, userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)<br>
|
||||||
|
* <font color="red">若部分userid非法,则在text中体现</font>
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param userIds
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.A0.E9.99.A4.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">删除标签成员说明</a>
|
||||||
|
* @see com.foxinmy.weixin4j.qy.api.TagApi
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteTagUsers(int tagId, List<String> userIds)
|
||||||
|
throws WeixinException {
|
||||||
|
return tagApi.deleteTagUsers(tagId, userIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.api;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||||
|
import com.foxinmy.weixin4j.xml.Map2ObjectConverter;
|
||||||
|
import com.foxinmy.weixin4j.xml.XStream;
|
||||||
|
import com.thoughtworks.xstream.core.ClassLoaderReference;
|
||||||
|
import com.thoughtworks.xstream.mapper.DefaultMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @className BaseApi
|
||||||
|
* @author jy.hu
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php">api文档</a>
|
||||||
|
*/
|
||||||
|
public class BaseApi {
|
||||||
|
protected final HttpRequest request = new HttpRequest();
|
||||||
|
protected final static XStream mapXstream = XStream.get();
|
||||||
|
private final static ResourceBundle weixinBundle;
|
||||||
|
static {
|
||||||
|
weixinBundle = ResourceBundle
|
||||||
|
.getBundle("com/foxinmy/weixin4j/qy/api/weixin");
|
||||||
|
mapXstream.alias("xml", Map.class);
|
||||||
|
mapXstream.registerConverter(new Map2ObjectConverter(new DefaultMapper(
|
||||||
|
new ClassLoaderReference(XStream.class.getClassLoader()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String map2xml(Map<?, ?> map) {
|
||||||
|
return mapXstream.toXML(map).replaceAll("__", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected Map<String, String> xml2map(String xml) {
|
||||||
|
return mapXstream.fromXML(xml, Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getRequestUri(String key) {
|
||||||
|
String url = weixinBundle.getString(key);
|
||||||
|
Pattern p = Pattern.compile("(\\{[^\\}]*\\})");
|
||||||
|
Matcher m = p.matcher(url);
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
String sub = null;
|
||||||
|
while (m.find()) {
|
||||||
|
sub = m.group();
|
||||||
|
m.appendReplacement(sb,
|
||||||
|
getRequestUri(sub.substring(1, sub.length() - 1)));
|
||||||
|
}
|
||||||
|
m.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.Department;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门API
|
||||||
|
*
|
||||||
|
* @className DepartApi
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8">管理部门说明</a>
|
||||||
|
*/
|
||||||
|
public class DepartApi extends BaseApi {
|
||||||
|
private final TokenHolder tokenHolder;
|
||||||
|
|
||||||
|
public DepartApi(TokenHolder tokenHolder) {
|
||||||
|
this.tokenHolder = tokenHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门(根部门的parentid为1)
|
||||||
|
*
|
||||||
|
* @param depart
|
||||||
|
* 部门对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E5.88.9B.E5.BB.BA.E9.83.A8.E9.97.A8">创建部门说明</a>
|
||||||
|
* @return 部门ID
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public int createDepart(Department depart) throws WeixinException {
|
||||||
|
String department_create_uri = getRequestUri("department_create_uri");
|
||||||
|
JSONObject obj = (JSONObject) JSON.toJSON(depart);
|
||||||
|
obj.remove("id");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(
|
||||||
|
String.format(department_create_uri, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
return response.getAsJson().getIntValue("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新部门(如果非必须的字段未指定 则不更新该字段之前的设置值)
|
||||||
|
*
|
||||||
|
* @param depart
|
||||||
|
* 部门对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E6.9B.B4.E6.96.B0.E9.83.A8.E9.97.A8">更新部门说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateDepart(Department depart) throws WeixinException {
|
||||||
|
String department_update_uri = getRequestUri("department_update_uri");
|
||||||
|
JSONObject obj = (JSONObject) JSON.toJSON(depart);
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(
|
||||||
|
String.format(department_update_uri, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询部门列表(以部门的order字段从小到大排列)
|
||||||
|
*
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.Department
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E5.88.97.E8.A1.A8">获取部门列表</a>
|
||||||
|
* @return 部门列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<Department> listDepart() throws WeixinException {
|
||||||
|
String department_list_uri = getRequestUri("department_list_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(department_list_uri,
|
||||||
|
token.getAccessToken()));
|
||||||
|
return JSON.parseArray(response.getAsJson().getString("department"),
|
||||||
|
Department.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除部门(不能删除根部门;不能删除含有子部门、成员的部门)
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E5.88.A0.E9.99.A4.E9.83.A8.E9.97.A8">删除部门说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteDepart(int departId) throws WeixinException {
|
||||||
|
String department_delete_uri = getRequestUri("department_delete_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(department_delete_uri,
|
||||||
|
token.getAccessToken(), departId));
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签API
|
||||||
|
*
|
||||||
|
* @className TagApi
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月19日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE">管理标签</a>
|
||||||
|
*/
|
||||||
|
public class TagApi extends BaseApi {
|
||||||
|
private final TokenHolder tokenHolder;
|
||||||
|
|
||||||
|
public TagApi(TokenHolder tokenHolder) {
|
||||||
|
this.tokenHolder = tokenHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建标签(创建的标签属于管理组;默认为未加锁状态)
|
||||||
|
*
|
||||||
|
* @param tagName
|
||||||
|
* 标签名称
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.9B.E5.BB.BA.E6.A0.87.E7.AD.BE">创建标签说明</a>
|
||||||
|
* @return 标签ID
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public int createTag(String tagName) throws WeixinException {
|
||||||
|
String tag_create_uri = getRequestUri("tag_create_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(
|
||||||
|
String.format(tag_create_uri, token.getAccessToken()),
|
||||||
|
String.format("{\"tagname\":\"%s\"}", tagName));
|
||||||
|
return response.getAsJson().getIntValue("tagid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新标签(管理组必须是指定标签的创建者)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param tagName
|
||||||
|
* 标签名称
|
||||||
|
* @see <a href=
|
||||||
|
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E6.9B.B4.E6.96.B0.E6.A0.87.E7.AD.BE.E5.90.8D.E5.AD.97"
|
||||||
|
* >更新标签说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateTag(int tagId, String tagName)
|
||||||
|
throws WeixinException {
|
||||||
|
String tag_update_uri = getRequestUri("tag_update_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(tag_update_uri,
|
||||||
|
token.getAccessToken()), String.format(
|
||||||
|
"{\"tagid\":%d,\"tagname\":\"%s\"}", tagId, tagName));
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标签(管理组必须是指定标签的创建者 并且标签的成员列表为空)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @return 处理结果
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.A0.E9.99.A4.E6.A0.87.E7.AD.BE">删除标签说明</a>
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteTag(int tagId) throws WeixinException {
|
||||||
|
String tag_delete_uri = getRequestUri("tag_delete_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(tag_delete_uri,
|
||||||
|
token.getAccessToken(), tagId));
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签列表
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E8.8E.B7.E5.8F.96.E6.A0.87.E7.AD.BE.E5.88.97.E8.A1.A8">获取标签列表说明</a>
|
||||||
|
* @return 标签列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JSONArray listTag() throws WeixinException {
|
||||||
|
String tag_list_uri = getRequestUri("tag_list_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(tag_list_uri,
|
||||||
|
token.getAccessToken()));
|
||||||
|
return response.getAsJson().getJSONArray("taglist");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签成员(管理组须拥有“获取标签成员”的接口权限,标签须对管理组可见;返回列表仅包含管理组管辖范围的成员)
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E8.8E.B7.E5.8F.96.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">获取标签成员说明</a>
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> getTagUsers(int tagId) throws WeixinException {
|
||||||
|
String tag_get_user_uri = getRequestUri("tag_get_user_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(tag_get_user_uri,
|
||||||
|
token.getAccessToken(), tagId));
|
||||||
|
return JSON.parseArray(response.getAsJson().getString("userlist"),
|
||||||
|
User.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)<br>
|
||||||
|
* <font color="red">若部分userid非法,则在text中体现</font>
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param userIds
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.A2.9E.E5.8A.A0.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">新增标签成员说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult addTagUsers(int tagId, List<String> userIds)
|
||||||
|
throws WeixinException {
|
||||||
|
String tag_add_user_uri = getRequestUri("tag_add_user_uri");
|
||||||
|
return excuteUsers(tag_add_user_uri, tagId, userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)<br>
|
||||||
|
* <font color="red">若部分userid非法,则在text中体现</font>
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param userIds
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E5.88.A0.E9.99.A4.E6.A0.87.E7.AD.BE.E6.88.90.E5.91.98">删除标签成员说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteTagUsers(int tagId, List<String> userIds)
|
||||||
|
throws WeixinException {
|
||||||
|
String tag_delete_user_uri = getRequestUri("tag_delete_user_uri");
|
||||||
|
return excuteUsers(tag_delete_user_uri, tagId, userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonResult excuteUsers(String uri, int tagId, List<String> userIds)
|
||||||
|
throws WeixinException {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("tagid", tagId);
|
||||||
|
obj.put("userlist", userIds);
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(
|
||||||
|
String.format(uri, token.getAccessToken()), obj.toJSONString());
|
||||||
|
obj = response.getAsJson();
|
||||||
|
JsonResult result = JSON.toJavaObject(obj, JsonResult.class);
|
||||||
|
result.setText(obj.getString("invalidlist"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,159 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.http.Response;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成员API
|
||||||
|
*
|
||||||
|
* @className UserApi
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月19日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98">管理成员说明</a>
|
||||||
|
*/
|
||||||
|
public class UserApi extends BaseApi {
|
||||||
|
private final TokenHolder tokenHolder;
|
||||||
|
|
||||||
|
public UserApi(TokenHolder tokenHolder) {
|
||||||
|
this.tokenHolder = tokenHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建成员
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* 成员对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E5.88.9B.E5.BB.BA.E6.88.90.E5.91.98">创建成员说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult createUser(User user) throws WeixinException {
|
||||||
|
String user_create_uri = getRequestUri("user_create_uri");
|
||||||
|
return excute(user_create_uri, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值)
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* 成员对象
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E6.9B.B4.E6.96.B0.E6.88.90.E5.91.98">更新成员说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult updateUser(User user) throws WeixinException {
|
||||||
|
String user_update_uri = getRequestUri("user_update_uri");
|
||||||
|
return excute(user_update_uri, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonResult excute(String uri, User user) throws WeixinException {
|
||||||
|
JSONObject obj = (JSONObject) JSON.toJSON(user);
|
||||||
|
Object extattr = obj.remove("extattr");
|
||||||
|
if (extattr != null) {
|
||||||
|
JSONObject attrs = new JSONObject();
|
||||||
|
attrs.put("attrs", extattr);
|
||||||
|
obj.put("extattr", attrs);
|
||||||
|
}
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(
|
||||||
|
String.format(uri, token.getAccessToken()), obj.toJSONString());
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取成员
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* 成员唯一ID
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E8.8E.B7.E5.8F.96.E6.88.90.E5.91.98">获取成员说明</a>
|
||||||
|
* @return 成员对象
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public User getUser(String userid) throws WeixinException {
|
||||||
|
String user_get_uri = getRequestUri("user_get_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(user_get_uri,
|
||||||
|
token.getAccessToken(), userid));
|
||||||
|
JSONObject obj = response.getAsJson();
|
||||||
|
Object attrs = obj.getJSONObject("extattr").remove("attrs");
|
||||||
|
if (attrs != null) {
|
||||||
|
obj.put("extattr", attrs);
|
||||||
|
}
|
||||||
|
return JSON.toJavaObject(obj, User.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门成员
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID 必须
|
||||||
|
* @param fetchChild
|
||||||
|
* 是否递归获取子部门下面的成员 非必须
|
||||||
|
* @param userStatus
|
||||||
|
* 成员状态 status可叠加 非必须
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.User
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98">获取部门成员说明</a>
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> listUser(int departId, boolean fetchChild,
|
||||||
|
UserStatus userStatus) throws WeixinException {
|
||||||
|
String user_list_uri = getRequestUri("user_list_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(user_list_uri,
|
||||||
|
token.getAccessToken(), departId, fetchChild ? 1 : 0,
|
||||||
|
userStatus.getVal()));
|
||||||
|
return JSON.parseArray(response.getAsJson().getString("userlist"),
|
||||||
|
User.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门下所有状态成员(不进行递归)
|
||||||
|
*
|
||||||
|
* @param departId
|
||||||
|
* 部门ID
|
||||||
|
* @see {@link com.foxinmy.weixin4j.qy.api.UserApi#listUser(int, boolean,UserStatus)}
|
||||||
|
* @return 成员列表
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<User> listUser(int departId) throws WeixinException {
|
||||||
|
return listUser(departId, false, UserStatus.BOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除成员
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* 成员ID
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E5.88.A0.E9.99.A4.E6.88.90.E5.91.98">删除成员说明</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult deleteUser(String userid) throws WeixinException {
|
||||||
|
String user_delete_uri = getRequestUri("user_delete_uri");
|
||||||
|
Token token = tokenHolder.getToken();
|
||||||
|
Response response = request.post(String.format(user_delete_uri,
|
||||||
|
token.getAccessToken(), userid));
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# api\u9996\u9875
|
||||||
|
# http://qydev.weixin.qq.com/wiki/index.php
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
api_base_url=https://qyapi.weixin.qq.com/cgi-bin
|
||||||
|
|
||||||
|
# \u521b\u5efa\u90e8\u95e8
|
||||||
|
department_create_uri={api_base_url}/department/create?access_token=%s
|
||||||
|
# \u66f4\u65b0\u90e8\u95e8
|
||||||
|
department_update_uri={api_base_url}/department/update?access_token=%s
|
||||||
|
# \u90e8\u95e8\u5217\u8868
|
||||||
|
department_list_uri={api_base_url}/department/list?access_token=%s
|
||||||
|
# \u5220\u9664\u90e8\u95e8
|
||||||
|
department_delete_uri={api_base_url}/department/delete?access_token=%s&id=%d
|
||||||
|
# \u521b\u5efa\u6210\u5458
|
||||||
|
user_create_uri={api_base_url}/user/create?access_token=%s
|
||||||
|
# \u66f4\u65b0\u6210\u5458
|
||||||
|
user_update_uri={api_base_url}/user/update?access_token=%s
|
||||||
|
# \u83b7\u53d6\u6210\u5458
|
||||||
|
user_get_uri={api_base_url}/user/get?access_token=%s&userid=%s
|
||||||
|
# \u83b7\u53d6\u90e8\u95e8\u6210\u5458
|
||||||
|
user_list_uri={api_base_url}/user/simplelist?access_token=%s&department_id=%d&fetch_child=%d&status=%d
|
||||||
|
# \u5220\u9664\u6210\u5458
|
||||||
|
user_delete_uri={api_base_url}/user/delete?access_token=%s&userid=%s
|
||||||
|
# \u521b\u5efa\u6807\u7b7e
|
||||||
|
tag_create_uri={api_base_url}/tag/create?access_token=%s
|
||||||
|
# \u66f4\u65b0\u6807\u7b7e
|
||||||
|
tag_update_uri={api_base_url}/tag/update?access_token=%s
|
||||||
|
# \u5220\u9664\u6807\u7b7e
|
||||||
|
tag_delete_uri={api_base_url}/tag/delete?access_token=%s&tagid=%d
|
||||||
|
# \u83b7\u53d6\u6807\u7b7e
|
||||||
|
tag_list_uri={api_base_url}/tag/list?access_token=%s
|
||||||
|
# \u83b7\u53d6\u6807\u7b7e\u6210\u5458
|
||||||
|
tag_get_user_uri={api_base_url}/tag/get?access_token=%s&tagid=%d
|
||||||
|
# \u6dfb\u52a0\u6807\u7b7e\u6210\u5458
|
||||||
|
tag_add_user_uri={api_base_url}/tag/addtagusers?access_token=%s
|
||||||
|
# \u5220\u9664\u6807\u7b7e\u6210\u5458
|
||||||
|
tag_delete_user_uri={api_base_url}/tag/deltagusers?access_token=%s
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门对象
|
||||||
|
*
|
||||||
|
* @className Department
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8">管理部门说明</a>
|
||||||
|
*/
|
||||||
|
public class Department implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2567893218591084288L;
|
||||||
|
private int id; // 部门ID
|
||||||
|
private String name; // 部门名称。长度限制为1~64个字符
|
||||||
|
private int parentid;// 父亲部门id。根部门id为1
|
||||||
|
private int order;// 在父部门中的次序。从1开始,数字越大排序越靠后
|
||||||
|
|
||||||
|
public Department() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Department(String name) {
|
||||||
|
this(name, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Department(String name, int parentid, int order) {
|
||||||
|
this.name = name;
|
||||||
|
this.parentid = parentid;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParentid() {
|
||||||
|
return parentid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentid(int parentid) {
|
||||||
|
this.parentid = parentid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrder(int order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Department [id=" + id + ", name=" + name + ", parentid="
|
||||||
|
+ parentid + ", order=" + order + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class NameValue implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -348620146718819093L;
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public NameValue() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameValue(String name, String value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NameValue [name=" + name + ", value=" + value + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,203 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import com.foxinmy.weixin4j.model.Gender;
|
||||||
|
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门成员对象
|
||||||
|
*
|
||||||
|
* @className User
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月19日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98">管理成员说明</a>
|
||||||
|
*/
|
||||||
|
public class User implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4747301605060801611L;
|
||||||
|
private String userid;// 是 员工UserID。对应管理端的帐号,企业内必须唯一。长度为1~64个字符
|
||||||
|
private String name;// 是 成员名称。长度为1~64个字符
|
||||||
|
private List<Integer> department;// 否 成员所属部门id列表。注意,每个部门的直属员工上限为1000个
|
||||||
|
private String position;// 否 职位信息。长度为0~64个字符
|
||||||
|
private String mobile;// 否 手机号码。企业内必须唯一,mobile/weixinid/email三者不能同时为空
|
||||||
|
private int gender;// 否 性别。gender=0表示男,=1表示女。默认gender=0
|
||||||
|
private String tel;// 否 办公电话。长度为0~64个字符
|
||||||
|
private String email;// 否 邮箱。长度为0~64个字符。企业内必须唯一
|
||||||
|
private String weixinid;// 否 微信号。企业内必须唯一
|
||||||
|
private String avatar;// 头像url。注:如果要获取小图将url最后的"/0"改成"/64"即可
|
||||||
|
private int status;// 关注状态: 1=已关注,2=已冻结,4=未关注
|
||||||
|
private List<NameValue> extattr;// 否 扩展属性。扩展属性需要在WEB管理端创建后才生效,否则忽略未知属性的赋值
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
this.extattr = new ArrayList<NameValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String userid, String name) {
|
||||||
|
this(userid, name, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mobile/weixinid/email三者不能同时为空
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* @param name
|
||||||
|
* @param tel
|
||||||
|
* @param email
|
||||||
|
* @param weixinid
|
||||||
|
*/
|
||||||
|
public User(String userid, String name, String tel, String email,
|
||||||
|
String weixinid) {
|
||||||
|
this.userid = userid;
|
||||||
|
this.name = name;
|
||||||
|
this.tel = tel;
|
||||||
|
this.email = email;
|
||||||
|
this.weixinid = weixinid;
|
||||||
|
this.extattr = new ArrayList<NameValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserid() {
|
||||||
|
return userid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserid(String userid) {
|
||||||
|
this.userid = userid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartment(List<Integer> department) {
|
||||||
|
this.department = department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartment(Integer... department) {
|
||||||
|
this.department = Arrays.asList(department);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(String position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMobile() {
|
||||||
|
return mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMobile(String mobile) {
|
||||||
|
this.mobile = mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGender() {
|
||||||
|
return gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
public Gender getEnumGender() {
|
||||||
|
if (gender == 0) {
|
||||||
|
return Gender.male;
|
||||||
|
} else if (gender == 1) {
|
||||||
|
return Gender.female;
|
||||||
|
} else {
|
||||||
|
return Gender.unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGender(int gender) {
|
||||||
|
this.gender = gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTel() {
|
||||||
|
return tel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTel(String tel) {
|
||||||
|
this.tel = tel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWeixinid() {
|
||||||
|
return weixinid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeixinid(String weixinid) {
|
||||||
|
this.weixinid = weixinid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
public String getAvatar() {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar(String avatar) {
|
||||||
|
this.avatar = avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
public UserStatus getStatus() {
|
||||||
|
for (UserStatus userStatus : UserStatus.values()) {
|
||||||
|
if (userStatus.getVal() == status) {
|
||||||
|
return userStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NameValue> getExtattr() {
|
||||||
|
return extattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtattr(List<NameValue> extattr) {
|
||||||
|
this.extattr = extattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtattr(NameValue... extattr) {
|
||||||
|
this.extattr = Arrays.asList(extattr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pushExattr(String name, String value) {
|
||||||
|
pushExattr(new NameValue(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pushExattr(NameValue nameValue) {
|
||||||
|
extattr.add(nameValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User [userid=" + userid + ", name=" + name + ", department="
|
||||||
|
+ department + ", position=" + position + ", mobile=" + mobile
|
||||||
|
+ ", gender=" + gender + ", tel=" + tel + ", email=" + email
|
||||||
|
+ ", weixinid=" + weixinid + ", avatar=" + avatar + ", status="
|
||||||
|
+ status + ", extattr=" + extattr + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成员状态
|
||||||
|
*
|
||||||
|
* @className UserStatus
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月19日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public enum UserStatus {
|
||||||
|
BOTH(0), // 0=全部
|
||||||
|
FOLLOW(1), // 1=已关注
|
||||||
|
FROZEN(2), // 2=已冻结
|
||||||
|
UNFOLLOW(4);// 4=未关注
|
||||||
|
private int val;
|
||||||
|
|
||||||
|
UserStatus(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVal() {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||||
|
# \u4f01\u4e1a\u53f7\u4fe1\u606f
|
||||||
|
account={"id":"wxd9d9fa581a07cefd","secret":"7tr6FXh2NORvqq1la9CVwxV0xZWGsRSgI6tfqd3-JFc9E2p7UukNNYeKoOTLe0Ru",\
|
||||||
|
"token":"gp2eGT5mIpngr",\
|
||||||
|
"encodingAesKey":"BRYfV4zPFUJb3v3MySNBg1ERKE3vyyMRoScu76vFySv"\
|
||||||
|
}
|
||||||
|
|
||||||
|
# \u4f7f\u7528FileTokenHolder\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||||
|
token_path=/tmp/weixin/token
|
||||||
|
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84
|
||||||
|
qr_path=/tmp/weixin/qr
|
||||||
|
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
|
||||||
|
media_path=/tmp/weixin/media
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.DepartApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.Department;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门API测试
|
||||||
|
*
|
||||||
|
* @className DepartTest
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class DepartTest extends TokenTest {
|
||||||
|
public DepartApi departApi;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
this.departApi = new DepartApi(tokenHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void create() throws WeixinException {
|
||||||
|
Department depart = new Department("苦逼组");
|
||||||
|
int id = departApi.createDepart(depart);
|
||||||
|
Assert.assertTrue(id > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void update() throws WeixinException {
|
||||||
|
Department depart = new Department("苦逼组111");
|
||||||
|
depart.setId(2);
|
||||||
|
JsonResult result = departApi.updateDepart(depart);
|
||||||
|
Assert.assertEquals("updated", result.getDesc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void list() throws WeixinException {
|
||||||
|
List<Department> list = departApi.listDepart();
|
||||||
|
Assert.assertFalse(list.isEmpty());
|
||||||
|
System.out.println(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void delete() throws WeixinException {
|
||||||
|
JsonResult result = departApi.deleteDepart(2);
|
||||||
|
Assert.assertEquals("deleted", result.getDesc());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.TagApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门API测试
|
||||||
|
*
|
||||||
|
* @className DepartTest
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class TagTest extends TokenTest {
|
||||||
|
public TagApi tagApi;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
this.tagApi = new TagApi(tokenHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void create() throws WeixinException {
|
||||||
|
int tagId = tagApi.createTag("coder");
|
||||||
|
Assert.assertTrue(tagId > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void update() throws WeixinException {
|
||||||
|
JsonResult result = tagApi.updateTag(1, "coder456");
|
||||||
|
Assert.assertEquals("updated", result.getDesc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getUsers() throws WeixinException {
|
||||||
|
List<User> listUser = tagApi.getTagUsers(1);
|
||||||
|
Assert.assertFalse(listUser.isEmpty());
|
||||||
|
System.out.println(listUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addUsers() throws WeixinException {
|
||||||
|
JsonResult result = tagApi.addTagUsers(1, Arrays.asList("jinyu"));
|
||||||
|
Assert.assertEquals("ok", result.getDesc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteUsers() throws WeixinException {
|
||||||
|
JsonResult result = tagApi.deleteTagUsers(1, Arrays.asList("jinyu"));
|
||||||
|
Assert.assertEquals("ok", result.getDesc());
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void list() throws WeixinException {
|
||||||
|
JSONArray tags = tagApi.listTag();
|
||||||
|
Assert.assertFalse(tags.isEmpty());
|
||||||
|
System.out.println(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void delete() throws WeixinException {
|
||||||
|
JsonResult result = tagApi.deleteTag(3);
|
||||||
|
Assert.assertEquals("deleted", result.getDesc());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.test;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
|
import com.foxinmy.weixin4j.type.AccountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token测试
|
||||||
|
*
|
||||||
|
* @className TokenTest
|
||||||
|
* @author jy.hu
|
||||||
|
* @date 2014年4月10日
|
||||||
|
* @since JDK 1.7
|
||||||
|
*/
|
||||||
|
public class TokenTest {
|
||||||
|
|
||||||
|
protected TokenHolder tokenHolder;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
tokenHolder = new FileTokenHolder(AccountType.QY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws WeixinException {
|
||||||
|
Assert.assertNotNull(tokenHolder.getToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.JsonResult;
|
||||||
|
import com.foxinmy.weixin4j.qy.api.UserApi;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门API测试
|
||||||
|
*
|
||||||
|
* @className DepartTest
|
||||||
|
* @author jy
|
||||||
|
* @date 2014年11月18日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class UserTest extends TokenTest {
|
||||||
|
public UserApi userApi;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
this.userApi = new UserApi(tokenHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void create() throws WeixinException {
|
||||||
|
User user = new User("u001", "jack");
|
||||||
|
user.setMobile("13500000000");
|
||||||
|
user.setDepartment(1);
|
||||||
|
user.pushExattr("爱好", "code");
|
||||||
|
JsonResult result = userApi.createUser(user);
|
||||||
|
Assert.assertEquals("created", result.getDesc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void update() throws WeixinException {
|
||||||
|
User user = new User("u001", "ted");
|
||||||
|
user.setMobile("13500000000");
|
||||||
|
user.setDepartment(1);
|
||||||
|
user.pushExattr("爱好", "code");
|
||||||
|
JsonResult result = userApi.updateUser(user);
|
||||||
|
Assert.assertEquals("updated", result.getDesc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void get() throws WeixinException {
|
||||||
|
User user = userApi.getUser("u001");
|
||||||
|
Assert.assertTrue(user != null);
|
||||||
|
System.out.println(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void list() throws WeixinException {
|
||||||
|
List<User> userList = userApi.listUser(1);
|
||||||
|
Assert.assertFalse(userList.isEmpty());
|
||||||
|
System.out.println(userList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void delete() throws WeixinException {
|
||||||
|
JsonResult result = userApi.deleteUser("u001");
|
||||||
|
Assert.assertEquals("deleted", result.getDesc());
|
||||||
|
}
|
||||||
|
}
|
||||||
28
weixin4j-qy/weixin4j-qy-server/.gitignore
vendored
Normal file
28
weixin4j-qy/weixin4j-qy-server/.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# eclipse ignore
|
||||||
|
*.settings/*
|
||||||
|
/.project
|
||||||
|
/.classpath
|
||||||
|
/.tomcatplugin
|
||||||
|
|
||||||
|
# maven ignore
|
||||||
|
target/*
|
||||||
|
|
||||||
|
# other ignore
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
Thumbs.db
|
||||||
|
/target/
|
||||||
|
.DS_Store
|
||||||
22
weixin4j-qy/weixin4j-qy-server/README.md
Normal file
22
weixin4j-qy/weixin4j-qy-server/README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
weixin4j-qy-server
|
||||||
|
==================
|
||||||
|
|
||||||
|
微信企业号netty服务
|
||||||
|
------------
|
||||||
|
|
||||||
|
功能列表
|
||||||
|
-------
|
||||||
|
|
||||||
|
* `netty构建服务器`
|
||||||
|
|
||||||
|
* `消息分发`
|
||||||
|
|
||||||
|
如何使用
|
||||||
|
--------
|
||||||
|
|
||||||
|
|
||||||
|
更新LOG
|
||||||
|
-------
|
||||||
|
* 2014-11-19
|
||||||
|
|
||||||
|
+ 得到`weixin4j-qy-server`工程
|
||||||
24
weixin4j-qy/weixin4j-qy-server/pom.xml
Normal file
24
weixin4j-qy/weixin4j-qy-server/pom.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.foxinmy.weixin4j</groupId>
|
||||||
|
<artifactId>weixin4j-qy</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>weixin4j-qy-server</artifactId>
|
||||||
|
<name>weixin4j-qy-server</name>
|
||||||
|
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy/weixin4j-qy-server</url>
|
||||||
|
<description>微信企业号工具包</description>
|
||||||
|
<build>
|
||||||
|
<finalName>weixin-qy-server</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
36
weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml
Normal file
36
weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||||
|
<id>bin</id>
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>true</includeBaseDirectory>
|
||||||
|
<dependencySets>
|
||||||
|
<dependencySet>
|
||||||
|
<useProjectArtifact>true</useProjectArtifact>
|
||||||
|
<outputDirectory>/lib</outputDirectory>
|
||||||
|
</dependencySet>
|
||||||
|
</dependencySets>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>com/foxinmy/weixin4j/qy</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.md</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>src/main</directory>
|
||||||
|
<outputDirectory>/</outputDirectory>
|
||||||
|
<includes>
|
||||||
|
<include>*.sh</include>
|
||||||
|
<include>*.bat</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<outputDirectory>/conf</outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
||||||
142
weixin4j-qy/weixin4j-qy-server/src/main/startup.sh
Normal file
142
weixin4j-qy/weixin4j-qy-server/src/main/startup.sh
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
ulimit -n 110000
|
||||||
|
#JDK home
|
||||||
|
JAVA_HOME="/usr/local/java/"
|
||||||
|
|
||||||
|
#executing user
|
||||||
|
RUNNING_USER=root
|
||||||
|
|
||||||
|
#Run home
|
||||||
|
APP_HOME="/usr/local/weixin/weixin-mp-server"
|
||||||
|
|
||||||
|
#main class
|
||||||
|
APP_MAINCLASS=com.foxinmy.weixin4j.mp.startup.WeixinServerBootstrap
|
||||||
|
|
||||||
|
#classpath
|
||||||
|
CLASSPATH=$APP_HOME/classes
|
||||||
|
for i in "$APP_HOME"/lib/*.jar; do
|
||||||
|
CLASSPATH="$CLASSPATH":"$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
CLASSPATH="$CLASSPATH":"$APP_HOME"/conf
|
||||||
|
|
||||||
|
#jvm options
|
||||||
|
JAVA_OPTS="-Xms256m -Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=128m -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+DisableExplicitGC -Xnoclassgc -Xverify:none"
|
||||||
|
|
||||||
|
#psid
|
||||||
|
psid=0
|
||||||
|
|
||||||
|
checkpid() {
|
||||||
|
javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`
|
||||||
|
|
||||||
|
if [ -n "$javaps" ]; then
|
||||||
|
psid=`echo $javaps | awk '{print $1}'`
|
||||||
|
else
|
||||||
|
psid=0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#startup
|
||||||
|
###################################
|
||||||
|
start() {
|
||||||
|
checkpid
|
||||||
|
|
||||||
|
if [ $psid -ne 0 ]; then
|
||||||
|
echo "====================================================="
|
||||||
|
echo "warn: $APP_MAINCLASS already started! (pid=$psid)"
|
||||||
|
echo "====================================================="
|
||||||
|
else
|
||||||
|
echo -n "Starting $APP_MAINCLASS ..."
|
||||||
|
# JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >/dev/null 2>&1 &"
|
||||||
|
JAVA_CMD="$JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS &"
|
||||||
|
su - $RUNNING_USER -c "$JAVA_CMD"
|
||||||
|
checkpid
|
||||||
|
if [ $psid -ne 0 ]; then
|
||||||
|
echo "(pid=$psid) [OK]"
|
||||||
|
else
|
||||||
|
echo "[Failed]"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#stop
|
||||||
|
###################################
|
||||||
|
stop() {
|
||||||
|
checkpid
|
||||||
|
|
||||||
|
if [ $psid -ne 0 ]; then
|
||||||
|
echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) "
|
||||||
|
su - $RUNNING_USER -c "kill -9 $psid"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "[OK]"
|
||||||
|
else
|
||||||
|
echo "[Failed]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
checkpid
|
||||||
|
if [ $psid -ne 0 ]; then
|
||||||
|
stop
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "====================================================="
|
||||||
|
echo "warn: $APP_MAINCLASS is not running"
|
||||||
|
echo "====================================================="
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#status
|
||||||
|
###################################
|
||||||
|
status() {
|
||||||
|
checkpid
|
||||||
|
|
||||||
|
if [ $psid -ne 0 ]; then
|
||||||
|
echo "$APP_MAINCLASS is running! (pid=$psid)"
|
||||||
|
else
|
||||||
|
echo "$APP_MAINCLASS is not running"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#info
|
||||||
|
###################################
|
||||||
|
info() {
|
||||||
|
echo "System Information:"
|
||||||
|
echo "****************************"
|
||||||
|
echo `head -n 1 /etc/issue`
|
||||||
|
echo `uname -a`
|
||||||
|
echo
|
||||||
|
echo "JAVA_HOME=$JAVA_HOME"
|
||||||
|
echo `$JAVA_HOME/bin/java -version`
|
||||||
|
echo
|
||||||
|
echo "APP_HOME=$APP_HOME"
|
||||||
|
echo "APP_MAINCLASS=$APP_MAINCLASS"
|
||||||
|
echo "****************************"
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#access only 1 argument:{start|stop|restart|status|info}
|
||||||
|
###################################
|
||||||
|
case "$1" in
|
||||||
|
'start')
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'stop')
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
'restart')
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'status')
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
'info')
|
||||||
|
info
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|restart|status|info}"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
Loading…
x
Reference in New Issue
Block a user