mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 18:46:10 +08:00 
			
		
		
		
	添加多客服中客服管理的6个接口
This commit is contained in:
		| @ -0,0 +1,15 @@ | |||||||
|  | package me.chanjar.weixin.mp.api; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | public interface WxMpBaseChildService { | ||||||
|  |   /** | ||||||
|  |    * 设置WxMpService对象 | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   void setWxMpService(WxMpService wxMpService); | ||||||
|  | } | ||||||
| @ -0,0 +1,73 @@ | |||||||
|  | package me.chanjar.weixin.mp.api; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.common.exception.WxErrorException; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 客服接口 , | ||||||
|  |  * 命名采用kefu拼音的原因是: | ||||||
|  |  * 其英文CustomerService如果再加上Service后缀显得有点啰嗦, | ||||||
|  |  * 如果不加又显得表意不完整 | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public interface WxMpKefuService  extends WxMpBaseChildService {   | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 获取客服基本信息 | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   WxMpKfList kfList() throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 获取在线客服接待信息 | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   WxMpKfOnlineList kfOnlineList() throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 添加客服账号 | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 设置客服信息(更新) | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 上传客服头像 | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |    | ||||||
|  |   boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 删除客服账号 | ||||||
|  |    * 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | ||||||
|  |    * https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   boolean kfAccountDel(String kfAccount) throws WxErrorException; | ||||||
|  | } | ||||||
| @ -1,14 +1,5 @@ | |||||||
| package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||||
|  |  | ||||||
| import me.chanjar.weixin.common.bean.WxCardApiSignature; |  | ||||||
| import me.chanjar.weixin.common.bean.WxMenu; |  | ||||||
| import me.chanjar.weixin.common.bean.WxJsapiSignature; |  | ||||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; |  | ||||||
| import me.chanjar.weixin.common.exception.WxErrorException; |  | ||||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; |  | ||||||
| import me.chanjar.weixin.mp.bean.*; |  | ||||||
| import me.chanjar.weixin.mp.bean.result.*; |  | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| @ -17,6 +8,47 @@ import java.util.Date; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.common.bean.WxCardApiSignature; | ||||||
|  | import me.chanjar.weixin.common.bean.WxJsapiSignature; | ||||||
|  | import me.chanjar.weixin.common.bean.WxMenu; | ||||||
|  | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||||
|  | import me.chanjar.weixin.common.exception.WxErrorException; | ||||||
|  | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpGroup; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpIndustry; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMassNews; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMassVideo; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMaterial; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpMaterialNews; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMediaImgUploadResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpCardResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMaterialFileBatchGetResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMaterialNewsBatchGetResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMaterialUploadResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpPayResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpUser; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpUserList; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; | ||||||
|  | import me.chanjar.weixin.mp.bean.result.WxRedpackResult; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 微信API的Service |  * 微信API的Service | ||||||
|  */ |  */ | ||||||
| @ -1001,4 +1033,11 @@ public interface WxMpService { | |||||||
|    * @throws WxErrorException |    * @throws WxErrorException | ||||||
|    */ |    */ | ||||||
|   WxMpIndustry getIndustry() throws WxErrorException; |   WxMpIndustry getIndustry() throws WxErrorException; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * 返回客服接口方法实现类,以方便调用个其各种接口 | ||||||
|  |    * @return WxMpKefuService | ||||||
|  |    */  | ||||||
|  |   WxMpKefuService getKefuService(); | ||||||
|  |    | ||||||
| } | } | ||||||
|  | |||||||
| @ -75,6 +75,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||||
|  |  | ||||||
|   protected WxMpConfigStorage wxMpConfigStorage; |   protected WxMpConfigStorage wxMpConfigStorage; | ||||||
|    |    | ||||||
|  |   protected WxMpKefuService kefuService; | ||||||
|  |  | ||||||
|   protected CloseableHttpClient httpClient; |   protected CloseableHttpClient httpClient; | ||||||
|  |  | ||||||
|   protected HttpHost httpProxy; |   protected HttpHost httpProxy; | ||||||
| @ -1369,4 +1371,14 @@ public class WxMpServiceImpl implements WxMpService { | |||||||
|     String responseContent = execute(new SimpleGetRequestExecutor(), url, null); |     String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | ||||||
|     return WxMpIndustry.fromJson(responseContent); |     return WxMpIndustry.fromJson(responseContent); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public WxMpKefuService getKefuService() { | ||||||
|  |     return this.kefuService; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   public void setCustomerService(WxMpKefuService kefuService) { | ||||||
|  |     this.kefuService = kefuService; | ||||||
|  |     this.kefuService.setWxMpService(this); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,72 @@ | |||||||
|  | package me.chanjar.weixin.mp.api.impl; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.common.exception.WxErrorException; | ||||||
|  | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||||
|  | import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | ||||||
|  | import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | ||||||
|  | import me.chanjar.weixin.mp.api.WxMpKefuService; | ||||||
|  | import me.chanjar.weixin.mp.api.WxMpService; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class WxMpKefuServiceImpl implements WxMpKefuService { | ||||||
|  |   private WxMpService wxMpService; | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public void setWxMpService(WxMpService wxMpService) { | ||||||
|  |     this.wxMpService = wxMpService; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public WxMpKfList kfList() throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist"; | ||||||
|  |     String responseContent = this.wxMpService.execute( | ||||||
|  |           new SimpleGetRequestExecutor(), url, null); | ||||||
|  |     return WxMpKfList.fromJson(responseContent); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public WxMpKfOnlineList kfOnlineList() throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist"; | ||||||
|  |     String responseContent = this.wxMpService.execute( | ||||||
|  |           new SimpleGetRequestExecutor(), url, null); | ||||||
|  |     return WxMpKfOnlineList.fromJson(responseContent); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/customservice/kfaccount/add"; | ||||||
|  |     this.wxMpService.execute(new SimplePostRequestExecutor(), url, request.toJson()); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/customservice/kfaccount/update"; | ||||||
|  |     this.wxMpService.execute(new SimplePostRequestExecutor(), url, request.toJson()); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account=" + kfAccount ; | ||||||
|  |     this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean kfAccountDel(String kfAccount) throws WxErrorException { | ||||||
|  |     String url = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=" + kfAccount; | ||||||
|  |     this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,133 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.customerservice.request; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  |  | ||||||
|  | import org.apache.commons.codec.digest.Md5Crypt; | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||||
|  |  | ||||||
|  | public class WxMpKfAccountRequest implements Serializable { | ||||||
|  |   private static final long serialVersionUID = -5451863610674856927L; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * kf_account   完整客服账号,格式为:账号前缀@公众号微信号 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("kf_account") | ||||||
|  |   private String kfAccount; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * nickname   客服昵称,最长6个汉字或12个英文字符 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("nickname") | ||||||
|  |   private String nickName; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * password   客服账号登录密码,格式为密码明文的32位加密MD5值 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("password") | ||||||
|  |   private String password; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * rawPassword   客服账号登录密码,明文密码,仅用于辅助操作 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("rawPassword") | ||||||
|  |   private String rawPassword; | ||||||
|  |    | ||||||
|  |   @Override | ||||||
|  |   public String toString() { | ||||||
|  |     return ToStringBuilder.reflectionToString(this); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   public String toJson() { | ||||||
|  |     return WxMpGsonBuilder.INSTANCE.create().toJson(this); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getKfAccount() { | ||||||
|  |     return this.kfAccount; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setKfAccount(String kfAccount) { | ||||||
|  |     this.kfAccount = kfAccount; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getNickName() { | ||||||
|  |     return this.nickName; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setNickName(String 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 void setRawPassword(String rawPassword) { | ||||||
|  |     this.rawPassword = rawPassword; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public static Builder builder() { | ||||||
|  |       return new Builder(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public static class Builder { | ||||||
|  |       private String kfAccount; | ||||||
|  |       private String nickName; | ||||||
|  |       private String password; | ||||||
|  |       private String rawPassword; | ||||||
|  |  | ||||||
|  |       @SuppressWarnings("hiding") | ||||||
|  |       public Builder kfAccount(String kfAccount) { | ||||||
|  |           this.kfAccount = kfAccount; | ||||||
|  |           return this; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       @SuppressWarnings("hiding") | ||||||
|  |       public Builder nickName(String nickName) { | ||||||
|  |           this.nickName = nickName; | ||||||
|  |           return this; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       @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 from(WxMpKfAccountRequest origin) { | ||||||
|  |           this.kfAccount(origin.kfAccount); | ||||||
|  |           this.nickName(origin.nickName); | ||||||
|  |           this.password(origin.password); | ||||||
|  |           this.rawPassword(origin.rawPassword); | ||||||
|  |           return this; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       public WxMpKfAccountRequest build() { | ||||||
|  |           WxMpKfAccountRequest m = new WxMpKfAccountRequest(); | ||||||
|  |           m.kfAccount = this.kfAccount; | ||||||
|  |           m.nickName = this.nickName; | ||||||
|  |           m.password = this.password; | ||||||
|  |           m.rawPassword = this.rawPassword; | ||||||
|  |           return m; | ||||||
|  |       } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,123 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.customerservice.result; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.Expose; | ||||||
|  | import com.google.gson.annotations.SerializedName; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 客服基本信息以及客服在线状态信息 | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class WxMpKfInfo implements Serializable { | ||||||
|  |   private static final long serialVersionUID = -5877300750666022290L; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * kf_account 完整客服账号,格式为:账号前缀@公众号微信号 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("kf_account") | ||||||
|  |   private String account; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * kf_headimgurl 客服头像地址 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("kf_headimgurl") | ||||||
|  |   private String headImgUrl; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * kf_id 客服工号 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("kf_id") | ||||||
|  |   private String id; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * kf_nick  客服昵称 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("kf_nick") | ||||||
|  |   private String nick; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    *  status 客服在线状态 1:pc在线,2:手机在线。若pc和手机同时在线则为 1+2=3 | ||||||
|  |    */ | ||||||
|  |   @SerializedName("status") | ||||||
|  |   private Integer status; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * auto_accept 客服设置的最大自动接入数 | ||||||
|  |    */ | ||||||
|  |   @Expose | ||||||
|  |   @SerializedName("auto_accept") | ||||||
|  |   private Integer autoAccept; | ||||||
|  |    | ||||||
|  |   /** | ||||||
|  |    * accepted_case 客服当前正在接待的会话数 | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   @Expose | ||||||
|  |   @SerializedName("accepted_case") | ||||||
|  |   private Integer acceptedCase; | ||||||
|  |  | ||||||
|  |   public Integer getStatus() { | ||||||
|  |     return this.status; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setStatus(Integer status) { | ||||||
|  |     this.status = status; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public Integer getAutoAccept() { | ||||||
|  |     return this.autoAccept; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAutoAccept(Integer autoAccept) { | ||||||
|  |     this.autoAccept = autoAccept; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public Integer getAcceptedCase() { | ||||||
|  |     return this.acceptedCase; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAcceptedCase(Integer acceptedCase) { | ||||||
|  |     this.acceptedCase = acceptedCase; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getAccount() { | ||||||
|  |     return this.account; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAccount(String account) { | ||||||
|  |     this.account = account; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getHeadImgUrl() { | ||||||
|  |     return this.headImgUrl; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setHeadImgUrl(String headImgUrl) { | ||||||
|  |     this.headImgUrl = headImgUrl; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getId() { | ||||||
|  |     return this.id; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setId(String id) { | ||||||
|  |     this.id = id; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getNick() { | ||||||
|  |     return this.nick; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setNick(String nick) { | ||||||
|  |     this.nick = nick; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public String toString() { | ||||||
|  |     return ToStringBuilder.reflectionToString(this); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,35 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.customerservice.result; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class WxMpKfList { | ||||||
|  |   @SerializedName("kf_list") | ||||||
|  |   private List<WxMpKfInfo> kfList; | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public String toString() { | ||||||
|  |     return ToStringBuilder.reflectionToString(this); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public List<WxMpKfInfo> getKfList() { | ||||||
|  |     return this.kfList; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setKfList(List<WxMpKfInfo> kfList) { | ||||||
|  |     this.kfList = kfList; | ||||||
|  |   }   | ||||||
|  |    | ||||||
|  |   public static WxMpKfList fromJson(String json) { | ||||||
|  |     return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpKfList.class); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,35 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.customerservice.result; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class WxMpKfOnlineList { | ||||||
|  |   @SerializedName("kf_online_list") | ||||||
|  |   private List<WxMpKfInfo> kfOnlineList; | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public String toString() { | ||||||
|  |     return ToStringBuilder.reflectionToString(this); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   public List<WxMpKfInfo> getKfOnlineList() { | ||||||
|  |     return this.kfOnlineList; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setKfOnlineList(List<WxMpKfInfo> kfOnlineList) { | ||||||
|  |     this.kfOnlineList = kfOnlineList; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public static WxMpKfOnlineList fromJson(String json) { | ||||||
|  |     return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpKfOnlineList.class); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,24 +1,36 @@ | |||||||
| package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  |  | ||||||
| import com.google.inject.Binder; | import com.google.inject.Binder; | ||||||
| import com.google.inject.Module; | import com.google.inject.Module; | ||||||
| import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; |  | ||||||
|  |  | ||||||
| import java.io.InputStream; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||||
|  | import me.chanjar.weixin.mp.api.impl.WxMpKefuServiceImpl; | ||||||
|  |  | ||||||
| public class ApiTestModule implements Module { | public class ApiTestModule implements Module { | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void configure(Binder binder) { |   public void configure(Binder binder) { | ||||||
|     InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); |     try (InputStream is1 = ClassLoader | ||||||
|     WxXmlMpInMemoryConfigStorage config = fromXml(WxXmlMpInMemoryConfigStorage.class, is1); |         .getSystemResourceAsStream("test-config.xml")) { | ||||||
|  |       WxXmlMpInMemoryConfigStorage config = fromXml( | ||||||
|  |           WxXmlMpInMemoryConfigStorage.class, is1); | ||||||
|       WxMpServiceImpl wxService = new WxMpServiceImpl(); |       WxMpServiceImpl wxService = new WxMpServiceImpl(); | ||||||
|       wxService.setWxMpConfigStorage(config); |       wxService.setWxMpConfigStorage(config); | ||||||
|  |       WxMpKefuService customerService = new WxMpKefuServiceImpl(); | ||||||
|  |       wxService.setCustomerService(customerService); | ||||||
|  |  | ||||||
|       binder.bind(WxMpServiceImpl.class).toInstance(wxService); |       binder.bind(WxMpServiceImpl.class).toInstance(wxService); | ||||||
|       binder.bind(WxMpConfigStorage.class).toInstance(config); |       binder.bind(WxMpConfigStorage.class).toInstance(config); | ||||||
|  |     } catch (IOException e) { | ||||||
|  |       e.printStackTrace(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static <T> T fromXml(Class<T> clazz, InputStream is) { |   public static <T> T fromXml(Class<T> clazz, InputStream is) { | ||||||
| @ -29,20 +41,22 @@ public class ApiTestModule implements Module { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @XStreamAlias("xml") |   @XStreamAlias("xml") | ||||||
|     public static class WxXmlMpInMemoryConfigStorage extends WxMpInMemoryConfigStorage { |   public static class WxXmlMpInMemoryConfigStorage | ||||||
|  |       extends WxMpInMemoryConfigStorage { | ||||||
|  |  | ||||||
|     protected String openId; |     protected String openId; | ||||||
|  |  | ||||||
|     public String getOpenId() { |     public String getOpenId() { | ||||||
|       return openId; |       return this.openId; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void setOpenId(String openId) { |     public void setOpenId(String openId) { | ||||||
|       this.openId = openId; |       this.openId = openId; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String toString() { |     public String toString() { | ||||||
|       return "SimpleWxConfigProvider [appId=" + appId + ", secret=" + secret + ", accessToken=" + accessToken |       return ToStringBuilder.reflectionToString(this); | ||||||
|           + ", expiresTime=" + expiresTime + ", token=" + token + ", openId=" + openId + "]"; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -0,0 +1,70 @@ | |||||||
|  | package me.chanjar.weixin.mp.api.impl; | ||||||
|  |  | ||||||
|  | import org.testng.annotations.Guice; | ||||||
|  | import org.testng.annotations.Test; | ||||||
|  |  | ||||||
|  | import com.google.inject.Inject; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.common.exception.WxErrorException; | ||||||
|  | import me.chanjar.weixin.mp.api.ApiTestModule; | ||||||
|  | import me.chanjar.weixin.mp.api.WxMpServiceImpl; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import org.testng.Assert; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 测试客服相关接口 | ||||||
|  |  * @author Binary Wang | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | @Test | ||||||
|  | @Guice(modules = ApiTestModule.class) | ||||||
|  | public class WxMpKefuImplTest { | ||||||
|  |   private static final String KF_ACCOUNT = "kf2009@youxintest"; | ||||||
|  |    | ||||||
|  |   @Inject | ||||||
|  |   protected WxMpServiceImpl wxService; | ||||||
|  |  | ||||||
|  |   public void testKfList() throws WxErrorException { | ||||||
|  |     WxMpKfList kfList = this.wxService.getKefuService().kfList(); | ||||||
|  |     Assert.assertNotNull(kfList); | ||||||
|  |     System.err.println(kfList); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void testKfOnlineList() throws WxErrorException { | ||||||
|  |     WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService().kfOnlineList(); | ||||||
|  |     Assert.assertNotNull(kfOnlineList); | ||||||
|  |     System.err.println(kfOnlineList); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void testKfAccountAdd() throws WxErrorException { | ||||||
|  |     WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | ||||||
|  |         .kfAccount(KF_ACCOUNT).nickName("我晕").rawPassword("123").build(); | ||||||
|  |     Assert.assertTrue(this.wxService.getKefuService().kfAccountAdd(request)); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @Test(dependsOnMethods = { "testKfAccountAdd" }) | ||||||
|  |   public void testKfAccountUpdate() throws WxErrorException { | ||||||
|  |     WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() | ||||||
|  |         .kfAccount(KF_ACCOUNT).nickName("我晕").rawPassword("123").build(); | ||||||
|  |     Assert.assertTrue(this.wxService.getKefuService().kfAccountUpdate(request)); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @Test(dependsOnMethods = { "testKfAccountUpdate" }) | ||||||
|  |   public void testKfAccountUploadHeadImg() throws WxErrorException { | ||||||
|  |     File imgFile = new File("src\\test\\resources\\mm.jpeg"); | ||||||
|  |     boolean result = this.wxService.getKefuService().kfAccountUploadHeadImg(KF_ACCOUNT, imgFile); | ||||||
|  |     Assert.assertTrue(result); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @Test(dependsOnMethods = { "testKfAccountUploadHeadImg" }) | ||||||
|  |   public void testKfAccountDel() throws WxErrorException {     | ||||||
|  |     boolean result = this.wxService.getKefuService().kfAccountDel(KF_ACCOUNT); | ||||||
|  |     Assert.assertTrue(result); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,41 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.result.kefu; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  | import org.testng.Assert; | ||||||
|  | import org.testng.annotations.Test; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | ||||||
|  |  | ||||||
|  | @Test | ||||||
|  | public class WxMpKfListTest { | ||||||
|  |  | ||||||
|  |   public void testFromJson() { | ||||||
|  |     String json=" {\r\n" +  | ||||||
|  |         "    \"kf_list\" : [\r\n" +  | ||||||
|  |         "       {\r\n" +  | ||||||
|  |         "          \"kf_account\" : \"test1@test\",\r\n" +  | ||||||
|  |         "          \"kf_headimgurl\" : \"http://mmbiz.qpic.cn/mmbiz/4whpV1VZl2iccsvYbHvnphkyGtnvjfUS8Ym0GSaLic0FD3vN0V8PILcibEGb2fPfEOmw/0\",\r\n" +  | ||||||
|  |         "          \"kf_id\" : \"1001\",\r\n" +  | ||||||
|  |         "          \"kf_nick\" : \"ntest1\"\r\n" +  | ||||||
|  |         "       },\r\n" +  | ||||||
|  |         "       {\r\n" +  | ||||||
|  |         "          \"kf_account\" : \"test2@test\",\r\n" +  | ||||||
|  |         "          \"kf_headimgurl\" : \"http://mmbiz.qpic.cn/mmbiz/4whpV1VZl2iccsvYbHvnphkyGtnvjfUS8Ym0GSaLic0FD3vN0V8PILcibEGb2fPfEOmw/0\",\r\n" +  | ||||||
|  |         "          \"kf_id\" : \"1002\",\r\n" +  | ||||||
|  |         "          \"kf_nick\" : \"ntest2\"\r\n" +  | ||||||
|  |         "       },\r\n" +  | ||||||
|  |         "       {\r\n" +  | ||||||
|  |         "          \"kf_account\" : \"test3@test\",\r\n" +  | ||||||
|  |         "          \"kf_headimgurl\" : \"http://mmbiz.qpic.cn/mmbiz/4whpV1VZl2iccsvYbHvnphkyGtnvjfUS8Ym0GSaLic0FD3vN0V8PILcibEGb2fPfEOmw/0\",\r\n" +  | ||||||
|  |         "          \"kf_id\" : \"1003\",\r\n" +  | ||||||
|  |         "          \"kf_nick\" : \"ntest3\"\r\n" +  | ||||||
|  |         "       }\r\n" +  | ||||||
|  |         "    ]\r\n" +  | ||||||
|  |         " }"; | ||||||
|  |      | ||||||
|  |     WxMpKfList wxMpKfList = WxMpKfList.fromJson(json); | ||||||
|  |     Assert.assertNotNull(wxMpKfList); | ||||||
|  |     System.err.println(ToStringBuilder.reflectionToString(wxMpKfList)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | package me.chanjar.weixin.mp.bean.result.kefu; | ||||||
|  |  | ||||||
|  | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
|  | import org.testng.Assert; | ||||||
|  | import org.testng.annotations.Test; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | ||||||
|  |  | ||||||
|  | @Test | ||||||
|  | public class WxMpKfOnlineListTest { | ||||||
|  |  | ||||||
|  |   @Test | ||||||
|  |   public void testFromJson() { | ||||||
|  |     String json = "{\r\n" +  | ||||||
|  |         "   \"kf_online_list\": [\r\n" +  | ||||||
|  |         "       {\r\n" +  | ||||||
|  |         "           \"kf_account\": \"test1@test\", \r\n" +  | ||||||
|  |         "           \"status\": 1, \r\n" +  | ||||||
|  |         "           \"kf_id\": \"1001\", \r\n" +  | ||||||
|  |         "           \"auto_accept\": 0, \r\n" +  | ||||||
|  |         "           \"accepted_case\": 1\r\n" +  | ||||||
|  |         "       },\r\n" +  | ||||||
|  |         "       {\r\n" +  | ||||||
|  |         "           \"kf_account\": \"test2@test\", \r\n" +  | ||||||
|  |         "           \"status\": 1, \r\n" +  | ||||||
|  |         "           \"kf_id\": \"1002\", \r\n" +  | ||||||
|  |         "           \"auto_accept\": 0, \r\n" +  | ||||||
|  |         "           \"accepted_case\": 2\r\n" +  | ||||||
|  |         "       }\r\n" +  | ||||||
|  |         "   ]\r\n" +  | ||||||
|  |         "}"; | ||||||
|  |  | ||||||
|  |     WxMpKfOnlineList wxMpKfOnlineList = WxMpKfOnlineList.fromJson(json); | ||||||
|  |     Assert.assertNotNull(wxMpKfOnlineList); | ||||||
|  |     System.err.println(ToStringBuilder.reflectionToString(wxMpKfOnlineList)); | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 BinaryWang
					BinaryWang