🆕 #1686 微信公众号增加对话能力(原导购助手)部分接口,如添加顾问、获取顾问信息等

This commit is contained in:
Binary Wang 2020-10-06 21:04:39 +08:00
parent 64402ab1de
commit 6948044ab9
15 changed files with 389 additions and 121 deletions

View File

@ -22,6 +22,11 @@ public class WxErrorException extends Exception {
this.error = error; this.error = error;
} }
public WxErrorException(Throwable cause) {
super(cause.getMessage(), cause);
this.error = WxError.builder().errorCode(-1).errorMsg(cause.getMessage()).build();
}
public WxError getError() { public WxError getError() {
return this.error; return this.error;
} }

View File

@ -1,5 +1,7 @@
package me.chanjar.weixin.common.service; package me.chanjar.weixin.common.service;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
/** /**
@ -38,4 +40,24 @@ public interface WxService {
* @throws WxErrorException 异常 * @throws WxErrorException 异常
*/ */
String post(String url, Object obj) throws WxErrorException; String post(String url, Object obj) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候可以用这个针对所有微信API中的POST请求.
*
* @param url 请求接口地址
* @param jsonObject 请求对象
* @return 接口响应字符串
* @throws WxErrorException 异常
*/
String post(String url, JsonObject jsonObject) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候可以用这个针对所有微信API中的POST请求.
*
* @param url 请求接口地址
* @param obj 请求对象实现了ToJson接口
* @return 接口响应字符串
* @throws WxErrorException 异常
*/
String post(String url, ToJson obj) throws WxErrorException;
} }

View File

