diff --git a/CHANGE.md b/CHANGE.md index 1d25cec9..d010d2e0 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -571,6 +571,10 @@ + weixin4j-base:新增JSSDK的config生成类 + + weixin4j-base:JSSDKHelper 重命名为 JSSDKConfigurator + + + weixin4j-base:重构了token类 + + weixin4j-mp:WeixinProxy新增获取appid(getAppId)方法 + weixin4j-mp:WeixinProxy新增获取jsticket(getJSTicketHolder)方法 @@ -584,3 +588,10 @@ + weixin4j-qy:私有化WeixinProxy(TokenHolder)构造器 + weixin4j-qy:SuiteApi新增获取Weixinproxy对象(getWeixinProxy)方法 + + + weixin4j-qy:删除WeixinJSTicketCreator类 + + + weixin4j-qy:新增企业号联系人筛选配置类(JSSDKContactConfigurator) + + + weixin4j-server:DigestUtil 重命名为 DigestUtils + \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java index 09c19e32..2081ae0a 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java @@ -16,7 +16,7 @@ import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; /** - * JSSDK帮助类 + * JSSDK配置类 * * @className JSSDKConfigurator * @author jy @@ -30,7 +30,7 @@ public class JSSDKConfigurator { private Set apis; /** - * ticket保存类 可调用WeixinProxy#getJSTicketHolder获取 + * ticket保存类 可调用WeixinProxy#getTicketHolder获取 * * @param ticketTokenHolder */ @@ -93,7 +93,7 @@ public class JSSDKConfigurator { } /** - * 生成config字符串 + * 生成config配置JSON串 * * @param url * 当前网页的URL,不包含#及其后面部分 diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 59487827..66191aed 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -160,7 +160,7 @@ public class WeixinProxy { } /** - * 获取JSSDK的tokenHolder + * 获取JSSDK JSTicket的tokenHolder * * @return */ diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java index b6e53fa0..c2b38d51 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java @@ -40,9 +40,11 @@ import com.foxinmy.weixin4j.qy.model.Party; import com.foxinmy.weixin4j.qy.model.Tag; import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.suite.WeixinTokenSuiteCreator; +import com.foxinmy.weixin4j.qy.token.WeixinTicketCreator; import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator; import com.foxinmy.weixin4j.qy.type.ChatType; import com.foxinmy.weixin4j.qy.type.InviteType; +import com.foxinmy.weixin4j.qy.type.TicketType; import com.foxinmy.weixin4j.qy.type.UserStatus; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenStorager; @@ -162,15 +164,15 @@ public class WeixinProxy { } /** - * 获取JSSDK的tokenHolder + * 获取JSSDK Ticket的tokenHolder * + * @param ticketType + * 票据类型 * @return */ - public TokenHolder getJSTicketHolder() { - return new TokenHolder( - new com.foxinmy.weixin4j.qy.token.WeixinJSTicketCreator( - this.corpId, this.tokenHolder), - this.tokenHolder.getTokenStorager()); + public TokenHolder getTicketHolder(TicketType ticketType) { + return new TokenHolder(new WeixinTicketCreator(this.corpId, ticketType, + this.tokenHolder), this.tokenHolder.getTokenStorager()); } /** diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactConfigurator.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactConfigurator.java new file mode 100644 index 00000000..359f7db5 --- /dev/null +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactConfigurator.java @@ -0,0 +1,199 @@ +package com.foxinmy.weixin4j.qy.jssdk; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.token.TokenHolder; +import com.foxinmy.weixin4j.util.DateUtil; +import com.foxinmy.weixin4j.util.DigestUtil; +import com.foxinmy.weixin4j.util.MapUtil; +import com.foxinmy.weixin4j.util.RandomUtil; + +/** + * JSSDK联系人筛选配置 + * + * @className JSSDKContactConfigurator + * @author jy + * @date 2015年12月25日 + * @since JDK 1.7 + * @see + */ +public class JSSDKContactConfigurator { + private final TokenHolder ticketTokenHolder; + private JSSDKContactParameter contactParameter; + + /** + * ticket保存类 可调用WeixinProxy#getTicketHolder获取 + * + * @param ticketTokenHolder + */ + public JSSDKContactConfigurator(TokenHolder ticketTokenHolder) { + this.ticketTokenHolder = ticketTokenHolder; + this.contactParameter = new JSSDKContactParameter(); + } + + /** + * 可选范围:部门ID列表(如果departmentIds为0则表示显示管理组下所有部门) + * + * @param departmentIds + * @return + */ + public JSSDKContactConfigurator departmentIds(Integer... departmentIds) { + contactParameter.putDepartmentIds(departmentIds); + return this; + } + + /** + * 可选范围:标签ID列表(如果tagIds为0则表示显示所有标签) + * + * @param tagIds + * @return + */ + public JSSDKContactConfigurator tagIds(Integer... tagIds) { + contactParameter.putTagIds(tagIds); + return this; + } + + /** + * 可选范围:用户ID列表 + * + * @param userIds + * @return + */ + public JSSDKContactConfigurator userIds(String... userIds) { + contactParameter.putUserIds(userIds); + return this; + } + + /** + * 单选模式 + * + * @return + */ + public JSSDKContactConfigurator singleMode() { + contactParameter.setMode("single"); + return this; + } + + /** + * 多选模式 + * + * @return + */ + public JSSDKContactConfigurator multiMode() { + contactParameter.setMode("multi"); + return this; + } + + /** + * 限制部门 + * + * @return + */ + public JSSDKContactConfigurator limitDepartment() { + contactParameter.putLimitType("department"); + return this; + } + + /** + * 限制标签 + * + * @return + */ + public JSSDKContactConfigurator limitTag() { + contactParameter.putLimitType("tag"); + return this; + } + + /** + * 限制用户 + * + * @return + */ + public JSSDKContactConfigurator limitUser() { + contactParameter.putLimitType("user"); + return this; + } + + /** + * 已选部门ID + * + * @param selectedDepartmentIds + * @return + */ + public JSSDKContactConfigurator selectedDepartmentIds( + Integer... selectedDepartmentIds) { + contactParameter.putSelectedDepartmentIds(selectedDepartmentIds); + return this; + } + + /** + * 已选标签ID + * + * @param selectedTagIds + * @return + */ + public JSSDKContactConfigurator selectedTagIds(Integer... selectedTagIds) { + contactParameter.putSelectedTagIds(selectedTagIds); + return this; + } + + /** + * 已选用户ID + * + * @param selectedUserIds + * @return + */ + public JSSDKContactConfigurator selectedUserIds(String... selectedUserIds) { + contactParameter.putSelectedUserIds(selectedUserIds); + return this; + } + + /** + * 生成config配置JSON串 + * + * @param url + * 当前网页的URL,不包含#及其后面部分 + * @return + * @throws WeixinException + */ + public String toJSONConfig(String url) throws WeixinException { + return toJSONConfig(url, contactParameter); + } + + /** + * 生成config配置JSON串 + * + * @param url + * 当前网页的URL,不包含#及其后面部分 + * @param parameter + * 自定义传入参数对象 + * @return + * @throws WeixinException + */ + public String toJSONConfig(String url, JSSDKContactParameter parameter) + throws WeixinException { + Map signMap = new HashMap(); + String timestamp = DateUtil.timestamp2string(); + String noncestr = RandomUtil.generateString(24); + Token token = this.ticketTokenHolder.getToken(); + signMap.put("timestamp", timestamp); + signMap.put("nonceStr", noncestr); + signMap.put("group_ticket", token.getAccessToken()); + signMap.put("url", url); + String sign = DigestUtil.SHA1(MapUtil + .toJoinString(signMap, false, true)); + JSONObject config = new JSONObject(); + config.put("signature", sign); + config.put("groupId", JSON.parseObject(token.getOriginalResult()) + .getString("group_id")); + config.put("timestamp", timestamp); + config.put("noncestr", noncestr); + config.put("params", parameter); + return config.toJSONString(); + } +} diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactParameter.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactParameter.java new file mode 100644 index 00000000..9e0a79f2 --- /dev/null +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/jssdk/JSSDKContactParameter.java @@ -0,0 +1,116 @@ +package com.foxinmy.weixin4j.qy.jssdk; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.qy.model.IdParameter; + +/** + * JSSDK联系人筛选参数 + * + * @className JSSDKContactParameter + * @author jy + * @date 2015年12月25日 + * @since JDK 1.6 + * @see + */ +public class JSSDKContactParameter extends IdParameter { + private static final long serialVersionUID = 1863797419140279996L; + + /** + * 选择模式 single/multi + */ + private String mode; + /** + * 选择限制类型 department/tag/user + */ + @JSONField(name = "type") + private List limitTypes; + /** + * 已选用户ID + */ + private List selectedUserIds; + /** + * 已选部门ID + */ + private List selectedDepartmentIds; + /** + * 已选标签ID + */ + private List selectedTagIds; + + public JSSDKContactParameter() { + super(); + this.selectedUserIds = new ArrayList(); + this.selectedTagIds = new ArrayList(); + this.selectedDepartmentIds = new ArrayList(); + this.limitTypes = new ArrayList(); + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public List getLimitTypes() { + return limitTypes; + } + + public void setLimitTypes(List limitTypes) { + this.limitTypes = limitTypes; + } + + public void putLimitType(String type) { + this.limitTypes.add(type); + } + + public List getSelectedUserIds() { + return selectedUserIds; + } + + public void setSelectedUserIds(List selectedUserIds) { + this.selectedUserIds = selectedUserIds; + } + + public void putSelectedUserIds(String... selectedUserIds) { + this.selectedUserIds.addAll(Arrays.asList(selectedUserIds)); + } + + public List getSelectedDepartmentIds() { + return selectedDepartmentIds; + } + + public void setSelectedDepartmentIds(List selectedDepartmentIds) { + this.selectedDepartmentIds = selectedDepartmentIds; + } + + public void putSelectedDepartmentIds(Integer... selectedDepartmentIds) { + this.selectedDepartmentIds.addAll(Arrays.asList(selectedDepartmentIds)); + } + + public List getSelectedTagIds() { + return selectedTagIds; + } + + public void setSelectedTagIds(List selectedTagIds) { + this.selectedTagIds = selectedTagIds; + } + + public void putSelectedTagIds(Integer... selectedTagIds) { + this.selectedTagIds.addAll(Arrays.asList(selectedTagIds)); + } + + @Override + public String toString() { + return "JSSDKContactParameter [mode=" + mode + ", limitTypes=" + + limitTypes + ", selectedUserIds=" + selectedUserIds + + ", selectedDepartmentIds=" + selectedDepartmentIds + + ", selectedTagIds=" + selectedTagIds + ", " + + super.toString() + "]"; + } +} diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java index b489ce83..4af10c25 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java @@ -48,7 +48,7 @@ public class NotifyMessage implements Serializable { private IdParameter target; public NotifyMessage(int agentid, NotifyTuple tuple) { - this(agentid, tuple, IdParameter.get(), false); + this(agentid, tuple, new IdParameter(), false); } public NotifyMessage(int agentId, NotifyTuple tuple, IdParameter target, diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/IdParameter.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/IdParameter.java index fe90a76d..8b8ce6d7 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/IdParameter.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/IdParameter.java @@ -25,19 +25,15 @@ public class IdParameter implements Serializable { private static final char SEPARATOR = '|'; private List userIds; - private List partyIds; + private List departmentIds; private List tagIds; - private IdParameter() { + public IdParameter() { this.userIds = new ArrayList(); - this.partyIds = new ArrayList(); + this.departmentIds = new ArrayList(); this.tagIds = new ArrayList(); } - public static IdParameter get() { - return new IdParameter(); - } - /** * 增加成员ID列表,最多支持1000个 * @@ -63,22 +59,22 @@ public class IdParameter implements Serializable { /** * 新增部门ID列表,最多支持100个 * - * @param partyIds + * @param departmentIds * @return */ - public IdParameter putPartyIds(Integer... partyIds) { - this.partyIds.addAll(Arrays.asList(partyIds)); + public IdParameter putDepartmentIds(Integer... departmentIds) { + this.departmentIds.addAll(Arrays.asList(departmentIds)); return this; } /** * 设置部门ID列表,最多支持100个 * - * @param partyIds + * @param departmentIds * @return */ - public IdParameter setPartyIds(List partyIds) { - this.partyIds = partyIds; + public IdParameter setDepartmentIds(List departmentIds) { + this.departmentIds = departmentIds; return this; } @@ -114,12 +110,18 @@ public class IdParameter implements Serializable { if (userIds != null && !userIds.isEmpty()) { parameterMap.put("touser", StringUtil.join(userIds, SEPARATOR)); } - if (partyIds != null && !partyIds.isEmpty()) { - parameterMap.put("toparty", StringUtil.join(partyIds, SEPARATOR)); + if (departmentIds != null && !departmentIds.isEmpty()) { + parameterMap.put("toparty", StringUtil.join(departmentIds, SEPARATOR)); } if (tagIds != null && !tagIds.isEmpty()) { parameterMap.put("totag", StringUtil.join(tagIds, SEPARATOR)); } return parameterMap; } + + @Override + public String toString() { + return "IdParameter [userIds=" + userIds + ", departmentIds=" + + departmentIds + ", tagIds=" + tagIds + "]"; + } } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinJSTicketCreator.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTicketCreator.java similarity index 58% rename from weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinJSTicketCreator.java rename to weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTicketCreator.java index 6476cf56..286cb5ca 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinJSTicketCreator.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTicketCreator.java @@ -5,50 +5,60 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.qy.type.TicketType; import com.foxinmy.weixin4j.qy.type.URLConsts; import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenHolder; /** - * 微信企业号JSTICKET创建 + * 微信企业号TICKET创建(包括jsticket、其它JSSDK所需的ticket的创建 * - * @className WeixinJSTicketCreator + * @className WeixinTicketCreator * @author jy - * @date 2015年1月10日 + * @date 2015年12月25日 * @since JDK 1.6 - * @see JS - * TICKET + * */ -public class WeixinJSTicketCreator implements TokenCreator { +public class WeixinTicketCreator implements TokenCreator { private final String corpid; + private final TicketType ticketType; private final TokenHolder weixinTokenHolder; private final WeixinRequestExecutor weixinExecutor; /** - * * @param corpid * 企业号ID + * @param ticketType + * 票据类型 * @param weixinTokenHolder * 企业号的的access_token */ - public WeixinJSTicketCreator(String corpid, TokenHolder weixinTokenHolder) { + public WeixinTicketCreator(String corpid, TicketType ticketType, + TokenHolder weixinTokenHolder) { this.corpid = corpid; + this.ticketType = ticketType; this.weixinTokenHolder = weixinTokenHolder; this.weixinExecutor = new WeixinRequestExecutor(); } @Override public String getCacheKey() { - return String.format("wx_qy_jsticket_%s", corpid); + return String.format("wx_qy_ticket_%s_%s", corpid, ticketType.name()); } @Override public Token createToken() throws WeixinException { - WeixinResponse response = weixinExecutor.get(String.format( - URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken() - .getAccessToken())); + WeixinResponse response = null; + if (ticketType == TicketType.jsticket) { + response = weixinExecutor.get(String.format( + URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken() + .getAccessToken())); + } else { + response = weixinExecutor.get(String.format(URLConsts.TICKET_URL, + weixinTokenHolder.getToken().getAccessToken(), + ticketType.name())); + } JSONObject result = response.getAsJson(); Token token = new Token(result.getString("ticket")); token.setExpiresIn(result.getIntValue("expires_in")); diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/type/TicketType.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/type/TicketType.java new file mode 100644 index 00000000..8b6a1cac --- /dev/null +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/type/TicketType.java @@ -0,0 +1,21 @@ +package com.foxinmy.weixin4j.qy.type; + +/** + * 票据类型 + * + * @className TicketType + * @author jy + * @date 2015年12月25日 + * @since JDK 1.7 + * @see + */ +public enum TicketType { + /** + * jsticket + */ + jsticket, + /** + * 选取联系人 + */ + contact; +}