diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpClientFactory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpClientFactory.java index 011609db..335339de 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpClientFactory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpClientFactory.java @@ -102,7 +102,7 @@ public abstract class HttpClientFactory { */ public static HttpClient getInstance(HttpParams params) { HttpClientFactory clientFactory = getDefaultFactory(); - clientFactory.resolveHttpParams(params); + clientFactory.setDefaultParams(params); return clientFactory.newInstance(); } @@ -112,11 +112,11 @@ public abstract class HttpClientFactory { * @param params * 请求参数 */ - public void resolveHttpParams(HttpParams params) { + public void setDefaultParams(HttpParams params) { if (params == null) { throw new IllegalArgumentException("'params' must not be empty"); } - resolveHttpParams0(params); + resolveHttpParams(params); } /** @@ -125,7 +125,7 @@ public abstract class HttpClientFactory { * @param params * 请求参数 */ - protected abstract void resolveHttpParams0(HttpParams params); + protected abstract void resolveHttpParams(HttpParams params); /** * 获取HttpClient实例 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/SimpleHttpClientFactory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/SimpleHttpClientFactory.java index 5260c13d..e5c2fbac 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/SimpleHttpClientFactory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/SimpleHttpClientFactory.java @@ -19,7 +19,7 @@ public class SimpleHttpClientFactory extends HttpClientFactory { private HttpParams params; @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { this.params = params; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache3/HttpComponent3Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache3/HttpComponent3Factory.java index d7ff0132..ebcf8189 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache3/HttpComponent3Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache3/HttpComponent3Factory.java @@ -41,7 +41,7 @@ public class HttpComponent3Factory extends HttpClientFactory { * Resolve Parameter */ @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { if (params.getProxy() != null) { InetSocketAddress socketAddress = (InetSocketAddress) params .getProxy().address(); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4Factory.java index f76e6147..c5796d7b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4Factory.java @@ -41,7 +41,7 @@ public class HttpComponent4Factory extends HttpClientFactory { } @Override - protected void resolveHttpParams0(HttpParams params) { - httpComponentFactory.resolveHttpParams(params); + protected void resolveHttpParams(HttpParams params) { + httpComponentFactory.setDefaultParams(params); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_1Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_1Factory.java index 287ba0ee..3cf8c8d4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_1Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_1Factory.java @@ -39,7 +39,7 @@ public class HttpComponent4_1Factory extends HttpClientFactory { } @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { if (params == null) { throw new IllegalArgumentException("'params' must not be empty"); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_2Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_2Factory.java index 698a8487..47d13dff 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_2Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/apache4/HttpComponent4_2Factory.java @@ -42,7 +42,7 @@ public class HttpComponent4_2Factory extends HttpClientFactory { } @Override - public void resolveHttpParams0(HttpParams params) { + public void resolveHttpParams(HttpParams params) { clientBuilder.setDefaultRequestConfig(RequestConfig.custom() .setConnectTimeout(params.getConnectTimeout()) .setConnectionRequestTimeout(params.getReadTimeout()).build()); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/netty/Netty4HttpClientFactory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/netty/Netty4HttpClientFactory.java index 49fa8cd8..a8bd2e1d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/netty/Netty4HttpClientFactory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/netty/Netty4HttpClientFactory.java @@ -46,7 +46,7 @@ public class Netty4HttpClientFactory extends HttpClientFactory { } @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { this.params = params; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient2Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient2Factory.java index d8d5d855..70eacc46 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient2Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient2Factory.java @@ -32,7 +32,7 @@ public class OkHttpClient2Factory extends HttpClientFactory { } @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { okClient.setConnectTimeout(params.getConnectTimeout(), TimeUnit.MILLISECONDS); okClient.setReadTimeout(params.getReadTimeout(), TimeUnit.MILLISECONDS); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient3Factory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient3Factory.java index c773975c..64e19ed6 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient3Factory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClient3Factory.java @@ -39,7 +39,7 @@ public class OkHttpClient3Factory extends HttpClientFactory { * * */ @Override - protected void resolveHttpParams0(HttpParams params) { + protected void resolveHttpParams(HttpParams params) { clientBuilder.connectTimeout(params.getConnectTimeout(), TimeUnit.MILLISECONDS); clientBuilder.readTimeout(params.getReadTimeout(), diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClientFactory.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClientFactory.java index 525f20e8..926ea8d0 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClientFactory.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/support/okhttp/OkHttpClientFactory.java @@ -27,8 +27,8 @@ public class OkHttpClientFactory extends HttpClientFactory { } @Override - protected void resolveHttpParams0(HttpParams params) { - okHttpClientFactory.resolveHttpParams(params); + protected void resolveHttpParams(HttpParams params) { + okHttpClientFactory.setDefaultParams(params); } @Override diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaRecord.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaRecord.java index 67cdfb0f..456cc2a7 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaRecord.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaRecord.java @@ -45,7 +45,7 @@ public class MediaRecord implements Serializable { @JSONField(serialize = false, deserialize = false) private Pageable pageable; @JSONField(serialize = false, deserialize = false) - private Pagedata pagedata; + private volatile Pagedata pagedata; public int getTotalCount() { return totalCount; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Pageable.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Pageable.java index ea111861..28a189e2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Pageable.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Pageable.java @@ -94,7 +94,7 @@ public class Pageable implements Serializable { } public Pageable first() { - return new Pageable(0, getPageSize(), getSort()); + return new Pageable(1, getPageSize(), getSort()); } @Override diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java index 49bfd1e6..3408ee93 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java @@ -79,7 +79,7 @@ public class DateUtil { public static String formatFee2Fen(double fee) { BigDecimal _fee = new BigDecimal(Double.toString(fee)); fee = _fee.multiply(new BigDecimal("100")) - .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + .setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue(); return new DecimalFormat("#").format(fee); } diff --git a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/http/HttpClientTest.java b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/http/HttpClientTest.java index 87e5a90f..ffc1fb1e 100644 --- a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/http/HttpClientTest.java +++ b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/http/HttpClientTest.java @@ -61,7 +61,7 @@ public abstract class HttpClientTest { protected HttpClient createHttpClient(HttpParams params) { HttpClientFactory httpClientFactory = createHttpFactory(); - httpClientFactory.resolveHttpParams(params); + httpClientFactory.setDefaultParams(params); return httpClientFactory.newInstance(); } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 2f555904..2599901c 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -34,6 +34,7 @@ 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.KfChatRecord; +import com.foxinmy.weixin4j.mp.model.KfOnlineAccount; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter; import com.foxinmy.weixin4j.mp.model.Menu; @@ -387,8 +388,7 @@ public class WeixinProxy { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738731&token=&lang=zh_CN"> * 删除永久媒体素材 */ - public ApiResult deleteMaterialMedia(String mediaId) - throws WeixinException { + public ApiResult deleteMaterialMedia(String mediaId) throws WeixinException { return mediaApi.deleteMaterialMedia(mediaId); } @@ -514,8 +514,8 @@ public class WeixinProxy { * 查询开始时间 * @param endTime * 查询结束时间 每次查询不能跨日查询 - * @param pageable - * 分页数据 + * @param number + * 最多10000条 * @see com.foxinmy.weixin4j.mp.model.CustomRecord * @see com.foxinmy.weixin4j.mp.api.CustomApi * @see 查询客服聊天记录 @@ -525,30 +525,38 @@ public class WeixinProxy { * @throws WeixinException */ public List getKfChatRecord(Date startTime, Date endTime, - Pageable pageable) throws WeixinException { - return customApi.getKfChatRecord(startTime, endTime, pageable); + int number) throws WeixinException { + return customApi.getKfChatRecord(startTime, endTime, number); } /** * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号 * - * @param isOnline - * 是否在线 为ture时可以可以获取客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、 - * 客服当前接待客户数 * @return 多客服信息列表 * @see com.foxinmy.weixin4j.mp.model.KfAccount * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 获取客服基本信息 * @see * 获取客服基本信息 - * @see 获取在线客服接待信息 - * 获取在线客服接待信息 * @throws WeixinException */ - public List listKfAccount(boolean isOnline) - throws WeixinException { - return customApi.listKfAccount(isOnline); + public List listKfAccount() throws WeixinException { + return customApi.listKfAccount(); + } + + /** + * 获取在线客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、 客服当前接待客户数 + * + * @return 多客服在线信息列表 + * @see com.foxinmy.weixin4j.mp.model.KfOnlineAccount + * @see com.foxinmy.weixin4j.mp.api.CustomApi + * @see + * 获取客服在线信息 + * @throws WeixinException + */ + public List listOnlineKfAccount() throws WeixinException { + return customApi.listOnlineKfAccount(); } /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java index 8fc7a727..f79ffd16 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java @@ -14,10 +14,10 @@ import com.foxinmy.weixin4j.http.apache.FormBodyPart; import com.foxinmy.weixin4j.http.apache.InputStreamBody; import com.foxinmy.weixin4j.http.weixin.ApiResult; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; -import com.foxinmy.weixin4j.model.Pageable; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.model.KfAccount; import com.foxinmy.weixin4j.mp.model.KfChatRecord; +import com.foxinmy.weixin4j.mp.model.KfOnlineAccount; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter; import com.foxinmy.weixin4j.token.TokenManager; @@ -50,8 +50,8 @@ public class CustomApi extends MpApi { * 查询开始时间 * @param endTime * 查询结束时间 每次查询不能跨日查询 - * @param pageable - * 分页数据 + * @param number + * 最多10000条 * @throws WeixinException * @see com.foxinmy.weixin4j.mp.model.KfChatRecord * @see 查询客服聊天记录 @@ -59,61 +59,70 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044854&token=&lang=zh_CN"> * 查询客服聊天记录 */ - public List getKfChatRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException { + public List getKfChatRecord(Date startTime, Date endTime, + int number) throws WeixinException { List records = new ArrayList(); String kf_chatrecord_uri = getRequestUri("kf_chatrecord_uri"); Token token = tokenManager.getCache(); JSONObject obj = new JSONObject(); obj.put("starttime", startTime.getTime() / 1000); obj.put("endtime", endTime.getTime() / 1000); - for (int i = 0; i < (int) Math.ceil(pageable.getPageSize() / 50d); i++) { - obj.put("pagesize", Math.min(50, pageable.getPageSize())); - obj.put("pageindex", pageable.getPageNumber()); - WeixinResponse response = weixinExecutor.post(String.format(kf_chatrecord_uri, token.getAccessToken()), + obj.put("msgid", "1"); + obj.put("number", Math.min(10000, number)); + JSONObject result = null; + do { + WeixinResponse response = weixinExecutor.post( + String.format(kf_chatrecord_uri, token.getAccessToken()), obj.toJSONString()); - - String text = response.getAsJson().getString("recordlist"); + result = response.getAsJson(); + String text = result.getString("recordlist"); if (StringUtil.isBlank(text) || "[]".equals(text)) { break; } records.addAll(JSON.parseArray(text, KfChatRecord.class)); - - pageable = new Pageable(pageable.getPageNumber() + 1, - Math.min(50, Math.max(1, pageable.getPageSize() - ((i + 1) * 50)))); - } + obj.put("msgid", result.getString("msgid")); + } while (obj.getIntValue("number") == result.getIntValue("number")); return records; } /** * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号 * - * @param isOnline - * 是否在线 为ture时可以可以获取客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、 - * 客服当前接待客户数 * @return 多客服信息列表 * @see com.foxinmy.weixin4j.mp.model.KfAccount - * @see 获取客服基本信息 * @see * 获取客服基本信息 - * @see 获取在线客服接待信息 * @throws WeixinException */ - public List listKfAccount(boolean isOnline) throws WeixinException { + public List listKfAccount() throws WeixinException { Token token = tokenManager.getCache(); - String text = ""; - if (isOnline) { - String kf_onlinelist_uri = getRequestUri("kf_onlinelist_uri"); - WeixinResponse response = weixinExecutor.get(String.format(kf_onlinelist_uri, token.getAccessToken())); - text = response.getAsJson().getString("kf_online_list"); - } else { - String kf_list_uri = getRequestUri("kf_list_uri"); - WeixinResponse response = weixinExecutor.get(String.format(kf_list_uri, token.getAccessToken())); - text = response.getAsJson().getString("kf_list"); - } + String kf_list_uri = getRequestUri("kf_list_uri"); + WeixinResponse response = weixinExecutor.get(String.format(kf_list_uri, + token.getAccessToken())); + String text = response.getAsJson().getString("kf_list"); return JSON.parseArray(text, KfAccount.class); } + /** + * 获取在线客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、 客服当前接待客户数 + * + * @return 多客服在线信息列表 + * @see com.foxinmy.weixin4j.mp.model.KfOnlineAccount + * @see + * 获取客服在线信息 + * @throws WeixinException + */ + public List listOnlineKfAccount() throws WeixinException { + Token token = tokenManager.getCache(); + String kf_onlinelist_uri = getRequestUri("kf_onlinelist_uri"); + WeixinResponse response = weixinExecutor.get(String.format( + kf_onlinelist_uri, token.getAccessToken())); + String text = response.getAsJson().getString("kf_online_list"); + return JSON.parseArray(text, KfOnlineAccount.class); + } + /** * 新增客服账号 * @@ -130,14 +139,16 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN"> * 新增客服账号 */ - public ApiResult createKfAccount(String id, String name, String pwd) throws WeixinException { + public ApiResult createKfAccount(String id, String name, String pwd) + throws WeixinException { JSONObject obj = new JSONObject(); obj.put("kf_account", id); obj.put("nickname", name); obj.put("password", DigestUtil.MD5(pwd)); String kf_create_uri = getRequestUri("kf_create_uri"); Token token = tokenManager.getCache(); - WeixinResponse response = weixinExecutor.post(String.format(kf_create_uri, token.getAccessToken()), + WeixinResponse response = weixinExecutor.post( + String.format(kf_create_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsResult(); } @@ -158,14 +169,16 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN"> * 新增客服账号 */ - public ApiResult updateKfAccount(String id, String name, String pwd) throws WeixinException { + public ApiResult updateKfAccount(String id, String name, String pwd) + throws WeixinException { JSONObject obj = new JSONObject(); obj.put("kf_account", id); obj.put("nickname", name); obj.put("password", DigestUtil.MD5(pwd)); String kf_update_uri = getRequestUri("kf_update_uri"); Token token = tokenManager.getCache(); - WeixinResponse response = weixinExecutor.post(String.format(kf_update_uri, token.getAccessToken()), + WeixinResponse response = weixinExecutor.post( + String.format(kf_update_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsResult(); } @@ -185,13 +198,15 @@ public class CustomApi extends MpApi { * >邀请绑定客服帐号 * @throws WeixinException */ - public ApiResult inviteKfAccount(String kfAccount, String inviteAccount) throws WeixinException { + public ApiResult inviteKfAccount(String kfAccount, String inviteAccount) + throws WeixinException { JSONObject obj = new JSONObject(); obj.put("kf_account", kfAccount); obj.put("invite_wx", inviteAccount); String kf_invite_uri = getRequestUri("kf_invite_uri"); Token token = tokenManager.getCache(); - WeixinResponse response = weixinExecutor.post(String.format(kf_invite_uri, token.getAccessToken()), + WeixinResponse response = weixinExecutor.post( + String.format(kf_invite_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsResult(); } @@ -211,18 +226,22 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044813&token=&lang=zh_CN"> * 上传客服头像 */ - public ApiResult uploadKfAvatar(String accountId, InputStream is, String fileName) throws WeixinException { + public ApiResult uploadKfAvatar(String accountId, InputStream is, + String fileName) throws WeixinException { if (StringUtil.isBlank(fileName)) { fileName = ObjectId.get().toHexString(); } if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) { fileName = String.format("%s.jpg", fileName); } - MimeType mimeType = new MimeType("image", FileUtil.getFileExtension(fileName)); + MimeType mimeType = new MimeType("image", + FileUtil.getFileExtension(fileName)); Token token = tokenManager.getCache(); String kf_avatar_uri = getRequestUri("kf_avatar_uri"); - WeixinResponse response = weixinExecutor.post(String.format(kf_avatar_uri, token.getAccessToken(), accountId), - new FormBodyPart("media", new InputStreamBody(is, mimeType.toString(), fileName))); + WeixinResponse response = weixinExecutor + .post(String.format(kf_avatar_uri, token.getAccessToken(), + accountId), new FormBodyPart("media", + new InputStreamBody(is, mimeType.toString(), fileName))); return response.getAsResult(); } @@ -241,7 +260,8 @@ public class CustomApi extends MpApi { public ApiResult deleteKfAccount(String id) throws WeixinException { Token token = tokenManager.getCache(); String kf_delete_uri = getRequestUri("kf_delete_uri"); - WeixinResponse response = weixinExecutor.get(String.format(kf_delete_uri, token.getAccessToken(), id)); + WeixinResponse response = weixinExecutor.get(String.format( + kf_delete_uri, token.getAccessToken(), id)); return response.getAsResult(); } @@ -265,14 +285,16 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044820&token=&lang=zh_CN"> * 创建会话 */ - public ApiResult createKfSession(String userOpenId, String kfAccount, String text) throws WeixinException { + public ApiResult createKfSession(String userOpenId, String kfAccount, + String text) throws WeixinException { Token token = tokenManager.getCache(); String kfsession_create_uri = getRequestUri("kfsession_create_uri"); JSONObject obj = new JSONObject(); obj.put("openid", userOpenId); obj.put("kf_account", kfAccount); obj.put("text", text); - WeixinResponse response = weixinExecutor.post(String.format(kfsession_create_uri, token.getAccessToken()), + WeixinResponse response = weixinExecutor.post( + String.format(kfsession_create_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsResult(); @@ -293,14 +315,16 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044820&token=&lang=zh_CN"> * 关闭会话 */ - public ApiResult closeKfSession(String userOpenId, String kfAccount, String text) throws WeixinException { + public ApiResult closeKfSession(String userOpenId, String kfAccount, + String text) throws WeixinException { Token token = tokenManager.getCache(); String kfsession_close_uri = getRequestUri("kfsession_close_uri"); JSONObject obj = new JSONObject(); obj.put("openid", userOpenId); obj.put("kf_account", kfAccount); obj.put("text", text); - WeixinResponse response = weixinExecutor.post(String.format(kfsession_close_uri, token.getAccessToken()), + WeixinResponse response = weixinExecutor.post( + String.format(kfsession_close_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsResult(); @@ -321,11 +345,12 @@ public class CustomApi extends MpApi { public KfSession getKfSession(String userOpenId) throws WeixinException { Token token = tokenManager.getCache(); String kfsession_get_uri = getRequestUri("kfsession_get_uri"); - WeixinResponse response = weixinExecutor - .get(String.format(kfsession_get_uri, token.getAccessToken(), userOpenId)); + WeixinResponse response = weixinExecutor.get(String.format( + kfsession_get_uri, token.getAccessToken(), userOpenId)); - KfSession session = response.getAsObject(new TypeReference() { - }); + KfSession session = response + .getAsObject(new TypeReference() { + }); session.setUserOpenId(userOpenId); return session; } @@ -342,19 +367,21 @@ public class CustomApi extends MpApi { * "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458044820&token=&lang=zh_CN"> * 获取客服的会话列表 */ - public List listKfSession(String kfAccount) throws WeixinException { + public List listKfSession(String kfAccount) + throws WeixinException { Token token = tokenManager.getCache(); String kfsession_list_uri = getRequestUri("kfsession_list_uri"); - WeixinResponse response = weixinExecutor - .get(String.format(kfsession_list_uri, token.getAccessToken(), kfAccount)); + WeixinResponse response = weixinExecutor.get(String.format( + kfsession_list_uri, token.getAccessToken(), kfAccount)); - List sessionList = JSON.parseArray(response.getAsJson().getString("sessionlist"), KfSession.class); + List sessionList = JSON.parseArray(response.getAsJson() + .getString("sessionlist"), KfSession.class); return sessionList; } /** - * 获取未接入会话列表:获取当前正在等待队列中的会话列表,此接口最多返回最早进入队列的100个未接入会话。
- * 缺陷:没有count字段 + * 获取未接入会话列表:获取当前正在等待队列中的会话列表,此接口最多返回最早进入队列的100个未接入会话。
缺陷:没有count字段 * * @return 会话列表 * @throws WeixinException @@ -367,7 +394,8 @@ public class CustomApi extends MpApi { public KfSessionCounter listKfWaitSession() throws WeixinException { Token token = tokenManager.getCache(); String kfsession_wait_uri = getRequestUri("kfsession_wait_uri"); - WeixinResponse response = weixinExecutor.get(String.format(kfsession_wait_uri, token.getAccessToken())); + WeixinResponse response = weixinExecutor.get(String.format( + kfsession_wait_uri, token.getAccessToken())); return response.getAsObject(new TypeReference() { }); diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties index 2dd6d764..bc695cc6 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties @@ -79,7 +79,7 @@ mass_preview_uri={api_cgi_url}/message/mass/preview?access_token=%s # \u67e5\u8be2\u7fa4\u53d1\u72b6\u6001 mass_get_uri={api_cgi_url}/message/mass/get?access_token=%s # \u5ba2\u670d\u804a\u5929\u8bb0\u5f55 -kf_chatrecord_uri={api_cgi_url}/customservice/getrecord?access_token=%s +kf_chatrecord_uri={api_base_url}/customservice/msgrecord/getmsglist?access_token=%s # \u5ba2\u670d\u57fa\u672c\u4fe1\u606f kf_list_uri={api_cgi_url}/customservice/getkflist?access_token=%s # \u5728\u7ebf\u5ba2\u670d\u57fa\u672c\u4fe1\u606f diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java index 87a60089..82d9ca27 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfAccount.java @@ -1,9 +1,10 @@ package com.foxinmy.weixin4j.mp.model; import java.io.Serializable; +import java.util.Date; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.mp.type.KfOnlineStatus; +import com.foxinmy.weixin4j.mp.type.KfInviteStatus; /** * 多客服账号信息 @@ -17,7 +18,11 @@ import com.foxinmy.weixin4j.mp.type.KfOnlineStatus; public class KfAccount implements Serializable { private static final long serialVersionUID = -4565570894727129245L; - + /** + * 客服工号 + */ + @JSONField(name = "kf_id") + private String id; /** * 客服账号@微信别名 微信别名如有修改,旧账号返回旧的微信别名,新增的账号返回新的微信别名 */ @@ -28,32 +33,31 @@ public class KfAccount implements Serializable { */ @JSONField(name = "kf_nick") private String nickName; - /** - * 客服工号 - */ - @JSONField(name = "kf_id") - private String id; /** * 客服头像 */ - @JSONField(name = "kf_headimg") - private String headImg; - - // 以下字段是调用在线客服状态返回的字段 + @JSONField(name = "kf_headimgurl") + private String headimgurl; /** - * 客服在线状态 1:pc在线,2:手机在线 若pc和手机同时在线则为 1+2=3 + * 客服微信 */ - private int status; + @JSONField(name = "kf_wx") + private String wx; /** - * 客服设置的最大自动接入数 + * 客服绑定邀请的微信号 */ - @JSONField(name = "auto_accept") - private int autoAccept; + @JSONField(name = "invite_wx") + private String inviteWx; /** - * 客服当前正在接待的会话数 + * 客服邀请的过期时间 */ - @JSONField(name = "accepted_case") - private int acceptedCase; + @JSONField(name = "invite_expire_time") + private long inviteExpireTime; + /** + * 客服邀请的状态 + */ + @JSONField(name = "invite_status") + private String inviteStatus; public String getAccount() { return account; @@ -79,53 +83,62 @@ public class KfAccount implements Serializable { this.id = id; } - public String getHeadImg() { - return headImg; + public String getHeadimgurl() { + return headimgurl; } - public void setHeadImg(String headImg) { - this.headImg = headImg; + public void setHeadimgurl(String headimgurl) { + this.headimgurl = headimgurl; } - public int getStatus() { - return status; + public String getWx() { + return wx; + } + + public void setWx(String wx) { + this.wx = wx; + } + + public String getInviteWx() { + return inviteWx; + } + + public void setInviteWx(String inviteWx) { + this.inviteWx = inviteWx; + } + + public long getInviteExpireTime() { + return inviteExpireTime; } @JSONField(serialize = false) - public KfOnlineStatus getFormatStatus() { - if (status == 1) { - return KfOnlineStatus.PC; - } else if (status == 2) { - return KfOnlineStatus.MOBILE; - } else { - return KfOnlineStatus.BOTH; - } + public Date getFormatInviteExpireTime() { + return new Date(inviteExpireTime * 1000l); } - public void setStatus(int status) { - this.status = status; + public void setInviteExpireTime(long inviteExpireTime) { + this.inviteExpireTime = inviteExpireTime; } - public int getAutoAccept() { - return autoAccept; + public String getInviteStatus() { + return inviteStatus; } - public void setAutoAccept(int autoAccept) { - this.autoAccept = autoAccept; + @JSONField(serialize = false) + public KfInviteStatus getFormatInviteStatus() { + return inviteStatus != null ? KfInviteStatus.valueOf(inviteStatus + .toUpperCase()) : null; } - public int getAcceptedCase() { - return acceptedCase; - } - - public void setAcceptedCase(int acceptedCase) { - this.acceptedCase = acceptedCase; + public void setInviteStatus(String inviteStatus) { + this.inviteStatus = inviteStatus; } @Override public String toString() { - return "KfAccount [account=" + account + ", nickName=" + nickName - + ", id=" + id + ", status=" + status + ", autoAccept=" - + autoAccept + ", acceptedCase=" + acceptedCase + "]"; + return "KfAccount [id=" + id + ", account=" + account + ", nickName=" + + nickName + ", headimgurl=" + headimgurl + ", wx=" + wx + + ", inviteWx=" + inviteWx + ", inviteExpireTime=" + + inviteExpireTime + ", inviteStatus=" + inviteStatus + "]"; } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfOnlineAccount.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfOnlineAccount.java new file mode 100644 index 00000000..b5936f7a --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfOnlineAccount.java @@ -0,0 +1,102 @@ +package com.foxinmy.weixin4j.mp.model; + +import java.io.Serializable; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.mp.type.KfOnlineStatus; + +/** + * 多客服在线信息 + * + * @className KfOnlineAccount + * @author jinyu(foxinmy@gmail.com) + * @date 2014年11月16日 + * @since JDK 1.6 + * @see 多客服账号信息 + */ +public class KfOnlineAccount implements Serializable { + + private static final long serialVersionUID = -4565570894727129245L; + /** + * 客服工号 + */ + @JSONField(name = "kf_id") + private String id; + /** + * 客服账号@微信别名 微信别名如有修改,旧账号返回旧的微信别名,新增的账号返回新的微信别名 + */ + @JSONField(name = "kf_account") + private String account; + /** + * 客服在线状态 1:pc在线,2:手机在线 若pc和手机同时在线则为 1+2=3 + */ + private int status; + /** + * 客服设置的最大自动接入数 + */ + @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 getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getStatus() { + return status; + } + + @JSONField(serialize = false) + public KfOnlineStatus getFormatStatus() { + if (status == 1) { + return KfOnlineStatus.PC; + } else if (status == 2) { + return KfOnlineStatus.MOBILE; + } else { + return KfOnlineStatus.BOTH; + } + } + + public void setStatus(int status) { + this.status = status; + } + + 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 + ", id=" + id + ", status=" + + status + ", autoAccept=" + autoAccept + ", acceptedCase=" + + acceptedCase + "]"; + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/KfInviteStatus.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/KfInviteStatus.java new file mode 100644 index 00000000..4d9ad45a --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/KfInviteStatus.java @@ -0,0 +1,23 @@ +package com.foxinmy.weixin4j.mp.type; + +/** + * 多客服邀请状态 + * + * @className KfInviteStatus + * @author jinyu(foxinmy@gmail.com) + * @date 2014年11月16日 + * @since JDK 1.6 + * @see + */ +public enum KfInviteStatus { + WAITING("等待确认"), REJECTED("被拒绝"), EXPIRED("已过期"); + private String desc; + + KfInviteStatus(String desc) { + this.desc = desc; + } + + public String getDesc() { + return desc; + } +} diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java index 81d8daf7..270feaf8 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java @@ -13,10 +13,10 @@ import org.junit.Test; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.ApiResult; -import com.foxinmy.weixin4j.model.Pageable; import com.foxinmy.weixin4j.mp.api.CustomApi; import com.foxinmy.weixin4j.mp.model.KfAccount; import com.foxinmy.weixin4j.mp.model.KfChatRecord; +import com.foxinmy.weixin4j.mp.model.KfOnlineAccount; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter; @@ -47,19 +47,19 @@ public class CustomTest extends TokenTest { calendar.set(Calendar.HOUR_OF_DAY, 21); Date endtime = calendar.getTime(); List recordList = customApi.getKfChatRecord(starttime, - endtime, new Pageable(1, 70)); + endtime, 10); Assert.assertFalse(recordList.isEmpty()); System.out.println(recordList); } @Test public void kfList() throws WeixinException { - List kfList = customApi.listKfAccount(false); - Assert.assertFalse(kfList.isEmpty()); - System.out.println(kfList); - kfList = customApi.listKfAccount(true); + List kfList = customApi.listKfAccount(); Assert.assertFalse(kfList.isEmpty()); System.out.println(kfList); + List kfOnlineList = customApi.listOnlineKfAccount(); + Assert.assertFalse(kfOnlineList.isEmpty()); + System.out.println(kfOnlineList); } @Test