@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
import me.chanjar.weixin.common.bean.ToJson; import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxService;
import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
@ -18,7 +19,7 @@ import me.chanjar.weixin.cp.config.WxCpConfigStorage;
* *
* @author chanjaster * @author chanjaster
*/ */
public interface WxCpService { public interface WxCpService extends WxService {
/** /**
* <pre> * <pre>
* 验证推送过来的消息的正确性 * 验证推送过来的消息的正确性
@ -161,46 +162,6 @@ public interface WxCpService {
*/ */
WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException; WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候可以用这个针对所有微信API中的GET请求
*
* @param url 接口地址
* @param queryParam 请求参数
* @return the string
* @throws WxErrorException the wx error exception
*/
String get(String url, String queryParam) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候可以用这个针对所有微信API中的POST请求
*
* @param url 接口地址
* @param postData 请求body字符串
* @return the string
* @throws WxErrorException the wx error exception
*/
String post(String url, String postData) throws WxErrorException;
/**
* 内部使用.
*
* @param url 接口地址
* @param jsonObject 请求body的json对象
* @return the string
* @throws WxErrorException the wx error exception
*/
String post(String url, JsonObject jsonObject) throws WxErrorException;
/**
* 内部使用.
*
* @param url 接口地址
* @param obj 请求body的对象实现了ToJson接口
* @return the string
* @throws WxErrorException the wx error exception
*/
String post(String url, ToJson obj) throws WxErrorException;
/** /**
* 当不需要自动带accessToken的时候可以用这个发起post请求 * 当不需要自动带accessToken的时候可以用这个发起post请求
* *

View File

@ -222,6 +222,11 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
return this.post(url, obj.toJson()); return this.post(url, obj.toJson());
} }
@Override
public String post(String url, Object obj) throws WxErrorException {
return this.post(url, obj.toString());
}
@Override @Override
public String postWithoutToken(String url, String postData) throws WxErrorException { public String postWithoutToken(String url, String postData) throws WxErrorException {
return this.executeNormal(SimplePostRequestExecutor.create(this), url, postData); return this.executeNormal(SimplePostRequestExecutor.create(this), url, postData);
@ -319,7 +324,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
return null; return null;
} catch (IOException e) { } catch (IOException e) {
log.error("\n【请求地址】: {}\n【请求参数】{}\n【异常信息】{}", uri, data, e.getMessage()); log.error("\n【请求地址】: {}\n【请求参数】{}\n【异常信息】{}", uri, data, e.getMessage());
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).errorCode(-1).build(), e); throw new WxErrorException(e);
} }
} }

View File

@ -58,8 +58,7 @@ public class WxCpOaCalendarServiceImplTest {
@Test @Test
public void testGet() throws WxErrorException { public void testGet() throws WxErrorException {
final List<WxCpOaCalendar> calendars = this.wxService.getOaCalendarService() final List<WxCpOaCalendar> calendars = this.wxService.getOaCalendarService().get(Arrays.asList(calId));
.get(Arrays.asList(calId));
assertThat(calendars).isNotEmpty(); assertThat(calendars).isNotEmpty();
} }

View File

@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.api.WxImgProcService; import me.chanjar.weixin.common.api.WxImgProcService;
import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.common.api.WxOcrService;
import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxError;
@ -186,7 +187,15 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
public String post(String url, Object obj) throws WxErrorException { public String post(String url, Object obj) throws WxErrorException {
return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj)); return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
} }
@Override
public String post(String url, ToJson obj) throws WxErrorException {
return this.post(url, obj.toJson());
}
@Override
public String post(String url, JsonObject jsonObject) throws WxErrorException {
return this.post(url, jsonObject.toString());
}
/** /**
* 向微信端发送请求在这里执行的策略是当发生access_token过期时才去刷新然后重新执行请求而不是全局定时请求 * 向微信端发送请求在这里执行的策略是当发生access_token过期时才去刷新然后重新执行请求而不是全局定时请求
*/ */

View File

@ -43,7 +43,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(IDCARD, imgUrl), null); final String result = this.mainService.post(String.format(IDCARD, imgUrl), (String) null);
return WxOcrIdCardResult.fromJson(result); return WxOcrIdCardResult.fromJson(result);
} }
@ -62,7 +62,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(BANK_CARD, imgUrl), null); final String result = this.mainService.post(String.format(BANK_CARD, imgUrl), (String) null);
return WxOcrBankCardResult.fromJson(result); return WxOcrBankCardResult.fromJson(result);
} }
@ -81,7 +81,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(DRIVING, imgUrl), null); final String result = this.mainService.post(String.format(DRIVING, imgUrl), (String) null);
return WxOcrDrivingResult.fromJson(result); return WxOcrDrivingResult.fromJson(result);
} }
@ -100,7 +100,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(DRIVING_LICENSE, imgUrl), null); final String result = this.mainService.post(String.format(DRIVING_LICENSE, imgUrl), (String) null);
return WxOcrDrivingLicenseResult.fromJson(result); return WxOcrDrivingLicenseResult.fromJson(result);
} }
@ -119,7 +119,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(BIZ_LICENSE, imgUrl), null); final String result = this.mainService.post(String.format(BIZ_LICENSE, imgUrl), (String) null);
return WxOcrBizLicenseResult.fromJson(result); return WxOcrBizLicenseResult.fromJson(result);
} }
@ -138,7 +138,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
// ignore cannot happen // ignore cannot happen
} }
final String result = this.mainService.post(String.format(COMM, imgUrl), null); final String result = this.mainService.post(String.format(COMM, imgUrl), (String) null);
return WxOcrCommResult.fromJson(result); return WxOcrCommResult.fromJson(result);
} }

View File

@ -0,0 +1,54 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
/**
* 微信导购助手现在叫对话能力接口.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020 -10-06
*/
public interface WxMpGuideService {
/**
* 为服务号添加顾问
* <pre>
* 请求地址 POST https://api.weixin.qq.com/cgi-bin/guide/addguideacct?access_token=ACCESS_TOKEN
* 文档地址https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.addGuideAcct.html
* </pre>
*
* @param account 顾问微信号guide_account和guide_openid二选一若同时请求默认为guide_account
* @param openid 顾问openid或者unionidguide_account和guide_openid二选一
* @param headImgUrl 顾问头像头像url只能用上传图文消息内的图片获取URL me.chanjar.weixin.mp.api.impl.WxMpMaterialServiceImpl#mediaImgUpload(java.io.File)
* @param nickName 顾问昵称
* @throws WxErrorException .
*/
void addGuide(String account, String openid, String headImgUrl, String nickName) throws WxErrorException;
/**
* 为服务号添加顾问
* <pre>
* 请求地址 POST https://api.weixin.qq.com/cgi-bin/guide/addguideacct?access_token=ACCESS_TOKEN
* 文档地址https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.addGuideAcct.html
* </pre>
*
* @param guideInfo 顾问信息
* @throws WxErrorException .
*/
void addGuide(WxMpGuideInfo guideInfo) throws WxErrorException;
/**
* 获取顾问信息
*
* <pre>
* 请求地址 POST https://api.weixin.qq.com/cgi-bin/guide/getguideacct?access_token=ACCESS_TOKEN
* 文档地址https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.getGuideAcct.html
* </pre>
*
* @param account 顾问微信号guide_account和guide_openid二选一若同时请求默认为guide_account
* @param openid 顾问openid或者unionidguide_account和guide_openid二选一
* @return 顾问信息
* @throws WxErrorException .
*/
WxMpGuideInfo getGuide(String account, String openid) throws WxErrorException;
}

