| @@ -24,7 +24,7 @@ public interface WxMpKefuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 获取客服基本信息 | * 获取客服基本信息 | ||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @@ -33,7 +33,7 @@ public interface WxMpKefuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 获取在线客服接待信息 | * 获取在线客服接待信息 | ||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @@ -42,7 +42,7 @@ public interface WxMpKefuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 添加客服账号 | * 添加客服账号 | ||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @@ -50,17 +50,26 @@ public interface WxMpKefuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 设置客服信息(更新) | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 设置客服信息(即更新客服信息) | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; | boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 设置客服信息(即更新客服信息) | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| */ | |||||
| boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 上传客服头像 | * 上传客服头像 | ||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | * 接口url格式:http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @@ -70,7 +79,7 @@ public interface WxMpKefuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 删除客服账号 | * 删除客服账号 | ||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||||
| * 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN">客服管理</a> | |||||
| * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @@ -62,6 +62,14 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||||
| return true; | return true; | ||||
| } | } | ||||
| @Override | |||||
| public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { | |||||
| String url = "https://api.weixin.qq.com/customservice/kfaccount/inviteworker"; | |||||
| this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||||
| request.toJson()); | |||||
| return true; | |||||
| } | |||||
| @Override | @Override | ||||
| public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | ||||
| throws WxErrorException { | throws WxErrorException { | ||||
| @@ -23,18 +23,12 @@ public class WxMpKfAccountRequest implements Serializable { | |||||
| */ | */ | ||||
| @SerializedName("nickname") | @SerializedName("nickname") | ||||
| private String nickName; | private String nickName; | ||||
| /** | |||||
| * password 客服账号登录密码,格式为密码明文的32位加密MD5值 | |||||
| */ | |||||
| @SerializedName("password") | |||||
| private String password; | |||||
| /** | /** | ||||
| * rawPassword 客服账号登录密码,明文密码,仅用于辅助操作 | |||||
| * invite_wx 接收绑定邀请的客服微信号 | |||||
| */ | */ | ||||
| @SerializedName("rawPassword") | |||||
| private String rawPassword; | |||||
| @SerializedName("invite_wx") | |||||
| private String inviteWx; | |||||
| @Override | @Override | ||||
| public String toString() { | public String toString() { | ||||
| @@ -61,31 +55,22 @@ public class WxMpKfAccountRequest implements Serializable { | |||||
| this.nickName = nickName; | this.nickName = nickName; | ||||
| } | } | ||||
| public String getPassword() { | |||||
| return this.password; | |||||
| } | |||||
| public void setPassword(String password) { | |||||
| this.password = password; | |||||
| } | |||||
| public String getRawPassword() { | |||||
| return this.rawPassword; | |||||
| public static Builder builder() { | |||||
| return new Builder(); | |||||
| } | } | ||||
| public void setRawPassword(String rawPassword) { | |||||
| this.rawPassword = rawPassword; | |||||
| public String getInviteWx() { | |||||
| return this.inviteWx; | |||||
| } | } | ||||
| public static Builder builder() { | |||||
| return new Builder(); | |||||
| public void setInviteWx(String inviteWx) { | |||||
| this.inviteWx = inviteWx; | |||||
| } | } | ||||
| public static class Builder { | public static class Builder { | ||||
| private String kfAccount; | private String kfAccount; | ||||
| private String nickName; | private String nickName; | ||||
| private String password; | |||||
| private String rawPassword; | |||||
| private String inviteWx; | |||||
| @SuppressWarnings("hiding") | @SuppressWarnings("hiding") | ||||
| public Builder kfAccount(String kfAccount) { | public Builder kfAccount(String kfAccount) { | ||||
| @@ -100,23 +85,15 @@ public class WxMpKfAccountRequest implements Serializable { | |||||
| } | } | ||||
| @SuppressWarnings("hiding") | @SuppressWarnings("hiding") | ||||
| public Builder password(String password) { | |||||
| this.password = password; | |||||
| return this; | |||||
| } | |||||
| @SuppressWarnings("hiding") | |||||
| public Builder rawPassword(String rawPassword) { | |||||
| this.rawPassword = rawPassword; | |||||
| this.password(Md5Crypt.md5Crypt(rawPassword.getBytes())); | |||||
| return this; | |||||
| public Builder inviteWx(String inviteWx) { | |||||
| this.inviteWx = inviteWx; | |||||
| return this; | |||||
| } | } | ||||
| public Builder from(WxMpKfAccountRequest origin) { | public Builder from(WxMpKfAccountRequest origin) { | ||||
| this.kfAccount(origin.kfAccount); | this.kfAccount(origin.kfAccount); | ||||
| this.nickName(origin.nickName); | this.nickName(origin.nickName); | ||||
| this.password(origin.password); | |||||
| this.rawPassword(origin.rawPassword); | |||||
| this.inviteWx(origin.inviteWx); | |||||
| return this; | return this; | ||||
| } | } | ||||
| @@ -124,8 +101,7 @@ public class WxMpKfAccountRequest implements Serializable { | |||||
| WxMpKfAccountRequest m = new WxMpKfAccountRequest(); | WxMpKfAccountRequest m = new WxMpKfAccountRequest(); | ||||
| m.kfAccount = this.kfAccount; | m.kfAccount = this.kfAccount; | ||||
| m.nickName = this.nickName; | m.nickName = this.nickName; | ||||
| m.password = this.password; | |||||
| m.rawPassword = this.rawPassword; | |||||
| m.inviteWx = this.inviteWx; | |||||
| return m; | return m; | ||||
| } | } | ||||
| } | } | ||||
| @@ -41,17 +41,34 @@ public class WxMpKfInfo implements Serializable { | |||||
| private String nick; | private String nick; | ||||
| /** | /** | ||||
| * status 客服在线状态 1:pc在线,2:手机在线。若pc和手机同时在线则为 1+2=3 | |||||
| * kf_wx 如果客服帐号已绑定了客服人员微信号,则此处显示微信号 | |||||
| */ | */ | ||||
| @SerializedName("status") | |||||
| private Integer status; | |||||
| @SerializedName("kf_wx") | |||||
| private String wxAccount; | |||||
| /** | /** | ||||
| * auto_accept 客服设置的最大自动接入数 | |||||
| * invite_wx 如果客服帐号尚未绑定微信号,但是已经发起了一个绑定邀请,则此处显示绑定邀请的微信号 | |||||
| */ | */ | ||||
| @Expose | |||||
| @SerializedName("auto_accept") | |||||
| private Integer autoAccept; | |||||
| @SerializedName("invite_wx") | |||||
| private String inviteWx; | |||||
| /** | |||||
| * invite_expire_time 如果客服帐号尚未绑定微信号,但是已经发起过一个绑定邀请,则此处显示为邀请的过期时间,为unix 时间戳 | |||||
| */ | |||||
| @SerializedName("invite_expire_time") | |||||
| private Long inviteExpireTime; | |||||
| /** | |||||
| * invite_status 邀请的状态,有等待确认“waiting”,被拒绝“rejected”,过期“expired” | |||||
| */ | |||||
| @SerializedName("invite_status") | |||||
| private String inviteStatus; | |||||
| /** | |||||
| * status 客服在线状态,目前为:1、web 在线 | |||||
| */ | |||||
| @SerializedName("status") | |||||
| private Integer status; | |||||
| /** | /** | ||||
| * accepted_case 客服当前正在接待的会话数 | * accepted_case 客服当前正在接待的会话数 | ||||
| @@ -68,14 +85,6 @@ public class WxMpKfInfo implements Serializable { | |||||
| this.status = status; | this.status = status; | ||||
| } | } | ||||
| public Integer getAutoAccept() { | |||||
| return this.autoAccept; | |||||
| } | |||||
| public void setAutoAccept(Integer autoAccept) { | |||||
| this.autoAccept = autoAccept; | |||||
| } | |||||
| public Integer getAcceptedCase() { | public Integer getAcceptedCase() { | ||||
| return this.acceptedCase; | return this.acceptedCase; | ||||
| } | } | ||||
| @@ -120,4 +129,36 @@ public class WxMpKfInfo implements Serializable { | |||||
| public String toString() { | public String toString() { | ||||
| return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | ||||
| } | } | ||||
| public String getWxAccount() { | |||||
| return this.wxAccount; | |||||
| } | |||||
| public void setWxAccount(String wxAccount) { | |||||
| this.wxAccount = wxAccount; | |||||
| } | |||||
| public String getInviteWx() { | |||||
| return this.inviteWx; | |||||
| } | |||||
| public void setInviteWx(String inviteWx) { | |||||
| this.inviteWx = inviteWx; | |||||
| } | |||||
| public Long getInviteExpireTime() { | |||||
| return this.inviteExpireTime; | |||||
| } | |||||
| public void setInviteExpireTime(Long inviteExpireTime) { | |||||
| this.inviteExpireTime = inviteExpireTime; | |||||
| } | |||||
| public String getInviteStatus() { | |||||
| return this.inviteStatus; | |||||
| } | |||||
| public void setInviteStatus(String inviteStatus) { | |||||
| this.inviteStatus = inviteStatus; | |||||
| } | |||||
| } | } | ||||
| @@ -60,7 +60,7 @@ public class WxMpKefuServiceImplTest { | |||||
| @Test(dataProvider = "getKfAccount") | @Test(dataProvider = "getKfAccount") | ||||
| public void testKfAccountAdd(String kfAccount) throws WxErrorException { | public void testKfAccountAdd(String kfAccount) throws WxErrorException { | ||||
| WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | ||||
| .kfAccount(kfAccount).nickName("我晕").rawPassword("123").build(); | |||||
| .kfAccount(kfAccount).nickName("我晕").build(); | |||||
| Assert.assertTrue(this.wxService.getKefuService().kfAccountAdd(request)); | Assert.assertTrue(this.wxService.getKefuService().kfAccountAdd(request)); | ||||
| } | } | ||||
| @@ -68,10 +68,18 @@ public class WxMpKefuServiceImplTest { | |||||
| "testKfAccountAdd" }, dataProvider = "getKfAccount") | "testKfAccountAdd" }, dataProvider = "getKfAccount") | ||||
| public void testKfAccountUpdate(String kfAccount) throws WxErrorException { | public void testKfAccountUpdate(String kfAccount) throws WxErrorException { | ||||
| WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | ||||
| .kfAccount(kfAccount).nickName("我晕").rawPassword("123").build(); | |||||
| .kfAccount(kfAccount).nickName("我晕").build(); | |||||
| Assert.assertTrue(this.wxService.getKefuService().kfAccountUpdate(request)); | Assert.assertTrue(this.wxService.getKefuService().kfAccountUpdate(request)); | ||||
| } | } | ||||
| @Test(dependsOnMethods = { | |||||
| "testKfAccountAdd" }, dataProvider = "getKfAccount") | |||||
| public void testKfAccountInviteWorker(String kfAccount) throws WxErrorException { | |||||
| WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | |||||
| .kfAccount(kfAccount).inviteWx("www_ucredit_com").build(); | |||||
| Assert.assertTrue(this.wxService.getKefuService().kfAccountInviteWorker(request)); | |||||
| } | |||||
| @Test(dependsOnMethods = { | @Test(dependsOnMethods = { | ||||
| "testKfAccountUpdate" }, dataProvider = "getKfAccount") | "testKfAccountUpdate" }, dataProvider = "getKfAccount") | ||||
| public void testKfAccountUploadHeadImg(String kfAccount) | public void testKfAccountUploadHeadImg(String kfAccount) | ||||