diff --git a/README.md b/README.md
index 7361b5a9..6a9878b3 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ weixin4j
+ **weixin4j-mp**: 新增V2版本`退款申请`、`退款查询`、`对账单下载`三个接口
- + **weixin-mp**: 新增一个简单的`语义理解`接口
+ + **weixin4j-mp**: 新增一个简单的`语义理解`接口
* 2014-11-11
@@ -74,17 +74,16 @@ weixin4j
+ **weixin4j-mp**: 新增被动消息的`加密`以及回复消息的`解密`
+* 2014-11-16
+
+ + **weixin4j-mp**: 新增`多客服`接口
接下来
------
-* 公众号智能接口
-
* 被扫支付
* 企业号API封装
-* 公众号多客服
-
* 微信小店
* 微信卡券
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c662868c..33d8ad45 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,7 @@
1.4.7
4.2.5
1.9
- 1.1.9
+ 1.2.1
1.7.3
1.1.6
2.6.0
diff --git a/weixin4j-mp/README.md b/weixin4j-mp/README.md
index 7c25e0b9..98b4112a 100644
--- a/weixin4j-mp/README.md
+++ b/weixin4j-mp/README.md
@@ -46,7 +46,7 @@ weixin4j-mp
* 2014-11-03
- + `weixin-mp`分离为`weixin-mp-api`和`weixin-mp-server`两个工程
+ + `weixin-mp`分离为`weixin4j-mp-api`和`weixin4j-mp-server`两个工程
+ **weixin4j-mp**: 新增`支付`模块
@@ -70,4 +70,8 @@ weixin4j-mp
+ **weixin4j-mp-server**: 解决`server工程`打包不能运行问题(`ClassUtil`无法获取jar包里面的类)
- + **weixin4j-mp-server**: 新增被动消息的`加密`以及回复消息的`解密`
\ No newline at end of file
+ + **weixin4j-mp-server**: 新增被动消息的`加密`以及回复消息的`解密`
+
+* 2014-11-16
+
+ + **weixin4j-mp-api**: 新增`多客服`接口
\ No newline at end of file
diff --git a/weixin4j-mp/weixin4j-mp-api/README.md b/weixin4j-mp/weixin4j-mp-api/README.md
index 07698944..bc117502 100644
--- a/weixin4j-mp/weixin4j-mp-api/README.md
+++ b/weixin4j-mp/weixin4j-mp-api/README.md
@@ -11,6 +11,8 @@ weixin4j-mp-api
* NotifyApi `客服消息API`
+* CustomApi `多客服API`*
+
* MassApi `群发消息API`
* UserApi `用户管理API`
@@ -108,4 +110,8 @@ weixin.properties说明
* 2014-11-15
- + 新增获取`微信服务器IP地址接口`
\ No newline at end of file
+ + 新增获取`微信服务器IP地址接口`
+
+* 2014-11-16
+
+ + 新增`多客服`接口
\ No newline at end of file
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
index 3dabbdf2..66d1cb54 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
@@ -11,6 +11,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.JsonResult;
import com.foxinmy.weixin4j.http.XmlResult;
import com.foxinmy.weixin4j.model.WeixinAccount;
+import com.foxinmy.weixin4j.mp.api.CustomApi;
import com.foxinmy.weixin4j.mp.api.GroupApi;
import com.foxinmy.weixin4j.mp.api.HelperApi;
import com.foxinmy.weixin4j.mp.api.MassApi;
@@ -25,6 +26,7 @@ import com.foxinmy.weixin4j.mp.model.Button;
import com.foxinmy.weixin4j.mp.model.CustomRecord;
import com.foxinmy.weixin4j.mp.model.Following;
import com.foxinmy.weixin4j.mp.model.Group;
+import com.foxinmy.weixin4j.mp.model.KfAccount;
import com.foxinmy.weixin4j.mp.model.MpArticle;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.QRParameter;
@@ -57,6 +59,7 @@ public class WeixinProxy {
private final MediaApi mediaApi;
private final NotifyApi notifyApi;
+ private final CustomApi customApi;
private final MassApi massApi;
private final UserApi userApi;
private final GroupApi groupApi;
@@ -101,6 +104,7 @@ public class WeixinProxy {
public WeixinProxy(TokenHolder tokenHolder) {
this.mediaApi = new MediaApi(tokenHolder);
this.notifyApi = new NotifyApi(tokenHolder);
+ this.customApi = new CustomApi(tokenHolder);
this.massApi = new MassApi(tokenHolder);
this.userApi = new UserApi(tokenHolder);
this.groupApi = new GroupApi(tokenHolder);
@@ -236,13 +240,13 @@ public class WeixinProxy {
* @param baseMsg
* 消息类型
* @return 发送结果
- * @throws WeixinException
* @see com.foxinmy.weixin4j.mp.msg.model.Text
* @see com.foxinmy.weixin4j.mp.msg.model.Image
* @see com.foxinmy.weixin4j.mp.msg.model.Music
* @see com.foxinmy.weixin4j.mp.msg.model.Video
* @see com.foxinmy.weixin4j.mp.msg.model.Voice
* @see com.foxinmy.weixin4j.mp.api.NotifyApi
+ * @throws WeixinException
*/
public JsonResult sendNotify(String touser, BaseMsg baseMsg)
throws WeixinException {
@@ -253,7 +257,7 @@ public class WeixinProxy {
* 客服聊天记录
*
* @param openId
- * 用户标识 可为空
+ * 用户标识 为空时则查询全部记录
* @param starttime
* 查询开始时间
* @param endtime
@@ -262,18 +266,37 @@ public class WeixinProxy {
* 每页大小 每页最多拉取1000条
* @param pageindex
* 查询第几页 从1开始
- * @throws WeixinException
* @see com.foxinmy.weixin4j.mp.model.CustomRecord
- * @see com.foxinmy.weixin4j.mp.api.NotifyApi
+ * @see com.foxinmy.weixin4j.mp.api.CustomApi
+ * @see 查询客服聊天记录
* @see 查询客服聊天记录
+ * @throws WeixinException
*/
- public List getCustomRecord(String openId, long starttime,
- long endtime, int pagesize, int pageindex) throws WeixinException {
- return notifyApi.getCustomRecord(openId, starttime, endtime, pagesize,
+ public List getCustomRecord(String openId, Date starttime,
+ Date endtime, int pagesize, int pageindex) throws WeixinException {
+ return customApi.getCustomRecord(openId, starttime, endtime, pagesize,
pageindex);
}
+ /**
+ * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号
+ *
+ * @param isOnline
+ * 是否在线 为ture时可以可以获取客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、
+ * 客服当前接待客户数
+ * @return 多客服信息列表
+ * @see com.foxinmy.weixin4j.mp.model.KfAccount
+ * @see com.foxinmy.weixin4j.mp.api.CustomApi
+ * @see 获取客服基本信息
+ * @see 获取在线客服接待信息
+ * @throws WeixinException
+ */
+ public List getKfAccountList(boolean isOnline)
+ throws WeixinException {
+ return customApi.getKfAccountList(isOnline);
+ }
+
/**
* 上传图文消息,一个图文消息支持1到10条图文
*
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java
new file mode 100644
index 00000000..32e2441e
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java
@@ -0,0 +1,98 @@
+package com.foxinmy.weixin4j.mp.api;
+
+import java.util.Date;
+import java.util.List;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.http.Response;
+import com.foxinmy.weixin4j.model.Token;
+import com.foxinmy.weixin4j.mp.model.CustomRecord;
+import com.foxinmy.weixin4j.mp.model.KfAccount;
+import com.foxinmy.weixin4j.token.TokenHolder;
+
+/**
+ * 多客服API
+ *
+ * @className CustomApi
+ * @author jy
+ * @date 2014年11月16日
+ * @since JDK 1.7
+ * @see 多客服说明
+ */
+public class CustomApi extends BaseApi {
+
+ private final TokenHolder tokenHolder;
+
+ public CustomApi(TokenHolder tokenHolder) {
+ this.tokenHolder = tokenHolder;
+ }
+
+ /**
+ * 客服聊天记录
+ *
+ * @param openId
+ * 用户标识 可为空
+ * @param starttime
+ * 查询开始时间
+ * @param endtime
+ * 查询结束时间 每次查询不能跨日查询
+ * @param pagesize
+ * 每页大小 每页最多拉取1000条
+ * @param pageindex
+ * 查询第几页 从1开始
+ * @throws WeixinException
+ * @see com.foxinmy.weixin4j.mp.model.CustomRecord
+ * @see 查询客服聊天记录
+ * @see 查询客服聊天记录
+ */
+ public List getCustomRecord(String openId, Date starttime,
+ Date endtime, int pagesize, int pageindex) throws WeixinException {
+ JSONObject obj = new JSONObject();
+ obj.put("openId", openId == null ? "" : openId);
+ obj.put("starttime", starttime.getTime() / 1000);
+ obj.put("endtime", endtime.getTime() / 1000);
+ obj.put("pagesize", pagesize > 1000 ? 1000 : pagesize);
+ obj.put("pageindex", pageindex);
+ String custom_record_uri = getRequestUri("custom_record_uri");
+ Token token = tokenHolder.getToken();
+ Response response = request.post(
+ String.format(custom_record_uri, token.getAccessToken()),
+ obj.toJSONString());
+
+ String text = response.getAsJson().getString("recordlist");
+ return JSON.parseArray(text, CustomRecord.class);
+ }
+
+ /**
+ * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号
+ *
+ * @param isOnline
+ * 是否在线 为ture时可以可以获取客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、
+ * 客服当前接待客户数
+ * @return 多客服信息列表
+ * @see com.foxinmy.weixin4j.mp.model.KfAccount
+ * @see 获取客服基本信息
+ * @see 获取在线客服接待信息
+ * @throws WeixinException
+ */
+ public List getKfAccountList(boolean isOnline)
+ throws WeixinException {
+ Token token = tokenHolder.getToken();
+ String text = "";
+ if (isOnline) {
+ String getonlinekflist_uri = getRequestUri("getonlinekflist_uri");
+ Response response = request.post(String.format(getonlinekflist_uri,
+ token.getAccessToken()));
+ text = response.getAsJson().getString("kf_online_list");
+ } else {
+ String getkflist_uri = getRequestUri("getkflist_uri");
+ Response response = request.post(String.format(getkflist_uri,
+ token.getAccessToken()));
+ text = response.getAsJson().getString("kf_list");
+ }
+ return JSON.parseArray(text, KfAccount.class);
+ }
+}
\ No newline at end of file
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/NotifyApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/NotifyApi.java
index bc06850c..1a2dfd51 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/NotifyApi.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/NotifyApi.java
@@ -2,13 +2,10 @@ package com.foxinmy.weixin4j.mp.api;
import java.util.List;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.JsonResult;
import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Token;
-import com.foxinmy.weixin4j.mp.model.CustomRecord;
import com.foxinmy.weixin4j.mp.msg.model.Article;
import com.foxinmy.weixin4j.mp.msg.model.BaseMsg;
import com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify;
@@ -16,7 +13,7 @@ import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
- * 客服相关API
+ * 客服消息API
*
* @className NotifyApi
* @author jy.hu
@@ -126,40 +123,4 @@ public class NotifyApi extends BaseApi {
return sendNotify(jsonPara.toString());
}
-
- /**
- * 客服聊天记录
- *
- * @param openId
- * 用户标识 可为空
- * @param starttime
- * 查询开始时间
- * @param endtime
- * 查询结束时间 每次查询不能跨日查询
- * @param pagesize
- * 每页大小 每页最多拉取1000条
- * @param pageindex
- * 查询第几页 从1开始
- * @throws WeixinException
- * @see com.foxinmy.weixin4j.mp.model.CustomRecord
- * @see 查询客服聊天记录
- */
- public List getCustomRecord(String openId, long starttime,
- long endtime, int pagesize, int pageindex) throws WeixinException {
- JSONObject obj = new JSONObject();
- obj.put("openId", openId == null ? "" : openId);
- obj.put("starttime", starttime);
- obj.put("endtime", endtime);
- obj.put("pagesize", pagesize > 1000 ? 1000 : pagesize);
- obj.put("pageindex", pageindex);
- String custom_record_uri = getRequestUri("custom_record_uri");
- Token token = tokenHolder.getToken();
- Response response = request.post(
- String.format(custom_record_uri, token.getAccessToken()),
- obj.toJSONString());
-
- String text = response.getAsJson().getString("recordlist");
- return JSON.parseArray(text, CustomRecord.class);
- }
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
index 8879ad91..75382e59 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
@@ -63,6 +63,10 @@ mass_openid_uri={api_cgi_url}/message/mass/send?access_token=%s
mass_delete_uri={api_cgi_url}/message/mass/delete?access_token=%s
# \u5ba2\u670d\u804a\u5929\u8bb0\u5f55
custom_record_uri={api_cgi_url}/customservice/getrecord?access_token=%s
+# \u5ba2\u670d\u57fa\u672c\u4fe1\u606f
+getkflist_uri={api_cgi_url}/customservice/getkflist?access_token=%s
+# \u5728\u7ebf\u5ba2\u670d\u57fa\u672c\u4fe1\u606f
+getonlinekflist_uri={api_cgi_url}/customservice/getonlinekflist?access_token=%s
# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5
shorturl_uri={api_cgi_url}/shorturl?access_token=%s
p_shorturl_uri={mch_base_url}/tools/shorturl
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java
index 6eef8b33..c943ab1e 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java
@@ -3,6 +3,9 @@ package com.foxinmy.weixin4j.mp.model;
import java.io.Serializable;
import java.util.Date;
+import com.foxinmy.weixin4j.mp.type.CustomRecordOperCode;
+import com.foxinmy.weixin4j.mp.util.EntityUtil;
+
/**
* 客服聊天记录
*
@@ -18,7 +21,7 @@ public class CustomRecord implements Serializable {
private static final long serialVersionUID = -4024147769411601325L;
private String worker;// 客服账号
private String openid;// 用户的标识
- private Opercode opercode;// 操作ID(会话状态)
+ private CustomRecordOperCode opercode;// 操作ID(会话状态)
private Date time;// 操作时间
private String text;// 聊天记录
@@ -38,20 +41,20 @@ public class CustomRecord implements Serializable {
this.openid = openid;
}
- public Opercode getOpercode() {
+ public CustomRecordOperCode getOpercode() {
return opercode;
}
- public void setOpercode(Opercode opercode) {
- this.opercode = opercode;
+ public void setOpercode(int opercode) {
+ this.opercode = EntityUtil.getCustomRecordOperCode(opercode);
}
public Date getTime() {
return time;
}
- public void setTime(Date time) {
- this.time = time;
+ public void setTime(long time) {
+ this.time = new Date(time * 1000);
}
public String getText() {
@@ -62,24 +65,6 @@ public class CustomRecord implements Serializable {
this.text = text;
}
- public enum Opercode {
- MISS(1000, "创建未接入会话"), ONLINE(1001, "接入会话"), CALL(1002, "主动发起会话"), CLOSE(
- 1004, "关闭会话"), RASE(1005, "抢接会话"), RECEIVE1(2001, "公众号收到消息"), SEND(
- 2002, "客服发送消息"), RECEIVE2(2003, "客服收到消息");
- private int code;
- private String desc;
- Opercode(int code, String desc) {
- this.code = code;
- this.desc = desc;
- }
- public int getCode() {
- return code;
- }
- public String getDesc() {
- return desc;
- }
- }
-
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java
new file mode 100644
index 00000000..01a7e504
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java
@@ -0,0 +1,96 @@
+package com.foxinmy.weixin4j.mp.model;
+
+import java.io.Serializable;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.foxinmy.weixin4j.mp.type.KfOnlineStatus;
+
+/**
+ * 多客服账号信息
+ *
+ * @className KfAccount
+ * @author jy
+ * @date 2014年11月16日
+ * @since JDK 1.7
+ * @see 多客服账号信息
+ */
+public class KfAccount implements Serializable {
+
+ private static final long serialVersionUID = -4565570894727129245L;
+
+ @JSONField(name = "kf_account")
+ // 客服账号@微信别名 微信别名如有修改,旧账号返回旧的微信别名,新增的账号返回新的微信别名
+ private String account;
+ @JSONField(name = "kf_nick")
+ private String nickName;// 客服昵称
+ @JSONField(name = "kf_id")
+ private String id;// 客服工号
+
+ // 以下字段是调用在线客服状态返回的字段
+ private KfOnlineStatus status; // 客服在线状态 1:pc在线,2:手机在线 若pc和手机同时在线则为 1+2=3
+ @JSONField(name = "auto_accept")
+ private int autoAccept;// 客服设置的最大自动接入数
+ @JSONField(name = "accepted_case")
+ private int acceptedCase;// 客服当前正在接待的会话数
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public KfOnlineStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ if (status == 1) {
+ this.status = KfOnlineStatus.PC;
+ } else if (status == 2) {
+ this.status = KfOnlineStatus.MOBILE;
+ } else {
+ this.status = KfOnlineStatus.BOTH;
+ }
+ }
+
+ public int getAutoAccept() {
+ return autoAccept;
+ }
+
+ public void setAutoAccept(int autoAccept) {
+ this.autoAccept = autoAccept;
+ }
+
+ public int getAcceptedCase() {
+ return acceptedCase;
+ }
+
+ public void setAcceptedCase(int acceptedCase) {
+ this.acceptedCase = acceptedCase;
+ }
+
+ @Override
+ public String toString() {
+ return "KfAccount [account=" + account + ", nickName=" + nickName
+ + ", id=" + id + ", status=" + status + ", autoAccept="
+ + autoAccept + ", acceptedCase=" + acceptedCase + "]";
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TransferResponse.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TransferResponse.java
index a6230201..108fa65e 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TransferResponse.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TransferResponse.java
@@ -13,6 +13,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see 多客服转移消息
+ * @see 将消息转发到多客服
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@@ -24,4 +25,49 @@ public class TransferResponse extends BaseResponse {
public TransferResponse(BaseMessage inMessage) {
super(ResponseType.transfer_customer_service, inMessage);
}
-}
+
+ /**
+ * 需如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满) 该用户会一直等待指定客服有接入能力后才会被接入 而不会被其他客服接待
+ *
+ * @param inMessage
+ * @param kfAccount
+ * 转移客服的账号
+ */
+ public TransferResponse(BaseMessage inMessage, String kfAccount) {
+ super(ResponseType.transfer_customer_service, inMessage);
+ this.transInfo = new TransInfo(kfAccount);
+ }
+
+ @XStreamAlias("TransInfo")
+ private TransInfo transInfo;
+
+ public String getTransAccount() {
+ if (transInfo != null) {
+ return transInfo.getKfAccount();
+ }
+ return null;
+ }
+
+ public void setTransAccount(String kfAccount) {
+ this.transInfo = new TransInfo(kfAccount);
+ }
+
+ private static class TransInfo {
+ // 指定会话接入的客服账号
+ @XStreamAlias("KfAccount")
+ private String kfAccount;
+
+ public TransInfo(String kfAccount) {
+ this.kfAccount = kfAccount;
+ }
+
+ public String getKfAccount() {
+ return kfAccount;
+ }
+
+ @Override
+ public String toString() {
+ return "TransInfo [kfAccount=" + kfAccount + "]";
+ }
+ }
+}
\ No newline at end of file
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/CustomRecordOperCode.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/CustomRecordOperCode.java
new file mode 100644
index 00000000..09de5e7c
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/CustomRecordOperCode.java
@@ -0,0 +1,30 @@
+package com.foxinmy.weixin4j.mp.type;
+
+/**
+ * 客服消息记录中的回话状态
+ * @className CustomRecordOperCode
+ * @author jy
+ * @date 2014年11月16日
+ * @since JDK 1.7
+ * @see
+ */
+public enum CustomRecordOperCode {
+ MISS(1000, "创建未接入会话"), ONLINE(1001, "接入会话"), CALL(1002, "主动发起会话"), CLOSE(
+ 1004, "关闭会话"), RASE(1005, "抢接会话"), RECEIVE1(2001, "公众号收到消息"), SEND(
+ 2002, "客服发送消息"), RECEIVE2(2003, "客服收到消息");
+ private int code;
+ private String desc;
+
+ CustomRecordOperCode(int code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/KfOnlineStatus.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/KfOnlineStatus.java
new file mode 100644
index 00000000..a10475c7
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/KfOnlineStatus.java
@@ -0,0 +1,29 @@
+package com.foxinmy.weixin4j.mp.type;
+
+/**
+ * 多客服在线状态
+ *
+ * @className KfOnlineStatus
+ * @author jy
+ * @date 2014年11月16日
+ * @since JDK 1.7
+ * @see
+ */
+public enum KfOnlineStatus {
+ PC(1, "PC在线"), MOBILE(2, "手机在线"), BOTH(3, "PC跟手机同时在线");
+ private int code;
+ private String desc;
+
+ KfOnlineStatus(int code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/util/EntityUtil.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/util/EntityUtil.java
new file mode 100644
index 00000000..1b1a5718
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/util/EntityUtil.java
@@ -0,0 +1,29 @@
+package com.foxinmy.weixin4j.mp.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.foxinmy.weixin4j.mp.type.CustomRecordOperCode;
+
+/**
+ * 实体帮助类
+ *
+ * @className EntityUtil
+ * @author jy
+ * @date 2014年11月16日
+ * @since JDK 1.7
+ * @see
+ */
+public class EntityUtil {
+ private static Map customRecordOperCodeMap;
+ static {
+ customRecordOperCodeMap = new HashMap();
+ for (CustomRecordOperCode operCode : CustomRecordOperCode.values()) {
+ customRecordOperCodeMap.put(operCode.getCode(), operCode);
+ }
+ }
+
+ public static CustomRecordOperCode getCustomRecordOperCode(int code) {
+ return customRecordOperCodeMap.get(code);
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/CustomTest.java b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/CustomTest.java
new file mode 100644
index 00000000..48c964af
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/CustomTest.java
@@ -0,0 +1,57 @@
+package com.foxinmy.weixin4j.mp.test.msg;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.mp.api.CustomApi;
+import com.foxinmy.weixin4j.mp.model.CustomRecord;
+import com.foxinmy.weixin4j.mp.model.KfAccount;
+import com.foxinmy.weixin4j.mp.test.TokenTest;
+
+/**
+ * 客服消息测试
+ *
+ * @className MessageNotifyTest
+ * @author jy.hu
+ * @date 2014年4月10日
+ * @since JDK 1.7
+ * @see
+ */
+public class CustomTest extends TokenTest {
+
+ private CustomApi customApi;
+
+ @Before
+ public void init() {
+ customApi = new CustomApi(tokenHolder);
+ }
+
+ @Test
+ public void customRecord() throws WeixinException {
+ String openId = "";
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY, 9);
+ calendar.add(Calendar.DAY_OF_MONTH, -2);
+ Date starttime = calendar.getTime();
+ calendar.set(Calendar.HOUR_OF_DAY, 21);
+ Date endtime = calendar.getTime();
+ int pagesize = 10;
+ int pageindex = 1;
+ List recordList = customApi.getCustomRecord(openId,
+ starttime, endtime, pagesize, pageindex);
+ System.out.println(recordList);
+ }
+
+ @Test
+ public void kfList() throws WeixinException {
+ List kfList = customApi.getKfAccountList(false);
+ System.out.println(kfList);
+ kfList = customApi.getKfAccountList(true);
+ System.out.println(kfList);
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/NotifyMsgTest.java b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/NotifyMsgTest.java
index 67b1067b..28f08909 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/NotifyMsgTest.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/NotifyMsgTest.java
@@ -93,8 +93,8 @@ public class NotifyMsgTest extends TokenTest {
@Test
public void send2() throws WeixinException, IOException {
- String mediaId = mediaApi.uploadMedia(new File(
- "/tmp/test.jpg"), MediaType.image);
+ String mediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
+ MediaType.image);
ImageNotify imageNotify = new ImageNotify(
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
imageNotify.pushMediaId(mediaId);
diff --git a/weixin4j-mp/weixin4j-mp-server/README.md b/weixin4j-mp/weixin4j-mp-server/README.md
index 35124778..1cedb071 100644
--- a/weixin4j-mp/weixin4j-mp-server/README.md
+++ b/weixin4j-mp/weixin4j-mp-server/README.md
@@ -28,7 +28,7 @@ weixin4j-mp-server
> account={"appId":"appId","appSecret":"appSecret",
> "token":"开放者的token 非必须","openId":"公众号的openid 非必须",
-> "encodingAesKey":"公众号设置了加密方式且为「安全模式」需要填入",
+> "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入",
> "mchId":"V3.x版本下的微信商户号",
> "partnerId":"财付通的商户号","partnerKey":"财付通商户权限密钥Key",
> "version":"针对微信支付的版本号(目前可能为2,3),如果不填则按照mchId非空与否来做判断",
@@ -49,7 +49,7 @@ weixin4j-mp-server
-------
* 2014-11-03
- + 得到`weixin-mp-server`工程
+ + 得到`weixin4j-mp-server`工程
* 2014-11-15