View File

@ -1,5 +1,6 @@
package me.chanjar.weixin.mp.api; package me.chanjar.weixin.mp.api;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.api.WxImgProcService; import me.chanjar.weixin.common.api.WxImgProcService;
import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.common.api.WxOcrService;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
@ -33,16 +34,16 @@ public interface WxMpService extends WxService {
* @param timestamp 时间戳 * @param timestamp 时间戳
* @param nonce 随机串 * @param nonce 随机串
* @param signature 签名 * @param signature 签名
* @return 是否验证通过 * @return 是否验证通过 boolean
*/ */
boolean checkSignature(String timestamp, String nonce, String signature); boolean checkSignature(String timestamp, String nonce, String signature);
/** /**
* 获取access_token, 不强制刷新access_token. * 获取access_token, 不强制刷新access_token.
* *
* @return token * @return token access token
* @throws WxErrorException . * @throws WxErrorException .
* @see #getAccessToken(boolean) * @see #getAccessToken(boolean) #getAccessToken(boolean)
*/ */
String getAccessToken() throws WxErrorException; String getAccessToken() throws WxErrorException;
@ -59,7 +60,7 @@ public interface WxMpService extends WxService {
* </pre> * </pre>
* *
* @param forceRefresh 是否强制刷新 * @param forceRefresh 是否强制刷新
* @return token * @return token access token
* @throws WxErrorException . * @throws WxErrorException .
*/ */
String getAccessToken(boolean forceRefresh) throws WxErrorException; String getAccessToken(boolean forceRefresh) throws WxErrorException;
@ -68,9 +69,9 @@ public interface WxMpService extends WxService {
* 获得ticket,不强制刷新ticket. * 获得ticket,不强制刷新ticket.
* *
* @param type ticket 类型 * @param type ticket 类型
* @return ticket * @return ticket ticket
* @throws WxErrorException . * @throws WxErrorException .
* @see #getTicket(TicketType, boolean) * @see #getTicket(TicketType, boolean) #getTicket(TicketType, boolean)
*/ */
String getTicket(TicketType type) throws WxErrorException; String getTicket(TicketType type) throws WxErrorException;
@ -82,7 +83,7 @@ public interface WxMpService extends WxService {
* *
* @param type ticket类型 * @param type ticket类型
* @param forceRefresh 强制刷新 * @param forceRefresh 强制刷新
* @return ticket * @return ticket ticket
* @throws WxErrorException . * @throws WxErrorException .
*/ */
String getTicket(TicketType type, boolean forceRefresh) throws WxErrorException; String getTicket(TicketType type, boolean forceRefresh) throws WxErrorException;
@ -92,7 +93,7 @@ public interface WxMpService extends WxService {
* *
* @return jsapi ticket * @return jsapi ticket
* @throws WxErrorException . * @throws WxErrorException .
* @see #getJsapiTicket(boolean) * @see #getJsapiTicket(boolean) #getJsapiTicket(boolean)
*/ */
String getJsapiTicket() throws WxErrorException; String getJsapiTicket() throws WxErrorException;
@ -118,7 +119,7 @@ public interface WxMpService extends WxService {
* </pre> * </pre>
* *
* @param url 地址 * @param url 地址
* @return 生成的签名对象 * @return 生成的签名对象 wx jsapi signature
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
@ -130,7 +131,7 @@ public interface WxMpService extends WxService {
* </pre> * </pre>
* *
* @param longUrl 长url * @param longUrl 长url
* @return 生成的短地址 * @return 生成的短地址 string
* @throws WxErrorException . * @throws WxErrorException .
*/ */
String shortUrl(String longUrl) throws WxErrorException; String shortUrl(String longUrl) throws WxErrorException;
@ -142,7 +143,7 @@ public interface WxMpService extends WxService {
* </pre> * </pre>
* *
* @param semanticQuery 查询条件 * @param semanticQuery 查询条件
* @return 查询结果 * @return 查询结果 wx mp semantic query result
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException;
@ -167,7 +168,7 @@ public interface WxMpService extends WxService {
* http://mp.weixin.qq.com/wiki/0/2ad4b6bfd29f30f71d39616c2a0fcedc.html * http://mp.weixin.qq.com/wiki/0/2ad4b6bfd29f30f71d39616c2a0fcedc.html
* </pre> * </pre>
* *
* @return 微信服务器ip地址数组 * @return 微信服务器ip地址数组 string [ ]
* @throws WxErrorException . * @throws WxErrorException .
*/ */
String[] getCallbackIP() throws WxErrorException; String[] getCallbackIP() throws WxErrorException;
@ -181,7 +182,7 @@ public interface WxMpService extends WxService {
* *
* @param action 执行的检测动作 * @param action 执行的检测动作
* @param operator 指定平台从某个运营商进行检测 * @param operator 指定平台从某个运营商进行检测
* @return 检测结果 * @return 检测结果 wx net check result
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxNetCheckResult netCheck(String action, String operator) throws WxErrorException; WxNetCheckResult netCheck(String action, String operator) throws WxErrorException;
@ -202,7 +203,7 @@ public interface WxMpService extends WxService {
* https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=ACCESS_TOKEN * https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=ACCESS_TOKEN
* </pre> * </pre>
* *
* @return 公众号的自动回复规则 * @return 公众号的自动回复规则 current auto reply info
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException; WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException;
@ -232,7 +233,7 @@ public interface WxMpService extends WxService {
* @param executor 执行器 * @param executor 执行器
* @param url 接口地址 * @param url 接口地址
* @param data 参数数据 * @param data 参数数据
* @return 结果 * @return 结果 t
* @throws WxErrorException 异常 * @throws WxErrorException 异常
*/ */
<T, E> T execute(RequestExecutor<T, E> executor, String url, E data) throws WxErrorException; <T, E> T execute(RequestExecutor<T, E> executor, String url, E data) throws WxErrorException;
@ -242,7 +243,7 @@ public interface WxMpService extends WxService {
* *
* @param url 请求接口地址 * @param url 请求接口地址
* @param queryParam 参数 * @param queryParam 参数
* @return 接口响应字符串 * @return 接口响应字符串 string
* @throws WxErrorException 异常 * @throws WxErrorException 异常
*/ */
String get(WxMpApiUrl url, String queryParam) throws WxErrorException; String get(WxMpApiUrl url, String queryParam) throws WxErrorException;
@ -252,11 +253,21 @@ public interface WxMpService extends WxService {
* *
* @param url 请求接口地址 * @param url 请求接口地址
* @param postData 请求参数json值 * @param postData 请求参数json值
* @return 接口响应字符串 * @return 接口响应字符串 string
* @throws WxErrorException 异常 * @throws WxErrorException 异常
*/ */
String post(WxMpApiUrl url, String postData) throws WxErrorException; String post(WxMpApiUrl url, String postData) throws WxErrorException;
/**
* 当本Service没有实现某个API的时候可以用这个针对所有微信API中的POST请求.
*
* @param url 请求接口地址
* @param jsonObject 请求参数json对象
* @return 接口响应字符串 string
* @throws WxErrorException 异常
*/
String post(WxMpApiUrl url, JsonObject jsonObject) throws WxErrorException;
/** /**
* <pre> * <pre>
* Service没有实现某个API的时候可以用这个 * Service没有实现某个API的时候可以用这个
@ -269,7 +280,7 @@ public interface WxMpService extends WxService {
* @param executor 执行器 * @param executor 执行器
* @param url 接口地址 * @param url 接口地址
* @param data 参数数据 * @param data 参数数据
* @return 结果 * @return 结果 t
* @throws WxErrorException 异常 * @throws WxErrorException 异常
*/ */
<T, E> T execute(RequestExecutor<T, E> executor, WxMpApiUrl url, E data) throws WxErrorException; <T, E> T execute(RequestExecutor<T, E> executor, WxMpApiUrl url, E data) throws WxErrorException;
@ -294,7 +305,7 @@ public interface WxMpService extends WxService {
/** /**
* 获取WxMpConfigStorage 对象. * 获取WxMpConfigStorage 对象.
* *
* @return WxMpConfigStorage * @return WxMpConfigStorage wx mp config storage
*/ */
WxMpConfigStorage getWxMpConfigStorage(); WxMpConfigStorage getWxMpConfigStorage();
@ -340,7 +351,7 @@ public interface WxMpService extends WxService {
* 进行相应的公众号切换. * 进行相应的公众号切换.
* *
* @param mpId 公众号标识 * @param mpId 公众号标识
* @return 切换是否成功 * @return 切换是否成功 boolean
*/ */
boolean switchover(String mpId); boolean switchover(String mpId);
@ -355,112 +366,112 @@ public interface WxMpService extends WxService {
/** /**
* 返回客服接口方法实现类以方便调用其各个接口. * 返回客服接口方法实现类以方便调用其各个接口.
* *
* @return WxMpKefuService * @return WxMpKefuService kefu service
*/ */
WxMpKefuService getKefuService(); WxMpKefuService getKefuService();
/** /**
* 返回素材相关接口方法的实现类对象以方便调用其各个接口. * 返回素材相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpMaterialService * @return WxMpMaterialService material service
*/ */
WxMpMaterialService getMaterialService(); WxMpMaterialService getMaterialService();
/** /**
* 返回菜单相关接口方法的实现类对象以方便调用其各个接口. * 返回菜单相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpMenuService * @return WxMpMenuService menu service
*/ */
WxMpMenuService getMenuService(); WxMpMenuService getMenuService();
/** /**
* 返回用户相关接口方法的实现类对象以方便调用其各个接口. * 返回用户相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpUserService * @return WxMpUserService user service
*/ */
WxMpUserService getUserService(); WxMpUserService getUserService();
/** /**
* 返回用户标签相关接口方法的实现类对象以方便调用其各个接口. * 返回用户标签相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpUserTagService * @return WxMpUserTagService user tag service
*/ */
WxMpUserTagService getUserTagService(); WxMpUserTagService getUserTagService();
/** /**
* 返回二维码相关接口方法的实现类对象以方便调用其各个接口. * 返回二维码相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpQrcodeService * @return WxMpQrcodeService qrcode service
*/ */
WxMpQrcodeService getQrcodeService(); WxMpQrcodeService getQrcodeService();
/** /**
* 返回卡券相关接口方法的实现类对象以方便调用其各个接口. * 返回卡券相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpCardService * @return WxMpCardService card service
*/ */
WxMpCardService getCardService(); WxMpCardService getCardService();
/** /**
* 返回数据分析统计相关接口方法的实现类对象以方便调用其各个接口. * 返回数据分析统计相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpDataCubeService * @return WxMpDataCubeService data cube service
*/ */
WxMpDataCubeService getDataCubeService(); WxMpDataCubeService getDataCubeService();
/** /**
* 返回用户黑名单管理相关接口方法的实现类对象以方便调用其各个接口. * 返回用户黑名单管理相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpUserBlacklistService * @return WxMpUserBlacklistService black list service
*/ */
WxMpUserBlacklistService getBlackListService(); WxMpUserBlacklistService getBlackListService();
/** /**
* 返回门店管理相关接口方法的实现类对象以方便调用其各个接口. * 返回门店管理相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpStoreService * @return WxMpStoreService store service
*/ */
WxMpStoreService getStoreService(); WxMpStoreService getStoreService();
/** /**
* 返回模板消息相关接口方法的实现类对象以方便调用其各个接口. * 返回模板消息相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpTemplateMsgService * @return WxMpTemplateMsgService template msg service
*/ */
WxMpTemplateMsgService getTemplateMsgService(); WxMpTemplateMsgService getTemplateMsgService();
/** /**
* 返回一次性订阅消息相关接口方法的实现类对象以方便调用其各个接口. * 返回一次性订阅消息相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpSubscribeMsgService * @return WxMpSubscribeMsgService subscribe msg service
*/ */
WxMpSubscribeMsgService getSubscribeMsgService(); WxMpSubscribeMsgService getSubscribeMsgService();
/** /**
* 返回硬件平台相关接口方法的实现类对象以方便调用其各个接口. * 返回硬件平台相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpDeviceService * @return WxMpDeviceService device service
*/ */
WxMpDeviceService getDeviceService(); WxMpDeviceService getDeviceService();
/** /**
* 返回摇一摇周边相关接口方法的实现类对象以方便调用其各个接口. * 返回摇一摇周边相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpShakeService * @return WxMpShakeService shake service
*/ */
WxMpShakeService getShakeService(); WxMpShakeService getShakeService();
/** /**
* 返回会员卡相关接口方法的实现类对象以方便调用其各个接口. * 返回会员卡相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpMemberCardService * @return WxMpMemberCardService member card service
*/ */
WxMpMemberCardService getMemberCardService(); WxMpMemberCardService getMemberCardService();
/** /**
* 返回营销相关接口方法的实现类对象以方便调用其各个接口. * 返回营销相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpMarketingService * @return WxMpMarketingService marketing service
*/ */
WxMpMarketingService getMarketingService(); WxMpMarketingService getMarketingService();
@ -472,42 +483,42 @@ public interface WxMpService extends WxService {
/** /**
* 获取RequestHttp对象. * 获取RequestHttp对象.
* *
* @return RequestHttp对象 * @return RequestHttp对象 request http
*/ */
RequestHttp getRequestHttp(); RequestHttp getRequestHttp();
/** /**
* 返回群发消息相关接口方法的实现类对象以方便调用其各个接口. * 返回群发消息相关接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpMassMessageService * @return WxMpMassMessageService mass message service
*/ */
WxMpMassMessageService getMassMessageService(); WxMpMassMessageService getMassMessageService();
/** /**
* 返回AI开放接口方法的实现类对象以方便调用其各个接口. * 返回AI开放接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpAiOpenService * @return WxMpAiOpenService ai open service
*/ */
WxMpAiOpenService getAiOpenService(); WxMpAiOpenService getAiOpenService();
/** /**
* 返回WIFI接口方法的实现类对象以方便调用其各个接口. * 返回WIFI接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpWifiService * @return WxMpWifiService wifi service
*/ */
WxMpWifiService getWifiService(); WxMpWifiService getWifiService();
/** /**
* 返回WIFI接口方法的实现类对象以方便调用其各个接口. * 返回WIFI接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpWifiService * @return WxMpWifiService ocr service
*/ */
WxOcrService getOcrService(); WxOcrService getOcrService();
/** /**
* 返回图像处理接口的实现类对象以方便调用其各个接口. * 返回图像处理接口的实现类对象以方便调用其各个接口.
* *
* @return WxImgProcService * @return WxImgProcService img proc service
*/ */
WxImgProcService getImgProcService(); WxImgProcService getImgProcService();
@ -647,7 +658,7 @@ public interface WxMpService extends WxService {
/** /**
* 返回评论数据管理接口方法的实现类对象以方便调用其各个接口. * 返回评论数据管理接口方法的实现类对象以方便调用其各个接口.
* *
* @return WxMpWifiService * @return WxMpWifiService comment service
*/ */
WxMpCommentService getCommentService(); WxMpCommentService getCommentService();
@ -671,4 +682,18 @@ public interface WxMpService extends WxService {
* @param oAuth2Service the o auth 2 service * @param oAuth2Service the o auth 2 service
*/ */
void setOAuth2Service(WxOAuth2Service oAuth2Service); void setOAuth2Service(WxOAuth2Service oAuth2Service);
/**
* Gets guide service.
*
* @return the guide service
*/
WxMpGuideService getGuideService();
/**
* Sets guide service.
*
* @param guideService the guide service
*/
void setGuideService(WxMpGuideService guideService);
} }

View File

@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.api.WxImgProcService; import me.chanjar.weixin.common.api.WxImgProcService;
import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.common.api.WxOcrService;
import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxNetCheckResult; import me.chanjar.weixin.common.bean.WxNetCheckResult;
@ -119,6 +120,10 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
@Setter @Setter
private WxMpMerchantInvoiceService merchantInvoiceService = new WxMpMerchantInvoiceServiceImpl(this, this.cardService); private WxMpMerchantInvoiceService merchantInvoiceService = new WxMpMerchantInvoiceServiceImpl(this, this.cardService);
@Getter
@Setter
private WxMpGuideService guideService = new WxMpGuideServiceImpl(this);
@Getter @Getter
@Setter @Setter
private WxOAuth2Service oAuth2Service = new WxOAuth2ServiceImpl(this); private WxOAuth2Service oAuth2Service = new WxOAuth2ServiceImpl(this);
@ -278,6 +283,21 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
return this.post(url.getUrl(this.getWxMpConfigStorage()), postData); return this.post(url.getUrl(this.getWxMpConfigStorage()), postData);
} }
@Override
public String post(WxMpApiUrl url, JsonObject jsonObject) throws WxErrorException {
return this.post(url.getUrl(this.getWxMpConfigStorage()), jsonObject.toString());
}
@Override
public String post(String url, ToJson obj) throws WxErrorException {
return this.post(url, obj.toJson());
}
@Override
public String post(String url, JsonObject jsonObject) throws WxErrorException {
return this.post(url, jsonObject.toString());
}
@Override @Override
public String post(String url, Object obj) throws WxErrorException { public String post(String url, Object obj) throws WxErrorException {
return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj)); return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
@ -366,7 +386,7 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
return null; return null;
} catch (IOException e) { } catch (IOException e) {
log.error("\n【请求地址】: {}\n【请求参数】{}\n【异常信息】{}", uriWithAccessToken, dataForLog, e.getMessage()); log.error("\n【请求地址】: {}\n【请求参数】{}\n【异常信息】{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); throw new WxErrorException(e);
} }
} }
@ -475,4 +495,13 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
return this; return this;
} }
@Override
public WxMpGuideService getGuideService() {
return this.guideService;
}
@Override
public void setGuideService(WxMpGuideService guideService) {
this.guideService = guideService;
}
} }

View File

@ -0,0 +1,43 @@
package me.chanjar.weixin.mp.api.impl;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.api.WxMpGuideService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
import me.chanjar.weixin.mp.enums.WxMpApiUrl;
/**
* .
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-06
*/
@AllArgsConstructor
public class WxMpGuideServiceImpl implements WxMpGuideService {
private static final String ACCOUNT = "guide_account";
private static final String OPENID = "guide_openid";
private final WxMpService mpService;
@Override
public void addGuide(String account, String openid, String headImgUrl, String nickName) throws WxErrorException {
this.mpService.post(WxMpApiUrl.Guide.ADD_GUIDE, GsonHelper.buildJsonObject(ACCOUNT, account,
"guide_headimgurl", headImgUrl, "guide_nickname", nickName, OPENID, openid));
}
@Override
public void addGuide(WxMpGuideInfo guideInfo) throws WxErrorException {
this.mpService.post(WxMpApiUrl.Guide.ADD_GUIDE,
GsonHelper.buildJsonObject(ACCOUNT, guideInfo.getAccount(),
"guide_headimgurl", guideInfo.getHeadImgUrl(),
"guide_nickname", guideInfo.getNickName(),
OPENID, guideInfo.getOpenid()));
}
@Override
public WxMpGuideInfo getGuide(String account, String openid) throws WxErrorException {
return WxMpGuideInfo.fromJson(this.mpService.post(WxMpApiUrl.Guide.GET_GUIDE,
GsonHelper.buildJsonObject(ACCOUNT, account, OPENID, openid)));
}
}

View File

@ -1,34 +1,18 @@
package me.chanjar.weixin.mp.api.impl; package me.chanjar.weixin.mp.api.impl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.common.api.WxOcrService;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.common.bean.ocr.*;
import me.chanjar.weixin.common.bean.ocr.WxOcrBankCardResult; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.bean.ocr.WxOcrBizLicenseResult;
import me.chanjar.weixin.common.bean.ocr.WxOcrCommResult;
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingLicenseResult;
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingResult;
import me.chanjar.weixin.common.bean.ocr.WxOcrIdCardResult;
import me.chanjar.weixin.common.requestexecuter.ocr.OcrDiscernRequestExecutor; import me.chanjar.weixin.common.requestexecuter.ocr.OcrDiscernRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpService;
import java.io.File; import java.io.File;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.BANK_CARD; import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.*;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.BIZ_LICENSE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.COMM;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.DRIVING;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.DRIVING_LICENSE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILEIDCARD;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_BANK_CARD;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_BIZ_LICENSE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_COMM;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_DRIVING;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_DRIVING_LICENSE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.IDCARD;
/** /**
* ocr 接口实现. * ocr 接口实现.
@ -49,7 +33,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(IDCARD.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(IDCARD.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrIdCardResult.fromJson(result); return WxOcrIdCardResult.fromJson(result);
} }
@ -69,7 +53,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(BANK_CARD.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(BANK_CARD.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrBankCardResult.fromJson(result); return WxOcrBankCardResult.fromJson(result);
} }
@ -89,7 +73,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(DRIVING.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(DRIVING.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrDrivingResult.fromJson(result); return WxOcrDrivingResult.fromJson(result);
} }
@ -109,7 +93,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(DRIVING_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(DRIVING_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrDrivingLicenseResult.fromJson(result); return WxOcrDrivingLicenseResult.fromJson(result);
} }
@ -129,7 +113,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(BIZ_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(BIZ_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrBizLicenseResult.fromJson(result); return WxOcrBizLicenseResult.fromJson(result);
} }
@ -149,7 +133,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
} }
final String result = this.mainService.post(String.format(COMM.getUrl(this.mainService.getWxMpConfigStorage()), final String result = this.mainService.post(String.format(COMM.getUrl(this.mainService.getWxMpConfigStorage()),
imgUrl), null); imgUrl), (String) null);
return WxOcrCommResult.fromJson(result); return WxOcrCommResult.fromJson(result);
} }

View File

@ -0,0 +1,66 @@
package me.chanjar.weixin.mp.bean.guide;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import java.io.Serializable;
/**
* 对话能力-顾问信息.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-06
*/
@Data
@Builder
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class WxMpGuideInfo implements ToJson, Serializable {
private static final long serialVersionUID = -8159470115679031290L;
/**
* 顾问的微信帐号
*/
@SerializedName("guide_account")
private String account;
/**
* 顾问的openid或者unionid
*/
@SerializedName("guide_openid")
private String openid;
/**
* 顾问昵称
*/
@SerializedName("guide_nickname")
private String nickName;
/**
* 顾问头像
*/
@SerializedName("guide_headimgurl")
private String headImgUrl;
/**
* 顾问状态1:确认中2已确认3已拒绝4已过期
*/
@SerializedName("status")
private Integer status;
@Override
public String toJson() {
return WxGsonBuilder.create().toJson(this);
}
public static WxMpGuideInfo fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxMpGuideInfo.class);
}
}

View File

@ -1156,4 +1156,31 @@ public interface WxMpApiUrl {
return buildUrl(config.getHostConfig(), prefix, path); return buildUrl(config.getHostConfig(), prefix, path);
} }
} }
/**
* 对话能力
*/
@AllArgsConstructor
enum Guide implements WxMpApiUrl {
/**
* 添加顾问
*/
ADD_GUIDE(API_DEFAULT_HOST_URL, "/cgi-bin/guide/addguideacct"),
/**
* 获取顾问信息
*/
GET_GUIDE(API_DEFAULT_HOST_URL, "/cgi-bin/guide/getguideacct");
private final String prefix;
private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (null == config) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
}
} }

View File

@ -0,0 +1,39 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.test.ApiTestModule;
import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 单元测试.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-06
*/
@Guice(modules = ApiTestModule.class)
public class WxMpGuideServiceImplTest {
@Inject
protected WxMpService wxService;
@Test
public void testAddGuide() throws WxErrorException {
this.wxService.getGuideService().addGuide("abc", "", null, null);
}
@Test
public void testAddGuide_another() throws WxErrorException {
this.wxService.getGuideService().addGuide(WxMpGuideInfo.builder().account("cde").build());
}
@Test
public void testGetGuide() throws WxErrorException {
final WxMpGuideInfo guideInfo = this.wxService.getGuideService().getGuide("abc", null);
assertThat(guideInfo).isNotNull();
}
}