mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 07:11:52 +08:00
mp:location 的自动回复;关注后的自动回复
This commit is contained in:
parent
44f0bcd182
commit
69e653cd94
@ -34,4 +34,11 @@ public interface MpAutoReplyMapper extends BaseMapperX<MpAutoReplyDO> {
|
||||
.eq(MpAutoReplyDO::getType, MpAutoReplyTypeEnum.MESSAGE.getType())
|
||||
.eq(MpAutoReplyDO::getRequestMessageType, requestMessageType));
|
||||
}
|
||||
|
||||
default List<MpAutoReplyDO> selectListByAppIdAndSubscribe(String appId) {
|
||||
return selectList(new LambdaQueryWrapperX<MpAutoReplyDO>()
|
||||
.eq(MpAutoReplyDO::getAppId, appId)
|
||||
.eq(MpAutoReplyDO::getType, MpAutoReplyTypeEnum.SUBSCRIBE.getType()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class MpConfiguration {
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
public MpServiceFactory mpServiceFactory(RedisTemplateWxRedisOps redisTemplateWxRedisOps,
|
||||
WxMpProperties wxMpProperties,
|
||||
MessageReceiveHandler logHandler,
|
||||
MessageReceiveHandler messageReceiveHandler,
|
||||
KfSessionHandler kfSessionHandler,
|
||||
StoreCheckNotifyHandler storeCheckNotifyHandler,
|
||||
MenuHandler menuHandler,
|
||||
@ -45,10 +45,10 @@ public class MpConfiguration {
|
||||
UnsubscribeHandler unsubscribeHandler,
|
||||
LocationHandler locationHandler,
|
||||
ScanHandler scanHandler,
|
||||
MessageAutoReplyHandler msgHandler) {
|
||||
MessageAutoReplyHandler messageAutoReplyHandler) {
|
||||
return new DefaultMpServiceFactory(redisTemplateWxRedisOps, wxMpProperties,
|
||||
logHandler, kfSessionHandler, storeCheckNotifyHandler, menuHandler,
|
||||
nullHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler, msgHandler);
|
||||
messageReceiveHandler, kfSessionHandler, storeCheckNotifyHandler, menuHandler,
|
||||
nullHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler, messageAutoReplyHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class DefaultMpServiceFactory implements MpServiceFactory {
|
||||
|
||||
// ========== 各种 Handler ==========
|
||||
|
||||
private final MessageReceiveHandler logHandler;
|
||||
private final MessageReceiveHandler messageReceiveHandler;
|
||||
private final KfSessionHandler kfSessionHandler;
|
||||
private final StoreCheckNotifyHandler storeCheckNotifyHandler;
|
||||
private final MenuHandler menuHandler;
|
||||
@ -58,7 +58,7 @@ public class DefaultMpServiceFactory implements MpServiceFactory {
|
||||
private final UnsubscribeHandler unsubscribeHandler;
|
||||
private final LocationHandler locationHandler;
|
||||
private final ScanHandler scanHandler;
|
||||
private final MessageAutoReplyHandler msgHandler;
|
||||
private final MessageAutoReplyHandler messageAutoReplyHandler;
|
||||
|
||||
@Override
|
||||
public void init(List<MpAccountDO> list) {
|
||||
@ -108,7 +108,7 @@ public class DefaultMpServiceFactory implements MpServiceFactory {
|
||||
private WxMpMessageRouter buildMpMessageRouter(WxMpService mpService) {
|
||||
WxMpMessageRouter router = new WxMpMessageRouter(mpService);
|
||||
// 记录所有事件的日志(异步执行)
|
||||
router.rule().handler(logHandler).next();
|
||||
router.rule().handler(messageReceiveHandler).next();
|
||||
|
||||
// 接收客服会话管理事件
|
||||
router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
@ -159,7 +159,7 @@ public class DefaultMpServiceFactory implements MpServiceFactory {
|
||||
.event(WxConsts.EventType.SCAN).handler(scanHandler).end();
|
||||
|
||||
// 默认
|
||||
router.rule().async(false).handler(msgHandler).end();
|
||||
router.rule().async(false).handler(messageAutoReplyHandler).end();
|
||||
return router;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
package cn.iocoder.yudao.module.mp.service.handler.user;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder;
|
||||
import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
@ -8,38 +13,37 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 上报地理位置的事件处理器
|
||||
*
|
||||
* // TODO @芋艿:需要实现一下~
|
||||
* 触发操作:打开微信公众号 -> 点击 + 号 -> 选择「语音」
|
||||
*
|
||||
* 逻辑:用户上传地理位置时,也可以触发自动回复
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LocationHandler implements WxMpMessageHandler {
|
||||
|
||||
@Resource
|
||||
private MpAutoReplyService mpAutoReplyService;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||
WxMpService wxMpService, WxSessionManager sessionManager) {
|
||||
// if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) {
|
||||
// //TODO 接收处理用户发送的地理位置消息
|
||||
// try {
|
||||
// String content = "感谢反馈,您的的地理位置已收到!";
|
||||
// return new TextBuilder().build(content, wxMessage, null);
|
||||
// } catch (Exception e) {
|
||||
// log.error("位置消息接收处理失败", e);
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //上报地理位置事件
|
||||
// log.info("上报地理位置,纬度 : {},经度 : {},精度 : {}",
|
||||
// wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision()));
|
||||
// 防御性编程:必须是 LOCATION 消息
|
||||
if (ObjectUtil.notEqual(wxMessage.getMsgType(), WxConsts.XmlMsgType.LOCATION)) {
|
||||
return null;
|
||||
}
|
||||
log.info("[handle][上报地理位置,纬度({})、经度({})、精度({})", wxMessage.getLatitude(),
|
||||
wxMessage.getLongitude(), wxMessage.getPrecision());
|
||||
|
||||
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
|
||||
|
||||
return null;
|
||||
// 自动回复
|
||||
return mpAutoReplyService.replyForMessage(MpContextHolder.getAppId(), wxMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mp.service.handler.user;
|
||||
import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
|
||||
import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder;
|
||||
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||
import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService;
|
||||
import cn.iocoder.yudao.module.mp.service.user.MpUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
@ -22,19 +23,15 @@ import java.util.Map;
|
||||
* 关注的事件处理器
|
||||
*
|
||||
* @author 芋道源码
|
||||
*
|
||||
* // TODO 芋艿:待实现
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SubscribeHandler implements WxMpMessageHandler {
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,解决循环依赖的问题
|
||||
private MpAccountService mpAccountService;
|
||||
|
||||
@Resource
|
||||
private MpUserService mpUserService;
|
||||
@Resource
|
||||
private MpAutoReplyService mpAutoReplyService;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||
@ -49,24 +46,10 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
||||
}
|
||||
|
||||
// 第二步,保存用户信息
|
||||
MpUserDO mpUser = null;
|
||||
if (wxMpUser != null) {
|
||||
mpUser = mpUserService.saveUser(MpContextHolder.getAppId(), wxMpUser);
|
||||
}
|
||||
mpUserService.saveUser(MpContextHolder.getAppId(), wxMpUser);
|
||||
|
||||
// 第三步,回复关注的欢迎语 TODO 芋艿:关注的欢迎语
|
||||
// return new TextBuilder().build("感谢关注", wxMessage, weixinService);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理
|
||||
*/
|
||||
private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage)
|
||||
throws Exception {
|
||||
|
||||
//TODO
|
||||
return null;
|
||||
// 第三步,回复关注的欢迎语
|
||||
return mpAutoReplyService.replyForSubscribe(MpContextHolder.getAppId(), wxMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,4 +19,13 @@ public interface MpAutoReplyService {
|
||||
*/
|
||||
WxMpXmlOutMessage replyForMessage(String appId, WxMpXmlMessage wxMessage);
|
||||
|
||||
/**
|
||||
* 当用户关注时,自动回复
|
||||
*
|
||||
* @param appId 微信公众号 appId
|
||||
* @param wxMessage 消息
|
||||
* @return 回复的消息
|
||||
*/
|
||||
WxMpXmlOutMessage replyForSubscribe(String appId, WxMpXmlMessage wxMessage);
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
package cn.iocoder.yudao.module.mp.service.message;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.module.mp.builder.TextBuilder;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||
import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpAutoReplyDO;
|
||||
import cn.iocoder.yudao.module.mp.dal.mysql.message.MpAutoReplyMapper;
|
||||
import cn.iocoder.yudao.module.mp.enums.message.MpAutoReplyMatchEnum;
|
||||
import cn.iocoder.yudao.module.mp.enums.message.MpAutoReplyTypeEnum;
|
||||
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@ -25,15 +28,15 @@ public class MpAutoReplyServiceImpl implements MpAutoReplyService {
|
||||
|
||||
@Resource
|
||||
private MpMessageService mpMessageService;
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private MpAccountService mpAccountService;
|
||||
|
||||
@Resource
|
||||
private MpAutoReplyMapper mpAutoReplyMapper;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage replyForMessage(String appId, WxMpXmlMessage wxMessage) {
|
||||
// if (true) {
|
||||
// return new TextBuilder().build("nihao", wxMessage, null);
|
||||
// }
|
||||
// 第一步,匹配自动回复
|
||||
List<MpAutoReplyDO> replies = null;
|
||||
// 1.1 关键字
|
||||
@ -58,4 +61,24 @@ public class MpAutoReplyServiceImpl implements MpAutoReplyService {
|
||||
return mpMessageService.createFromAutoReply(wxMessage.getFromUser(), reply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage replyForSubscribe(String appId, WxMpXmlMessage wxMessage) {
|
||||
// 第一步,匹配自动回复
|
||||
List<MpAutoReplyDO> replies = mpAutoReplyMapper.selectListByAppIdAndSubscribe(appId);
|
||||
MpAutoReplyDO reply = CollUtil.isNotEmpty(replies) ? CollUtil.getFirst(replies)
|
||||
: buildDefaultSubscribeAutoReply(appId); // 如果不存在,提供一个默认末班
|
||||
|
||||
// 第二步,基于自动回复,创建消息
|
||||
return mpMessageService.createFromAutoReply(wxMessage.getFromUser(), reply);
|
||||
}
|
||||
|
||||
private MpAutoReplyDO buildDefaultSubscribeAutoReply(String appId) {
|
||||
MpAccountDO account = mpAccountService.getAccountFromCache(appId);
|
||||
Assert.notNull(account, "公众号账号({}) 不存在", appId);
|
||||
// 构建默认的【关注】自动回复
|
||||
return new MpAutoReplyDO().setAppId(appId).setAccountId(account.getId())
|
||||
.setType(MpAutoReplyTypeEnum.SUBSCRIBE.getType())
|
||||
.setResponseMessageType(WxConsts.XmlMsgType.TEXT).setResponseContent("感谢关注");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class MpMessageServiceImpl implements MpMessageService {
|
||||
}
|
||||
mpMessageMapper.insert(message);
|
||||
|
||||
// WxConsts.MenuButtonType.VIEW
|
||||
// WxConsts.MenuButtonType.VIEW TODO 芋艿:待测试
|
||||
// wxMessage.getEventKey()
|
||||
|
||||
// WxConsts.MenuButtonType.CLICK
|
||||
|
Loading…
Reference in New Issue
Block a user