@@ -5,7 +5,7 @@ import lombok.Getter; | |||
/** | |||
* <pre> | |||
* 企业微信全局错误码. | |||
* 参考文档:<a href="https://work.weixin.qq.com/api/doc#10649">企业微信全局错误码</a> | |||
* 参考文档:<a href="https://work.weixin.qq.com/api/doc/90000/90139/90313">企业微信全局错误码</a> | |||
* Created by Binary Wang on 2018/5/13. | |||
* </pre> | |||
* | |||
@@ -609,6 +609,322 @@ public enum WxCpErrorMsgEnum { | |||
* 不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节. | |||
*/ | |||
CODE_84025(84025, "不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节"), | |||
/** | |||
* 缺少caller参数. | |||
*/ | |||
CODE_84052(84052, "缺少caller参数"), | |||
/** | |||
* 缺少callee参数. | |||
*/ | |||
CODE_84053(84053, "缺少callee参数"), | |||
/** | |||
* 缺少auth_corpid参数. | |||
*/ | |||
CODE_84054(84054, "缺少auth_corpid参数"), | |||
/** | |||
* 超过拨打公费电话频率。排查方法:同一个客服5秒内只能调用api拨打一次公费电话 | |||
*/ | |||
CODE_84055(84055, "超过拨打公费电话频率。排查方法:同一个客服5秒内只能调用api拨打一次公费电话"), | |||
/** | |||
* 被拨打用户安装应用时未授权拨打公费电话权限. | |||
*/ | |||
CODE_84056(84056, "被拨打用户安装应用时未授权拨打公费电话权限"), | |||
/** | |||
* 公费电话余额不足. | |||
*/ | |||
CODE_84057(84057, "公费电话余额不足"), | |||
/** | |||
* caller | |||
*/ | |||
CODE_84058(84058, "caller 呼叫号码不支持"), | |||
/** | |||
* 号码非法. | |||
*/ | |||
CODE_84059(84059, "号码非法"), | |||
/** | |||
* callee | |||
*/ | |||
CODE_84060(84060, "callee 呼叫号码不支持"), | |||
/** | |||
* 不存在外部联系人的关系. | |||
*/ | |||
CODE_84061(84061, "不存在外部联系人的关系"), | |||
/** | |||
* 未开启公费电话应用. | |||
*/ | |||
CODE_84062(84062, "未开启公费电话应用"), | |||
/** | |||
* caller不存在. | |||
*/ | |||
CODE_84063(84063, "caller不存在"), | |||
/** | |||
* callee不存在. | |||
*/ | |||
CODE_84064(84064, "callee不存在"), | |||
/** | |||
* caller跟callee电话号码一致。排查方法:不允许自己拨打给自己 | |||
*/ | |||
CODE_84065(84065, "caller跟callee电话号码一致。排查方法:不允许自己拨打给自己"), | |||
/** | |||
* 服务商拨打次数超过限制。排查方法:单个企业管理员,在一天(以上午10 | |||
*/ | |||
CODE_84066(84066, "服务商拨打次数超过限制。排查方法:单个企业管理员,在一天(以上午10:00为起始时间)内,对应单个服务商,只能被呼叫【4】次。"), | |||
/** | |||
* 管理员收到的服务商公费电话个数超过限制。排查方法:单个企业管理员,在一天(以上午10 | |||
*/ | |||
CODE_84067(84067, "管理员收到的服务商公费电话个数超过限制。排查方法:单个企业管理员,在一天(以上午10:00为起始时间)内,一共只能被【3】个服务商成功呼叫。"), | |||
/** | |||
* 拨打方被限制拨打公费电话. | |||
*/ | |||
CODE_84069(84069, "拨打方被限制拨打公费电话"), | |||
/** | |||
* 不支持的电话号码。排查方法:拨打方或者被拨打方电话号码不支持 | |||
*/ | |||
CODE_84070(84070, "不支持的电话号码。排查方法:拨打方或者被拨打方电话号码不支持"), | |||
/** | |||
* 不合法的外部联系人授权码。排查方法:非法或者已经消费过 | |||
*/ | |||
CODE_84071(84071, "不合法的外部联系人授权码。排查方法:非法或者已经消费过"), | |||
/** | |||
* 应用未配置客服. | |||
*/ | |||
CODE_84072(84072, "应用未配置客服"), | |||
/** | |||
* 客服userid不在应用配置的客服列表中. | |||
*/ | |||
CODE_84073(84073, "客服userid不在应用配置的客服列表中"), | |||
/** | |||
* 没有外部联系人权限. | |||
*/ | |||
CODE_84074(84074, "没有外部联系人权限"), | |||
/** | |||
* 不合法或过期的authcode. | |||
*/ | |||
CODE_84075(84075, "不合法或过期的authcode"), | |||
/** | |||
* 缺失authcode. | |||
*/ | |||
CODE_84076(84076, "缺失authcode"), | |||
/** | |||
* 订单价格过高,无法受理. | |||
*/ | |||
CODE_84077(84077, "订单价格过高,无法受理"), | |||
/** | |||
* 购买人数不正确. | |||
*/ | |||
CODE_84078(84078, "购买人数不正确"), | |||
/** | |||
* 价格策略不存在. | |||
*/ | |||
CODE_84079(84079, "价格策略不存在"), | |||
/** | |||
* 订单不存在. | |||
*/ | |||
CODE_84080(84080, "订单不存在"), | |||
/** | |||
* 存在未支付订单. | |||
*/ | |||
CODE_84081(84081, "存在未支付订单"), | |||
/** | |||
* 存在申请退款中的订单. | |||
*/ | |||
CODE_84082(84082, "存在申请退款中的订单"), | |||
/** | |||
* 非服务人员. | |||
*/ | |||
CODE_84083(84083, "非服务人员"), | |||
/** | |||
* 非跟进用户. | |||
*/ | |||
CODE_84084(84084, "非跟进用户"), | |||
/** | |||
* 应用已下架. | |||
*/ | |||
CODE_84085(84085, "应用已下架"), | |||
/** | |||
* 订单人数超过可购买最大人数. | |||
*/ | |||
CODE_84086(84086, "订单人数超过可购买最大人数"), | |||
/** | |||
* 打开订单支付前禁止关闭订单. | |||
*/ | |||
CODE_84087(84087, "打开订单支付前禁止关闭订单"), | |||
/** | |||
* 禁止关闭已支付的订单. | |||
*/ | |||
CODE_84088(84088, "禁止关闭已支付的订单"), | |||
/** | |||
* 订单已支付. | |||
*/ | |||
CODE_84089(84089, "订单已支付"), | |||
/** | |||
* 缺失user_ticket. | |||
*/ | |||
CODE_84090(84090, "缺失user_ticket"), | |||
/** | |||
* 订单价格不可低于下限. | |||
*/ | |||
CODE_84091(84091, "订单价格不可低于下限"), | |||
/** | |||
* 无法发起代下单操作. | |||
*/ | |||
CODE_84092(84092, "无法发起代下单操作"), | |||
/** | |||
* 代理关系已占用,无法代下单. | |||
*/ | |||
CODE_84093(84093, "代理关系已占用,无法代下单"), | |||
/** | |||
* 该应用未配置代理分润规则,请先联系应用服务商处理. | |||
*/ | |||
CODE_84094(84094, "该应用未配置代理分润规则,请先联系应用服务商处理"), | |||
/** | |||
* 免费试用版,无法扩容. | |||
*/ | |||
CODE_84095(84095, "免费试用版,无法扩容"), | |||
/** | |||
* 免费试用版,无法续期. | |||
*/ | |||
CODE_84096(84096, "免费试用版,无法续期"), | |||
/** | |||
* 当前企业有未处理订单. | |||
*/ | |||
CODE_84097(84097, "当前企业有未处理订单"), | |||
/** | |||
* 固定总量,无法扩容. | |||
*/ | |||
CODE_84098(84098, "固定总量,无法扩容"), | |||
/** | |||
* 非购买状态,无法扩容. | |||
*/ | |||
CODE_84099(84099, "非购买状态,无法扩容"), | |||
/** | |||
* 未购买过此应用,无法续期. | |||
*/ | |||
CODE_84100(84100, "未购买过此应用,无法续期"), | |||
/** | |||
* 企业已试用付费版本,无法全新购买. | |||
*/ | |||
CODE_84101(84101, "企业已试用付费版本,无法全新购买"), | |||
/** | |||
* 企业当前应用状态已过期,无法扩容. | |||
*/ | |||
CODE_84102(84102, "企业当前应用状态已过期,无法扩容"), | |||
/** | |||
* 仅可修改未支付订单. | |||
*/ | |||
CODE_84103(84103, "仅可修改未支付订单"), | |||
/** | |||
* 订单已支付,无法修改. | |||
*/ | |||
CODE_84104(84104, "订单已支付,无法修改"), | |||
/** | |||
* 订单已被取消,无法修改. | |||
*/ | |||
CODE_84105(84105, "订单已被取消,无法修改"), | |||
/** | |||
* 企业含有该应用的待支付订单,无法代下单. | |||
*/ | |||
CODE_84106(84106, "企业含有该应用的待支付订单,无法代下单"), | |||
/** | |||
* 企业含有该应用的退款中订单,无法代下单. | |||
*/ | |||
CODE_84107(84107, "企业含有该应用的退款中订单,无法代下单"), | |||
/** | |||
* 企业含有该应用的待生效订单,无法代下单. | |||
*/ | |||
CODE_84108(84108, "企业含有该应用的待生效订单,无法代下单"), | |||
/** | |||
* 订单定价不能未0. | |||
*/ | |||
CODE_84109(84109, "订单定价不能未0"), | |||
/** | |||
* 新安装应用不在试用状态,无法升级为付费版. | |||
*/ | |||
CODE_84110(84110, "新安装应用不在试用状态,无法升级为付费版"), | |||
/** | |||
* 无足够可用优惠券. | |||
*/ | |||
CODE_84111(84111, "无足够可用优惠券"), | |||
/** | |||
* 无法关闭未支付订单. | |||
*/ | |||
CODE_84112(84112, "无法关闭未支付订单"), | |||
/** | |||
* 无付费信息. | |||
*/ | |||
CODE_84113(84113, "无付费信息"), | |||
/** | |||
* 虚拟版本不支持下单. | |||
*/ | |||
CODE_84114(84114, "虚拟版本不支持下单"), | |||
/** | |||
* 虚拟版本不支持扩容. | |||
*/ | |||
CODE_84115(84115, "虚拟版本不支持扩容"), | |||
/** | |||
* 虚拟版本不支持续期. | |||
*/ | |||
CODE_84116(84116, "虚拟版本不支持续期"), | |||
/** | |||
* 在虚拟正式版期内不能扩容. | |||
*/ | |||
CODE_84117(84117, "在虚拟正式版期内不能扩容"), | |||
/** | |||
* 虚拟正式版期内不能变更版本. | |||
*/ | |||
CODE_84118(84118, "虚拟正式版期内不能变更版本"), | |||
/** | |||
* 当前企业未报备,无法进行代下单. | |||
*/ | |||
CODE_84119(84119, "当前企业未报备,无法进行代下单"), | |||
/** | |||
* 当前应用版本已删除. | |||
*/ | |||
CODE_84120(84120, "当前应用版本已删除"), | |||
/** | |||
* 应用版本已删除,无法扩容. | |||
*/ | |||
CODE_84121(84121, "应用版本已删除,无法扩容"), | |||
/** | |||
* 应用版本已删除,无法续期. | |||
*/ | |||
CODE_84122(84122, "应用版本已删除,无法续期"), | |||
/** | |||
* 非虚拟版本,无法升级. | |||
*/ | |||
CODE_84123(84123, "非虚拟版本,无法升级"), | |||
/** | |||
* 非行业方案订单,不能添加部分应用版本的订单. | |||
*/ | |||
CODE_84124(84124, "非行业方案订单,不能添加部分应用版本的订单"), | |||
/** | |||
* 购买人数不能少于最少购买人数. | |||
*/ | |||
CODE_84125(84125, "购买人数不能少于最少购买人数"), | |||
/** | |||
* 购买人数不能多于最大购买人数. | |||
*/ | |||
CODE_84126(84126, "购买人数不能多于最大购买人数"), | |||
/** | |||
* 无应用管理权限. | |||
*/ | |||
CODE_84127(84127, "无应用管理权限"), | |||
/** | |||
* 无该行业方案下全部应用的管理权限. | |||
*/ | |||
CODE_84128(84128, "无该行业方案下全部应用的管理权限"), | |||
/** | |||
* 付费策略已被删除,无法下单. | |||
*/ | |||
CODE_84129(84129, "付费策略已被删除,无法下单"), | |||
/** | |||
* 订单生效时间不合法. | |||
*/ | |||
CODE_84130(84130, "订单生效时间不合法"), | |||
/** | |||
* 文件转译解析错误。排查方法:只支持utf8文件转译,可能是不支持的文件类型或者格式 | |||
*/ | |||
CODE_84200(84200, "文件转译解析错误。排查方法:只支持utf8文件转译,可能是不支持的文件类型或者格式"), | |||
/** | |||
* 包含不合法的词语. | |||
*/ | |||
@@ -85,7 +85,7 @@ public interface WxCpExternalContactService { | |||
* @return List of CpUser id | |||
* @throws WxErrorException . | |||
*/ | |||
List<String> listFollowUser() throws WxErrorException; | |||
List<String> listFollowers() throws WxErrorException; | |||
/** | |||
* 企业和第三方可通过此接口,获取所有离职成员的客户列表,并可进一步调用离职成员的外部联系人再分配接口将这些客户重新分配给其他企业成员。 | |||
@@ -2,23 +2,26 @@ package me.chanjar.weixin.cp.api.impl; | |||
import com.google.gson.Gson; | |||
import com.google.gson.JsonObject; | |||
import lombok.RequiredArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxCpErrorMsgEnum; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.cp.api.WxCpExternalContactService; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import me.chanjar.weixin.cp.bean.*; | |||
import org.apache.commons.lang3.ArrayUtils; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import java.util.List; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.ExternalContact.*; | |||
/** | |||
* @author 曹祖鹏 & yuanqixun | |||
*/ | |||
@RequiredArgsConstructor | |||
public class WxCpExternalContactServiceImpl implements WxCpExternalContactService { | |||
private WxCpService mainService; | |||
public WxCpExternalContactServiceImpl(WxCpService mainService) { | |||
this.mainService = mainService; | |||
} | |||
private final WxCpService mainService; | |||
@Override | |||
public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException { | |||
@@ -37,22 +40,30 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||
@Override | |||
public List<String> listExternalContacts(String userId) throws WxErrorException { | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId); | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserExternalContactList.fromJson(responseContent).getExternalUserId(); | |||
try { | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserExternalContactList.fromJson(responseContent).getExternalUserId(); | |||
} catch (WxErrorException e) { | |||
// not external contact,无客户则返回空列表 | |||
if (e.getError().getErrorCode() == WxCpErrorMsgEnum.CODE_84061.getCode()) { | |||
return Collections.emptyList(); | |||
} | |||
throw e; | |||
} | |||
} | |||
@Override | |||
public List<String> listFollowUser() throws WxErrorException { | |||
public List<String> listFollowers() throws WxErrorException { | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_FOLLOW_USER_LIST); | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserWithExternalPermission.fromJson(responseContent).getFollowUser(); | |||
return WxCpUserWithExternalPermission.fromJson(responseContent).getFollowers(); | |||
} | |||
@Override | |||
public WxCpUserExternalUnassignList listUnassignedList(Integer pageIndex, Integer pageSize) throws WxErrorException { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("page_id",pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("page_size",pageSize == null ? 100 : pageSize); | |||
json.addProperty("page_id", pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("page_size", pageSize == null ? 100 : pageSize); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_UNASSIGNED_CONTACT); | |||
final String result = this.mainService.post(url, json.toString()); | |||
return WxCpUserExternalUnassignList.fromJson(result); | |||
@@ -72,18 +83,18 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||
@Override | |||
public WxCpUserExternalGroupChatList listGroupChat(Integer pageIndex, Integer pageSize, int status, String[] userIds, String[] partyIds) throws WxErrorException { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("offset",pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("limit",pageSize == null ? 100 : pageSize); | |||
json.addProperty("status_filter",status); | |||
if(ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)){ | |||
json.addProperty("offset", pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("limit", pageSize == null ? 100 : pageSize); | |||
json.addProperty("status_filter", status); | |||
if (ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)) { | |||
JsonObject ownerFilter = new JsonObject(); | |||
if(ArrayUtils.isNotEmpty(userIds)){ | |||
if (ArrayUtils.isNotEmpty(userIds)) { | |||
json.add("userid", new Gson().toJsonTree(userIds).getAsJsonArray()); | |||
} | |||
if(ArrayUtils.isNotEmpty(partyIds)){ | |||
if (ArrayUtils.isNotEmpty(partyIds)) { | |||
json.add("partyid", new Gson().toJsonTree(partyIds).getAsJsonArray()); | |||
} | |||
json.add("owner_filter",ownerFilter); | |||
json.add("owner_filter", ownerFilter); | |||
} | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GROUP_CHAT_LIST); | |||
final String result = this.mainService.post(url, json.toString()); | |||
@@ -102,13 +113,13 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||
@Override | |||
public WxCpUserExternalUserBehaviorStatistic getUserBehaviorStatistic(Date startTime, Date endTime, String[] userIds, String[] partyIds) throws WxErrorException { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("start_time", startTime.getTime()/1000); | |||
json.addProperty("end_time", endTime.getTime()/1000); | |||
if(ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)){ | |||
if(ArrayUtils.isNotEmpty(userIds)){ | |||
json.addProperty("start_time", startTime.getTime() / 1000); | |||
json.addProperty("end_time", endTime.getTime() / 1000); | |||
if (ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)) { | |||
if (ArrayUtils.isNotEmpty(userIds)) { | |||
json.add("userid", new Gson().toJsonTree(userIds).getAsJsonArray()); | |||
} | |||
if(ArrayUtils.isNotEmpty(partyIds)){ | |||
if (ArrayUtils.isNotEmpty(partyIds)) { | |||
json.add("partyid", new Gson().toJsonTree(partyIds).getAsJsonArray()); | |||
} | |||
} | |||
@@ -120,20 +131,20 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||
@Override | |||
public WxCpUserExternalGroupChatStatistic getGroupChatStatistic(Date startTime, Integer orderBy, Integer orderAsc, Integer pageIndex, Integer pageSize, String[] userIds, String[] partyIds) throws WxErrorException { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("day_begin_time", startTime.getTime()/1000); | |||
json.addProperty("day_begin_time", startTime.getTime() / 1000); | |||
json.addProperty("order_by", orderBy == null ? 1 : orderBy); | |||
json.addProperty("order_asc",orderAsc == null ? 0 : orderAsc); | |||
json.addProperty("offset",pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("limit",pageSize == null ? 500 : pageSize); | |||
if(ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)){ | |||
json.addProperty("order_asc", orderAsc == null ? 0 : orderAsc); | |||
json.addProperty("offset", pageIndex == null ? 0 : pageIndex); | |||
json.addProperty("limit", pageSize == null ? 500 : pageSize); | |||
if (ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)) { | |||
JsonObject ownerFilter = new JsonObject(); | |||
if(ArrayUtils.isNotEmpty(userIds)){ | |||
if (ArrayUtils.isNotEmpty(userIds)) { | |||
json.add("userid_list", new Gson().toJsonTree(userIds).getAsJsonArray()); | |||
} | |||
if(ArrayUtils.isNotEmpty(partyIds)){ | |||
if (ArrayUtils.isNotEmpty(partyIds)) { | |||
json.add("userid_list", new Gson().toJsonTree(partyIds).getAsJsonArray()); | |||
} | |||
json.add("owner_filter",ownerFilter); | |||
json.add("owner_filter", ownerFilter); | |||
} | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_GROUP_CHAT_DATA); | |||
final String result = this.mainService.post(url, json.toString()); | |||
@@ -2,46 +2,26 @@ package me.chanjar.weixin.cp.bean; | |||
import com.google.gson.annotations.Expose; | |||
import com.google.gson.annotations.SerializedName; | |||
import lombok.Data; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import java.util.List; | |||
/** | |||
* @author 曹祖鹏 | |||
*/ | |||
@Data | |||
public class WxCpUserWithExternalPermission { | |||
@SerializedName("errcode") | |||
@Expose | |||
private Long errcode; | |||
private Long errCode; | |||
@SerializedName("errmsg") | |||
@Expose | |||
private String errmsg; | |||
private String errMsg; | |||
@SerializedName("follow_user") | |||
@Expose | |||
private List<String> followUser = null; | |||
public Long getErrcode() { | |||
return errcode; | |||
} | |||
public void setErrcode(Long errcode) { | |||
this.errcode = errcode; | |||
} | |||
public String getErrmsg() { | |||
return errmsg; | |||
} | |||
public void setErrmsg(String errmsg) { | |||
this.errmsg = errmsg; | |||
} | |||
public List<String> getFollowUser() { | |||
return followUser; | |||
} | |||
public void setFollowUser(List<String> followUser) { | |||
this.followUser = followUser; | |||
} | |||
private List<String> followers = null; | |||
public static WxCpUserWithExternalPermission fromJson(String json) { | |||
return WxCpGsonBuilder.create().fromJson(json, WxCpUserWithExternalPermission.class); | |||
@@ -38,7 +38,7 @@ public class WxCpExternalContactServiceImplTest { | |||
@Test | |||
public void testListExternalWithPermission() throws WxErrorException { | |||
List<String> ret = this.wxCpService.getExternalContactService().listFollowUser(); | |||
List<String> ret = this.wxCpService.getExternalContactService().listFollowers(); | |||
System.out.println(ret); | |||
assertNotNull(ret); | |||
} | |||