weixin4j-qy:新增服务商接口(ProviderApi)

This commit is contained in:
jinyu 2015-12-30 11:29:14 +08:00
parent fbbd670b0f
commit 3d26b8f531
11 changed files with 276 additions and 104 deletions

View File

@ -608,3 +608,8 @@
+ weixin4j-server:删除无用的工具类并重新整理
* 2015-12-30
+ weixin4j-qy:新增服务商接口(ProviderApi)

View File

@ -0,0 +1,5 @@
* CashApi `现金红包API`
* CouponApi `优惠券API`
* Pay3Api `微信支付API`

View File

@ -7,39 +7,31 @@ weixin4j-mp
功能列表
-------
* MediaApi `媒体素材API`
* NotifyApi `客服消息API`
* CustomApi `多客服API`
* MassApi `群发消息API`
* UserApi `用户管理API`
* DataApi `数据统计API`
* GroupApi `分组管理API`
* HelperApi `辅助API`
* MassApi `群发消息API`
* MediaApi `上传/下载媒体文件API`
* MenuApi `底部菜单API`
* NotifyApi `客服消息API`
* OauthApi `oauth授权API`
* Pay2Api `V2支付API`
* QrApi `二维码API`
* TmplApi `模板消息API`
* HelperApi `辅助API`
* Pay2Api `V2支付API`
* Pay3Api `V3(商户平台)支付API`
* CouponApi `代金券API`
* DataApi `数据统计API`
* OauthApi `oauth授权API`
* CashApi `现金API`
* PayUtil [微信支付工具类](https://github.com/foxinmy/weixin4j/tree/master/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayUtil.java)
* UserApi `用户管理API`
如何使用
--------

View File

@ -1,31 +1,25 @@
* MediaApi `上传/下载媒体文件API`
* NotifyApi `客服消息API`
* CustomApi `多客服API`
* MassApi `群发消息API`
* UserApi `用户管理API`
* DataApi `数据统计API`
* GroupApi `分组管理API`
* HelperApi `辅助API`
* MassApi `群发消息API`
* MediaApi `上传/下载媒体文件API`
* MenuApi `底部菜单API`
* NotifyApi `客服消息API`
* OauthApi `oauth授权API`
* Pay2Api `V2支付API`
* QrApi `二维码API`
* TmplApi `模板消息API`
* HelperApi `辅助API`
* Pay2Api `V2支付API`
* Pay3Api `V3支付API`
* CouponApi `代金券API`
* DataApi `数据统计API`
* OauthApi `oauth授权API`
* CashApi `现金API`
* UserApi `用户管理API`

View File

@ -7,11 +7,13 @@ weixin4j-qy
功能列表
-------
* PartyApi `部门管理API`
* AgentApi `应用设置API`
* UserApi `成员管理API`
* BatchApi `批量任务API`
* TagApi `标签管理API`
* ChatApi `会话服务API`
* Helper `辅助API`
* MediaApi `媒体素材API`
@ -19,21 +21,18 @@ weixin4j-qy
* NotifyApi `消息发送API`
* AgentApi `应用设置API`
* BatchApi `批量任务API`
* OauthApi `oauth授权登陆API`
* PartyApi `部门管理API`
* ProviderApi `服务商API`
* SuiteApi `第三方应用API`
* Pay3Api `商户平台支付API`
* TagApi `标签管理API`
* CouponApi `代金券API`
* UserApi `成员管理API`
* CashApi `现金API`
* ChatApi `会话服务API`
如何使用
--------

View File

@ -5,10 +5,17 @@ import java.util.Map;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.qy.api.ProviderApi;
import com.foxinmy.weixin4j.qy.api.QyApi;
import com.foxinmy.weixin4j.qy.api.SuiteApi;
import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder;
import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator;
import com.foxinmy.weixin4j.qy.type.LoginTargetType;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* 微信第三方应用接口实现
@ -23,7 +30,8 @@ import com.foxinmy.weixin4j.token.TokenStorager;
*/
public class WeixinSuiteProxy {
private final Map<String, SuiteApi> suiteMap;
private Map<String, SuiteApi> suiteMap;
private ProviderApi providerApi;
public WeixinSuiteProxy() {
this(QyApi.DEFAULT_TOKEN_STORAGER);
@ -38,8 +46,8 @@ public class WeixinSuiteProxy {
* @throws WeixinException
*/
public WeixinSuiteProxy(String suiteId, String suiteSecret) {
this(QyApi.DEFAULT_TOKEN_STORAGER, new WeixinAccount(suiteId,
suiteSecret));
this(QyApi.DEFAULT_TOKEN_STORAGER, null, null, new WeixinAccount(
suiteId, suiteSecret));
}
/**
@ -48,7 +56,7 @@ public class WeixinSuiteProxy {
* token存储
*/
public WeixinSuiteProxy(TokenStorager tokenStorager) {
this(tokenStorager, QyApi.DEFAULT_WEIXIN_ACCOUNT.suitesToArray());
this(tokenStorager, QyApi.DEFAULT_WEIXIN_ACCOUNT);
}
/**
@ -56,18 +64,43 @@ public class WeixinSuiteProxy {
* @param tokenStorager
* token存储
* @param suites
* 套件信息
* 套件信息 必填项
*/
public WeixinSuiteProxy(TokenStorager tokenStorager,
WeixinAccount... suites) {
WeixinQyAccount weixinAccount) {
this(tokenStorager, weixinAccount.getId(), weixinAccount
.getProviderSecret(), weixinAccount.suitesToArray());
}
/**
*
* @param tokenStorager
* token存储
* @param corpId
* 服务商的企业号ID <font color="red">使用服务商API时必填项</font>
* @param providerSecret
* 服务商secret <font color="red">使用服务商API时必填项</font>
* @param suites
* 套件信息 <font color="red">使用套件API时必填项</font>
*/
public WeixinSuiteProxy(TokenStorager tokenStorager, String corpId,
String providerSecret, WeixinAccount... suites) {
if (suites != null) {
this.suiteMap = new HashMap<String, SuiteApi>();
for (WeixinAccount suite : suites) {
this.suiteMap.put(suite.getId(), new SuiteApi(
new SuiteTicketHolder(suite.getId(), suite.getSecret(),
tokenStorager)));
}
this.suiteMap.put(null, suiteMap.get(suites[0].getId()));
}
}
if (StringUtil.isNotBlank(corpId)
&& StringUtil.isNotBlank(providerSecret)) {
this.providerApi = new ProviderApi(new TokenHolder(
new WeixinProviderTokenCreator(corpId, providerSecret),
tokenStorager));
}
}
/**
* 只关注第一个套件获取API(如果只有一个套件
@ -91,5 +124,41 @@ public class WeixinSuiteProxy {
return this.suiteMap.get(suiteId);
}
/**
* 第三方套件获取企业号管理员登录信息
*
* @param authCode
* oauth2.0授权企业号管理员登录产生的code
* @return 登陆信息
* @see com.foxinmy.weixin4j.qy.api.ProviderApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF">授权获取企业号管理员登录信息</a>
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
* @throws WeixinException
*/
public OUserInfo getOUserInfoByCode(String authCode) throws WeixinException {
return providerApi.getOUserInfoByCode(authCode);
}
/**
* 获取登录企业号官网的url
*
* @param corpId
* <font color="red">oauth授权的corpid</font>
* @param targetType
* 登录跳转到企业号后台的目标页面
* @param agentId
* 授权方应用id 小余1时则不传递
* @return 登陆URL
* @see com.foxinmy.weixin4j.qy.api.ProviderApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%AE%98%E7%BD%91%E7%9A%84url">获取登录企业号官网的url</a>
* @throws WeixinException
*/
public String getLoingUrl(String corpId, LoginTargetType targetType,
int agentId) throws WeixinException {
return providerApi.getLoingUrl(corpId, targetType, agentId);
}
public final static String VERSION = "1.6.5";
}

View File

@ -3,12 +3,7 @@ package com.foxinmy.weixin4j.qy.api;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/**
@ -90,6 +85,8 @@ public class OauthApi extends QyApi {
* @param state
* 用于保持请求和回调的状态授权请求后原样带回给第三方
* @return 请求授权的URL
* @see ProviderApi
* @see {@link com.foxinmy.weixin4j.qy.WeixinSuiteProxy#getOUserInfoByCode(String)}
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号第三方提供商授权</a>
*/
@ -105,33 +102,6 @@ public class OauthApi extends QyApi {
return "";
}
/**
* 第三方套件获取企业号管理员登录信息
*
* @param providerToken
* 提供商的token
* @param authCode
* oauth2.0授权企业号管理员登录产生的code
* @return 登陆信息
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF">授权获取企业号管理员登录信息</a>
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
* @throws WeixinException
*/
public OUserInfo getOUserInfoByCode(String providerToken, String authCode)
throws WeixinException {
String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri");
WeixinResponse response = weixinExecutor.post(
String.format(oauth_logininfo_uri, providerToken),
String.format("{\"auth_code\":\"%s\"}", authCode));
JSONObject obj = response.getAsJson();
OUserInfo oUser = JSON.toJavaObject(obj, OUserInfo.class);
oUser.getRedirectLoginInfo().setAccessToken(
obj.getJSONObject("redirect_login_info").getString(
"login_ticket"));
return oUser;
}
/**
* 应用套件授权
*

View File

@ -0,0 +1,96 @@
package com.foxinmy.weixin4j.qy.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.type.LoginTargetType;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* 服务商相关API
*
* @className ProviderApi
* @author jy
* @date 2015年12月30日
* @since JDK 1.6
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号登录授权说明</a>
*/
public class ProviderApi extends QyApi {
private final TokenHolder providerTokenHolder;
public ProviderApi(TokenHolder providerTokenHolder) {
this.providerTokenHolder = providerTokenHolder;
}
/**
* 第三方套件获取企业号管理员登录信息
*
* @param authCode
* oauth2.0授权企业号管理员登录产生的code
* @return 登陆信息
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF">授权获取企业号管理员登录信息</a>
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
* @throws WeixinException
*/
public OUserInfo getOUserInfoByCode(String authCode) throws WeixinException {
String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri");
WeixinResponse response = weixinExecutor.post(
String.format(oauth_logininfo_uri,
providerTokenHolder.getAccessToken()),
String.format("{\"auth_code\":\"%s\"}", authCode));
JSONObject obj = response.getAsJson();
OUserInfo oUser = JSON.toJavaObject(obj, OUserInfo.class);
oUser.getRedirectLoginInfo().setAccessToken(
obj.getJSONObject("redirect_login_info").getString(
"login_ticket"));
providerTokenHolder.getTokenStorager().caching(
getLoginTicketCacheKey(oUser.getCorpInfo().getCorpId()),
oUser.getRedirectLoginInfo());
return oUser;
}
private String getLoginTicketCacheKey(String coprId) {
return String.format("wx_qy_provider_login_ticket_%s", coprId);
}
/**
* 获取登录企业号官网的url
*
* @param corpId
* <font color="red">oauth授权的corpid</font>
* @param targetType
* 登录跳转到企业号后台的目标页面
* @param agentId
* 授权方应用id 小余1时则不传递
* @return 登陆URL
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%AE%98%E7%BD%91%E7%9A%84url">获取登录企业号官网的url</a>
* @throws WeixinException
*/
public String getLoingUrl(String corpId, LoginTargetType targetType,
int agentId) throws WeixinException {
Token token = providerTokenHolder.getTokenStorager().lookup(
getLoginTicketCacheKey(corpId));
if (token == null || StringUtil.isBlank(token.getAccessToken())) {
throw new WeixinException("maybe oauth first?");
}
String oauth_loginurl_uri = getRequestUri("oauth_loginurl_uri");
JSONObject obj = new JSONObject();
obj.put("login_ticket", token.getAccessToken());
obj.put("target", targetType.name());
if (agentId > 0) {
obj.put("agentid", agentId);
}
WeixinResponse response = weixinExecutor.post(
String.format(oauth_loginurl_uri,
providerTokenHolder.getAccessToken()),
obj.toJSONString());
return response.getAsJson().getString("login_url");
}
}

View File

@ -0,0 +1,26 @@
* AgentApi `应用设置API`
* BatchApi `批量任务API`
* ChatApi `会话服务API`
* Helper `辅助API`
* MediaApi `媒体素材API`
* MenuApi `菜单管理API`
* NotifyApi `消息发送API`
* OauthApi `oauth授权登陆API`
* PartyApi `部门管理API`
* ProviderApi `服务商API`
* SuiteApi `第三方应用API`
* TagApi `标签管理API`
* UserApi `成员管理API`

View File

@ -88,6 +88,8 @@ user_oauth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redi
provider_oauth_uri=https://qy.weixin.qq.com/cgi-bin/loginpage?corp_id=%s&redirect_uri=%s&state=%s
# \u4f01\u4e1a\u53f7\u7ba1\u7406\u5458\u767b\u5f55\u4fe1\u606f
oauth_logininfo_uri={api_base_url}/service/get_login_info?provider_access_token=%s
# \u767b\u5f55\u4f01\u4e1a\u53f7\u5b98\u7f51\u7684url
oauth_loginurl_uri={api_base_url}/service/get_login_url?provider_access_token=%s
# \u5e94\u7528\u5957\u4ef6oauth\u6388\u6743
suite_oauth_uri=https://qy.weixin.qq.com/cgi-bin/loginpage?suite_id=%s&pre_auth_code=%s&redirect_uri=%s&state=%s
# \u5e94\u7528\u5957\u4ef6\u8bbe\u7f6e\u6388\u6743\u914d\u7f6e

View File

@ -0,0 +1,14 @@
package com.foxinmy.weixin4j.qy.type;
/**
* 登录跳转到企业号后台的目标页面
*
* @className LoginTargetType
* @author jy
* @date 2015年12月30日
* @since JDK 1.6
* @see
*/
public enum LoginTargetType {
agent_setting, send_msg, contact, third_admin
}