package cn.iocoder.yudao.module.mp.framework.mp.core; import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; import cn.iocoder.yudao.module.mp.service.handler.menu.MenuHandler; import cn.iocoder.yudao.module.mp.service.handler.message.MessageReceiveHandler; import cn.iocoder.yudao.module.mp.service.handler.message.MessageAutoReplyHandler; import cn.iocoder.yudao.module.mp.service.handler.other.KfSessionHandler; import cn.iocoder.yudao.module.mp.service.handler.other.NullHandler; import cn.iocoder.yudao.module.mp.service.handler.other.ScanHandler; import cn.iocoder.yudao.module.mp.service.handler.other.StoreCheckNotifyHandler; import cn.iocoder.yudao.module.mp.service.handler.user.LocationHandler; import cn.iocoder.yudao.module.mp.service.handler.user.SubscribeHandler; import cn.iocoder.yudao.module.mp.service.handler.user.UnsubscribeHandler; import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; import com.google.common.collect.Maps; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; import me.chanjar.weixin.mp.constant.WxMpEventConstants; import java.util.List; import java.util.Map; /** * 默认的 {@link MpServiceFactory} 实现类 * * @author 芋道源码 */ @Slf4j @RequiredArgsConstructor public class DefaultMpServiceFactory implements MpServiceFactory { /** * 微信 appId 与 WxMpService 的映射 */ private volatile Map appId2MpServices; /** * 公众号账号 id 与 WxMpService 的映射 */ private volatile Map id2MpServices; /** * 微信 appId 与 WxMpMessageRouter 的映射 */ private volatile Map mpMessageRouters; private final RedisTemplateWxRedisOps redisTemplateWxRedisOps; private final WxMpProperties mpProperties; // ========== 各种 Handler ========== private final MessageReceiveHandler messageReceiveHandler; private final KfSessionHandler kfSessionHandler; private final StoreCheckNotifyHandler storeCheckNotifyHandler; private final MenuHandler menuHandler; private final NullHandler nullHandler; private final SubscribeHandler subscribeHandler; private final UnsubscribeHandler unsubscribeHandler; private final LocationHandler locationHandler; private final ScanHandler scanHandler; private final MessageAutoReplyHandler messageAutoReplyHandler; @Override public void init(List list) { Map appId2MpServices = Maps.newHashMap(); Map id2MpServices = Maps.newHashMap(); Map mpMessageRouters = Maps.newHashMap(); // 处理 list list.forEach(account -> { // 构建 WxMpService 对象 WxMpService mpService = buildMpService(account); appId2MpServices.put(account.getAppId(), mpService); id2MpServices.put(account.getId(), mpService); // 构建 WxMpMessageRouter 对象 WxMpMessageRouter mpMessageRouter = buildMpMessageRouter(mpService); mpMessageRouters.put(account.getAppId(), mpMessageRouter); }); // 设置到缓存 this.appId2MpServices = appId2MpServices; this.id2MpServices = id2MpServices; this.mpMessageRouters = mpMessageRouters; } @Override public WxMpService getMpService(Long id) { return id2MpServices.get(id); } @Override public WxMpService getMpService(String appId) { return appId2MpServices.get(appId); } @Override public WxMpMessageRouter getMpMessageRouter(String appId) { return mpMessageRouters.get(appId); } private WxMpService buildMpService(MpAccountDO account) { // 第一步,创建 WxMpRedisConfigImpl 对象 WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( redisTemplateWxRedisOps, mpProperties.getConfigStorage().getKeyPrefix()); configStorage.setAppId(account.getAppId()); configStorage.setSecret(account.getAppSecret()); configStorage.setToken(account.getToken()); configStorage.setAesKey(account.getAesKey()); // 第二步,创建 WxMpService 对象 WxMpService service = new WxMpServiceImpl(); service.setWxMpConfigStorage(configStorage); return service; } private WxMpMessageRouter buildMpMessageRouter(WxMpService mpService) { WxMpMessageRouter router = new WxMpMessageRouter(mpService); // 记录所有事件的日志(异步执行) router.rule().handler(messageReceiveHandler).next(); // 接收客服会话管理事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION) .handler(kfSessionHandler).end(); router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION) .handler(kfSessionHandler) .end(); router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION) .handler(kfSessionHandler).end(); // 门店审核事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxMpEventConstants.POI_CHECK_NOTIFY) .handler(storeCheckNotifyHandler).end(); // 自定义菜单事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end(); // 点击菜单连接事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end(); // 关注事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler) .end(); // 取消关注事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.EventType.UNSUBSCRIBE) .handler(unsubscribeHandler).end(); // 上报地理位置事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.EventType.LOCATION).handler(locationHandler) .end(); // 接收地理位置消息 router.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION) .handler(locationHandler).end(); // 扫码事件 router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) .event(WxConsts.EventType.SCAN).handler(scanHandler).end(); // 默认 router.rule().async(false).handler(messageAutoReplyHandler).end(); return router; } }