@@ -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(); | |||||
} | } |
@@ -74,6 +74,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
protected final Object globalCardApiTicketRefreshLock = new Object(); | protected final Object globalCardApiTicketRefreshLock = new Object(); | ||||
protected WxMpConfigStorage wxMpConfigStorage; | protected WxMpConfigStorage wxMpConfigStorage; | ||||
protected WxMpKefuService kefuService; | |||||
protected CloseableHttpClient httpClient; | protected CloseableHttpClient httpClient; | ||||
@@ -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"); | |||||
WxXmlMpInMemoryConfigStorage config = fromXml(WxXmlMpInMemoryConfigStorage.class, is1); | |||||
WxMpServiceImpl wxService = new WxMpServiceImpl(); | |||||
wxService.setWxMpConfigStorage(config); | |||||
try (InputStream is1 = ClassLoader | |||||
.getSystemResourceAsStream("test-config.xml")) { | |||||
WxXmlMpInMemoryConfigStorage config = fromXml( | |||||
WxXmlMpInMemoryConfigStorage.class, is1); | |||||
WxMpServiceImpl wxService = new WxMpServiceImpl(); | |||||
wxService.setWxMpConfigStorage(config); | |||||
WxMpKefuService customerService = new WxMpKefuServiceImpl(); | |||||
wxService.setCustomerService(customerService); | |||||
binder.bind(WxMpServiceImpl.class).toInstance(wxService); | |||||
binder.bind(WxMpConfigStorage.class).toInstance(config); | |||||
binder.bind(WxMpServiceImpl.class).toInstance(wxService); | |||||
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,22 +41,24 @@ 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 | |||||
+ ", expiresTime=" + expiresTime + ", token=" + token + ", openId=" + openId + "]"; | |||||
return ToStringBuilder.reflectionToString(this); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -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)); | |||||
} | |||||
} |