mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
mp:增加 MpServiceFactory 管理创建的 MpService~
This commit is contained in:
parent
627cb39517
commit
275a1b10f6
@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.*;
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.*;
|
||||||
import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert;
|
import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@ -25,7 +25,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|||||||
public class MpAccountController {
|
public class MpAccountController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private WxAccountService wxAccountService;
|
private MpAccountService wxAccountService;
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@ApiOperation("创建公众号账户")
|
@ApiOperation("创建公众号账户")
|
||||||
|
@ -63,13 +63,4 @@ public class MpAccountDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
// TODO 芋艿:需要迁移走
|
|
||||||
public WxMpConfigStorage toWxMpConfigStorage(RedisTemplateWxRedisOps redisTemplateWxRedisOps, WxMpProperties wxMpProperties) {
|
|
||||||
WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisTemplateWxRedisOps, wxMpProperties.getConfigStorage().getKeyPrefix());
|
|
||||||
wxMpRedisConfig.setAppId(appId);
|
|
||||||
wxMpRedisConfig.setSecret(appSecret);
|
|
||||||
wxMpRedisConfig.setToken(token);
|
|
||||||
wxMpRedisConfig.setAesKey(aesKey);
|
|
||||||
return wxMpRedisConfig;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|||||||
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO;
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface MpAccountMapper extends BaseMapperX<MpAccountDO> {
|
public interface MpAccountMapper extends BaseMapperX<MpAccountDO> {
|
||||||
@ -18,4 +21,7 @@ public interface MpAccountMapper extends BaseMapperX<MpAccountDO> {
|
|||||||
.orderByDesc(MpAccountDO::getId));
|
.orderByDesc(MpAccountDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Select("SELECT COUNT(*) FROM mp_account WHERE update_time > #{maxUpdateTime}")
|
||||||
|
Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.framework.mp.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.mp.framework.mp.core.DefaultMpServiceFactory;
|
||||||
|
import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.fansmsgres.NullHandler;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.handler.*;
|
||||||
|
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
||||||
|
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信公众号的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class MpConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||||
|
public RedisTemplateWxRedisOps redisTemplateWxRedisOps(StringRedisTemplate stringRedisTemplate) {
|
||||||
|
return new RedisTemplateWxRedisOps(stringRedisTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||||
|
public MpServiceFactory mpServiceFactory(RedisTemplateWxRedisOps redisTemplateWxRedisOps,
|
||||||
|
WxMpProperties wxMpProperties,
|
||||||
|
LogHandler logHandler,
|
||||||
|
KfSessionHandler kfSessionHandler,
|
||||||
|
StoreCheckNotifyHandler storeCheckNotifyHandler,
|
||||||
|
MenuHandler menuHandler,
|
||||||
|
NullHandler nullHandler,
|
||||||
|
SubscribeHandler subscribeHandler,
|
||||||
|
UnsubscribeHandler unsubscribeHandler,
|
||||||
|
LocationHandler locationHandler,
|
||||||
|
ScanHandler scanHandler,
|
||||||
|
DefaultMessageHandler msgHandler) {
|
||||||
|
return new DefaultMpServiceFactory(redisTemplateWxRedisOps, wxMpProperties,
|
||||||
|
logHandler, kfSessionHandler, storeCheckNotifyHandler, menuHandler,
|
||||||
|
nullHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler, msgHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
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.fansmsgres.NullHandler;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.handler.*;
|
||||||
|
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<String, WxMpService> mpServices;
|
||||||
|
/**
|
||||||
|
* 微信 appId 与 WxMpMessageRouter 的映射
|
||||||
|
*/
|
||||||
|
private volatile Map<String, WxMpMessageRouter> mpMessageRouters;
|
||||||
|
|
||||||
|
private final RedisTemplateWxRedisOps redisTemplateWxRedisOps;
|
||||||
|
private final WxMpProperties mpProperties;
|
||||||
|
|
||||||
|
// ========== 各种 Handler ==========
|
||||||
|
|
||||||
|
private final LogHandler logHandler;
|
||||||
|
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 DefaultMessageHandler msgHandler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(List<MpAccountDO> list) {
|
||||||
|
Map<String, WxMpService> mpServices = Maps.newHashMap();
|
||||||
|
Map<String, WxMpMessageRouter> mpMessageRouters = Maps.newHashMap();
|
||||||
|
// 处理 list
|
||||||
|
list.forEach(account -> {
|
||||||
|
// 构建 WxMpService 对象
|
||||||
|
WxMpService mpService = buildMpService(account);
|
||||||
|
mpServices.put(account.getAppId(), mpService);
|
||||||
|
// 构建 WxMpMessageRouter 对象
|
||||||
|
WxMpMessageRouter mpMessageRouter = buildMpMessageRouter(mpService);
|
||||||
|
mpMessageRouters.put(account.getAppId(), mpMessageRouter);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置到缓存
|
||||||
|
this.mpServices = mpServices;
|
||||||
|
this.mpMessageRouters = mpMessageRouters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpService getMpService(String appId) {
|
||||||
|
return mpServices.get(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpMessageRouter getMpMessageRouter(String appId) {
|
||||||
|
return mpMessageRouters.get(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WxMpService buildMpService(MpAccountDO account) {
|
||||||
|
// 第一步,创建 WxMpRedisConfigImpl 对象
|
||||||
|
// TODO 芋艿:需要确认下,redis key 的存储结构
|
||||||
|
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 null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WxMpMessageRouter buildMpMessageRouter(WxMpService mpService) {
|
||||||
|
final WxMpMessageRouter newRouter = new WxMpMessageRouter(mpService);
|
||||||
|
// 记录所有事件的日志(异步执行)
|
||||||
|
newRouter.rule().handler(logHandler).next();
|
||||||
|
|
||||||
|
// 接收客服会话管理事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
|
||||||
|
.handler(kfSessionHandler).end();
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
|
||||||
|
.handler(kfSessionHandler)
|
||||||
|
.end();
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
|
||||||
|
.handler(kfSessionHandler).end();
|
||||||
|
|
||||||
|
// 门店审核事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxMpEventConstants.POI_CHECK_NOTIFY)
|
||||||
|
.handler(storeCheckNotifyHandler).end();
|
||||||
|
|
||||||
|
// 自定义菜单事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end();
|
||||||
|
|
||||||
|
// 点击菜单连接事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end();
|
||||||
|
|
||||||
|
// 关注事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler)
|
||||||
|
.end();
|
||||||
|
|
||||||
|
// 取消关注事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.EventType.UNSUBSCRIBE)
|
||||||
|
.handler(unsubscribeHandler).end();
|
||||||
|
|
||||||
|
// 上报地理位置事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.EventType.LOCATION).handler(locationHandler)
|
||||||
|
.end();
|
||||||
|
|
||||||
|
// 接收地理位置消息
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
|
||||||
|
.handler(locationHandler).end();
|
||||||
|
|
||||||
|
// 扫码事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||||
|
.event(WxConsts.EventType.SCAN).handler(scanHandler).end();
|
||||||
|
|
||||||
|
// 默认
|
||||||
|
newRouter.rule().async(false).handler(msgHandler).end();
|
||||||
|
return newRouter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.framework.mp.core;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link WxMpService} 工厂接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface MpServiceFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于微信公众号的账号,初始化对应的 WxMpService 与 WxMpMessageRouter 实例
|
||||||
|
*
|
||||||
|
* @param list 公众号的账号列表
|
||||||
|
*/
|
||||||
|
void init(List<MpAccountDO> list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 appId 对应的 WxMpService 实例
|
||||||
|
*
|
||||||
|
* @param appId 微信公众号 appId
|
||||||
|
* @return WxMpService 实例
|
||||||
|
*/
|
||||||
|
WxMpService getMpService(String appId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 appId 对应的 WxMpMessageRouter 实例
|
||||||
|
*
|
||||||
|
* @param appId 微信公众号 appId
|
||||||
|
* @return WxMpMessageRouter 实例
|
||||||
|
*/
|
||||||
|
WxMpMessageRouter getMpMessageRouter(String appId);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @date 2022/6/20
|
* 属于 mp 模块的 framework 封装
|
||||||
* @author feng-dan
|
*
|
||||||
* @version 1.0
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
package cn.iocoder.yudao.module.mp.framework;
|
package cn.iocoder.yudao.module.mp.framework;
|
@ -1,106 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.mp.framework.weixin;
|
|
||||||
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.mp.handler.*;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import me.chanjar.weixin.common.api.WxConsts;
|
|
||||||
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
|
||||||
import me.chanjar.weixin.mp.api.WxMpService;
|
|
||||||
import me.chanjar.weixin.mp.constant.WxMpEventConstants;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author fengdan
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class WxMpMessageRouterConfiguration {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private WxMpService wxMpService;
|
|
||||||
@Resource
|
|
||||||
private LogHandler logHandler;
|
|
||||||
@Resource
|
|
||||||
private KfSessionHandler kfSessionHandler;
|
|
||||||
@Resource
|
|
||||||
private StoreCheckNotifyHandler storeCheckNotifyHandler;
|
|
||||||
@Resource
|
|
||||||
private MenuHandler menuHandler;
|
|
||||||
@Resource
|
|
||||||
private NullHandler nullHandler;
|
|
||||||
@Resource
|
|
||||||
private SubscribeHandler subscribeHandler;
|
|
||||||
@Resource
|
|
||||||
private UnsubscribeHandler unsubscribeHandler;
|
|
||||||
@Resource
|
|
||||||
private LocationHandler locationHandler;
|
|
||||||
@Resource
|
|
||||||
private ScanHandler scanHandler;
|
|
||||||
@Resource
|
|
||||||
private MsgHandler msgHandler;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public WxMpMessageRouter messageRouter() {
|
|
||||||
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
|
|
||||||
// 记录所有事件的日志 (异步执行)
|
|
||||||
newRouter.rule().handler(logHandler).next();
|
|
||||||
|
|
||||||
// 接收客服会话管理事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
|
|
||||||
.handler(kfSessionHandler).end();
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
|
|
||||||
.handler(kfSessionHandler)
|
|
||||||
.end();
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
|
|
||||||
.handler(kfSessionHandler).end();
|
|
||||||
|
|
||||||
// 门店审核事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxMpEventConstants.POI_CHECK_NOTIFY)
|
|
||||||
.handler(storeCheckNotifyHandler).end();
|
|
||||||
|
|
||||||
// 自定义菜单事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end();
|
|
||||||
|
|
||||||
// 点击菜单连接事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end();
|
|
||||||
|
|
||||||
// 关注事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler)
|
|
||||||
.end();
|
|
||||||
|
|
||||||
// 取消关注事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.EventType.UNSUBSCRIBE)
|
|
||||||
.handler(unsubscribeHandler).end();
|
|
||||||
|
|
||||||
// 上报地理位置事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.EventType.LOCATION).handler(locationHandler)
|
|
||||||
.end();
|
|
||||||
|
|
||||||
// 接收地理位置消息
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
|
|
||||||
.handler(locationHandler).end();
|
|
||||||
|
|
||||||
// 扫码事件
|
|
||||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
|
||||||
.event(WxConsts.EventType.SCAN).handler(scanHandler).end();
|
|
||||||
|
|
||||||
// 默认
|
|
||||||
newRouter.rule().async(false).handler(msgHandler).end();
|
|
||||||
|
|
||||||
return newRouter;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.mq.costomer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
|
||||||
|
import cn.iocoder.yudao.module.mp.mq.message.MpConfigRefreshMessage;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 针对 {@link MpConfigRefreshMessage} 的消费者
|
||||||
|
*
|
||||||
|
* @author lyz
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class MpConfigRefreshConsumer extends AbstractChannelMessageListener<MpConfigRefreshMessage> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MpAccountService wxAccountService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(MpConfigRefreshMessage message) {
|
||||||
|
log.info("[onMessage][收到 MpConfig 刷新消息]");
|
||||||
|
wxAccountService.initLocalCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.mp.mq.costomer;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
|
|
||||||
import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage;
|
|
||||||
import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 针对 {@link WxConfigDataRefreshMessage} 的消费者
|
|
||||||
*
|
|
||||||
* @author lyz
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class WxConfigDataRefreshConsumer extends AbstractChannelMessageListener<WxConfigDataRefreshMessage> {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private WxAccountService wxAccountService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(WxConfigDataRefreshMessage message) {
|
|
||||||
log.info("[onMessage][收到 WxConfigData 刷新消息]");
|
|
||||||
wxAccountService.initLoadWxMpConfigStorages();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -9,11 +9,11 @@ import lombok.EqualsAndHashCode;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class WxConfigDataRefreshMessage extends AbstractChannelMessage {
|
public class MpConfigRefreshMessage extends AbstractChannelMessage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getChannel() {
|
public String getChannel() {
|
||||||
return "wechat-mp.wx-config-data.refresh";
|
return "mp.config-data.refresh";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.mp.mq.producer;
|
package cn.iocoder.yudao.module.mp.mq.producer;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
||||||
import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage;
|
import cn.iocoder.yudao.module.mp.mq.message.MpConfigRefreshMessage;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -10,16 +10,16 @@ import javax.annotation.Resource;
|
|||||||
* 微信配置数据相关消息的 Producer
|
* 微信配置数据相关消息的 Producer
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class WxMpConfigDataProducer {
|
public class MpConfigProducer {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RedisMQTemplate redisMQTemplate;
|
private RedisMQTemplate redisMQTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送 {@link WxConfigDataRefreshMessage} 消息
|
* 发送 {@link MpConfigRefreshMessage} 消息
|
||||||
*/
|
*/
|
||||||
public void sendDictDataRefreshMessage() {
|
public void sendDictDataRefreshMessage() {
|
||||||
WxConfigDataRefreshMessage message = new WxConfigDataRefreshMessage();
|
MpConfigRefreshMessage message = new MpConfigRefreshMessage();
|
||||||
redisMQTemplate.send(message);
|
redisMQTemplate.send(message);
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,12 @@ import javax.validation.Valid;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
public interface WxAccountService {
|
public interface MpAccountService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化缓存
|
||||||
|
*/
|
||||||
|
void initLocalCache();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建公众号账户
|
* 创建公众号账户
|
||||||
@ -64,8 +69,4 @@ public interface WxAccountService {
|
|||||||
*/
|
*/
|
||||||
MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val);
|
MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val);
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化
|
|
||||||
*/
|
|
||||||
void initLoadWxMpConfigStorages();
|
|
||||||
}
|
}
|
@ -0,0 +1,159 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.service.account;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.mysql.account.MpAccountMapper;
|
||||||
|
import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants;
|
||||||
|
import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
|
||||||
|
import cn.iocoder.yudao.module.mp.mq.producer.MpConfigProducer;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号账户 Service 实现类
|
||||||
|
*
|
||||||
|
* @author fengdan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class MpAccountServiceImpl implements MpAccountService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时执行 {@link #schedulePeriodicRefresh()} 的周期
|
||||||
|
* 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
|
||||||
|
*/
|
||||||
|
private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private volatile LocalDateTime maxUpdateTime;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MpAccountMapper mpAccountMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Lazy // 延迟加载,解决循环依赖的问题
|
||||||
|
private MpServiceFactory mpServiceFactory;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MpConfigProducer mpConfigDataProducer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PostConstruct
|
||||||
|
public void initLocalCache() {
|
||||||
|
initLocalCacheIfUpdate(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
|
||||||
|
public void schedulePeriodicRefresh() {
|
||||||
|
initLocalCacheIfUpdate(this.maxUpdateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新本地缓存
|
||||||
|
*
|
||||||
|
* @param maxUpdateTime 最大更新时间
|
||||||
|
* 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
|
||||||
|
* 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
|
||||||
|
*/
|
||||||
|
private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
|
||||||
|
// 注意:忽略自动多租户,因为要全局初始化缓存
|
||||||
|
TenantUtils.executeIgnore(() -> {
|
||||||
|
// 第一步:基于 maxUpdateTime 判断缓存是否刷新。
|
||||||
|
// 如果没有增量的数据变化,则不进行本地缓存的刷新
|
||||||
|
if (maxUpdateTime != null
|
||||||
|
&& mpAccountMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
|
||||||
|
log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<MpAccountDO> accounts = mpAccountMapper.selectList();
|
||||||
|
log.info("[initLocalCacheIfUpdate][缓存公众号账号,数量为:{}]", accounts.size());
|
||||||
|
|
||||||
|
// 第二步:构建缓存。创建或更新支付 Client
|
||||||
|
mpServiceFactory.init(accounts);
|
||||||
|
|
||||||
|
// 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
|
||||||
|
this.maxUpdateTime = CollectionUtils.getMaxValue(accounts, MpAccountDO::getUpdateTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createAccount(MpAccountCreateReqVO createReqVO) {
|
||||||
|
// TODO 芋艿:校验唯一性
|
||||||
|
// 插入
|
||||||
|
MpAccountDO wxAccount = MpAccountConvert.INSTANCE.convert(createReqVO);
|
||||||
|
mpAccountMapper.insert(wxAccount);
|
||||||
|
|
||||||
|
// TODO 芋艿:刷新的方式
|
||||||
|
mpConfigDataProducer.sendDictDataRefreshMessage();
|
||||||
|
// 返回
|
||||||
|
return wxAccount.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAccount(MpAccountUpdateReqVO updateReqVO) {
|
||||||
|
// TODO 芋艿:校验唯一性
|
||||||
|
// 校验存在
|
||||||
|
validateWxAccountExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
MpAccountDO updateObj = MpAccountConvert.INSTANCE.convert(updateReqVO);
|
||||||
|
mpAccountMapper.updateById(updateObj);
|
||||||
|
|
||||||
|
// TODO 芋艿:刷新的方式
|
||||||
|
mpConfigDataProducer.sendDictDataRefreshMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAccount(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateWxAccountExists(id);
|
||||||
|
// 删除
|
||||||
|
mpAccountMapper.deleteById(id);
|
||||||
|
|
||||||
|
// TODO 芋艿:刷新的方式
|
||||||
|
mpConfigDataProducer.sendDictDataRefreshMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateWxAccountExists(Long id) {
|
||||||
|
if (mpAccountMapper.selectById(id) == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.WX_ACCOUNT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MpAccountDO getAccount(Long id) {
|
||||||
|
return mpAccountMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<MpAccountDO> getAccountPage(MpAccountPageReqVO pageReqVO) {
|
||||||
|
return mpAccountMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val) {
|
||||||
|
return mpAccountMapper.selectOne(field, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,157 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.mp.service.account;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert;
|
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
|
||||||
import cn.iocoder.yudao.module.mp.dal.mysql.account.MpAccountMapper;
|
|
||||||
import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants;
|
|
||||||
import cn.iocoder.yudao.module.mp.mq.producer.WxMpConfigDataProducer;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
|
||||||
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
|
|
||||||
import me.chanjar.weixin.mp.api.WxMpService;
|
|
||||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 公众号账户 Service 实现类
|
|
||||||
*
|
|
||||||
* @author fengdan
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
public class WxAccountServiceImpl implements WxAccountService {
|
|
||||||
|
|
||||||
private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private MpAccountMapper wxAccountMapper;
|
|
||||||
@Resource
|
|
||||||
private WxMpConfigDataProducer wxMpConfigDataProducer;
|
|
||||||
@Resource
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
|
||||||
@Resource
|
|
||||||
private WxMpService wxMpService;
|
|
||||||
@Resource
|
|
||||||
private WxMpProperties wxMpProperties;
|
|
||||||
@Resource
|
|
||||||
@Lazy // 注入自己,所以延迟加载
|
|
||||||
private WxAccountService self;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long createAccount(MpAccountCreateReqVO createReqVO) {
|
|
||||||
// TODO 芋艿:校验唯一性
|
|
||||||
// 插入
|
|
||||||
MpAccountDO wxAccount = MpAccountConvert.INSTANCE.convert(createReqVO);
|
|
||||||
wxAccountMapper.insert(wxAccount);
|
|
||||||
|
|
||||||
// TODO 芋艿:刷新的方式
|
|
||||||
wxMpConfigDataProducer.sendDictDataRefreshMessage();
|
|
||||||
// 返回
|
|
||||||
return wxAccount.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateAccount(MpAccountUpdateReqVO updateReqVO) {
|
|
||||||
// TODO 芋艿:校验唯一性
|
|
||||||
// 校验存在
|
|
||||||
validateWxAccountExists(updateReqVO.getId());
|
|
||||||
// 更新
|
|
||||||
MpAccountDO updateObj = MpAccountConvert.INSTANCE.convert(updateReqVO);
|
|
||||||
wxAccountMapper.updateById(updateObj);
|
|
||||||
|
|
||||||
// TODO 芋艿:刷新的方式
|
|
||||||
wxMpConfigDataProducer.sendDictDataRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteAccount(Long id) {
|
|
||||||
// 校验存在
|
|
||||||
validateWxAccountExists(id);
|
|
||||||
// 删除
|
|
||||||
wxAccountMapper.deleteById(id);
|
|
||||||
|
|
||||||
// TODO 芋艿:刷新的方式
|
|
||||||
wxMpConfigDataProducer.sendDictDataRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateWxAccountExists(Long id) {
|
|
||||||
if (wxAccountMapper.selectById(id) == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.WX_ACCOUNT_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MpAccountDO getAccount(Long id) {
|
|
||||||
return wxAccountMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<MpAccountDO> getAccountPage(MpAccountPageReqVO pageReqVO) {
|
|
||||||
return wxAccountMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val) {
|
|
||||||
return wxAccountMapper.selectOne(field, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
@TenantIgnore
|
|
||||||
@Override
|
|
||||||
public void initLoadWxMpConfigStorages() {
|
|
||||||
// TODO 芋艿:刷新的方式
|
|
||||||
List<MpAccountDO> wxAccountList = this.wxAccountMapper.selectList();
|
|
||||||
if (CollectionUtils.isEmpty(wxAccountList)) {
|
|
||||||
log.info("未读取到公众号配置,请在管理后台添加");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log.info("加载到{}条公众号配置", wxAccountList.size());
|
|
||||||
wxAccountList.forEach(account -> addAccountToRuntime(account, new RedisTemplateWxRedisOps(stringRedisTemplate)));
|
|
||||||
log.info("公众号配置加载完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加账号到当前程序,如首次添加需初始化configStorageMap
|
|
||||||
*
|
|
||||||
* @param account 公众号
|
|
||||||
*/
|
|
||||||
private synchronized void addAccountToRuntime(MpAccountDO account, RedisTemplateWxRedisOps redisOps) {
|
|
||||||
String appId = account.getAppId();
|
|
||||||
WxMpConfigStorage wxMpRedisConfig = account.toWxMpConfigStorage(redisOps, wxMpProperties);
|
|
||||||
try {
|
|
||||||
wxMpService.addConfigStorage(appId, wxMpRedisConfig);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
log.info("需初始化configStorageMap...");
|
|
||||||
Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4);
|
|
||||||
configStorages.put(appId, wxMpRedisConfig);
|
|
||||||
wxMpService.setMultiConfigStorages(configStorages, appId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
|
|
||||||
public void schedulePeriodicRefresh() {
|
|
||||||
self.initLoadWxMpConfigStorages();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.fansmsgres;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||||
@ -9,13 +9,15 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击菜单连接的事件处理器
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class NullHandler implements WxMpMessageHandler {
|
public class NullHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||||
Map<String, Object> context, WxMpService wxMpService,
|
WxMpService wxMpService, WxSessionManager sessionManager) {
|
||||||
WxSessionManager sessionManager) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.http.HtmlUtil;
|
import cn.hutool.http.HtmlUtil;
|
||||||
@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
|||||||
import cn.iocoder.yudao.module.mp.builder.TextBuilder;
|
import cn.iocoder.yudao.module.mp.builder.TextBuilder;
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.fansmsg.vo.WxFansMsgCreateReqVO;
|
import cn.iocoder.yudao.module.mp.controller.admin.fansmsg.vo.WxFansMsgCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
import cn.iocoder.yudao.module.mp.service.fansmsg.WxFansMsgService;
|
import cn.iocoder.yudao.module.mp.service.fansmsg.WxFansMsgService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.chanjar.weixin.common.api.WxConsts;
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
@ -21,6 +21,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
|||||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -28,11 +29,18 @@ import java.io.File;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认所有消息的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO 芋艿:待实现
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class MsgHandler implements WxMpMessageHandler {
|
public class DefaultMessageHandler implements WxMpMessageHandler {
|
||||||
@Autowired
|
|
||||||
private WxAccountService wxAccountService;
|
@Resource
|
||||||
|
@Lazy // 延迟加载,解决循环依赖的问题
|
||||||
|
private MpAccountService mpAccountService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WxFansMsgService wxFansMsgService;
|
private WxFansMsgService wxFansMsgService;
|
||||||
@ -55,7 +63,7 @@ public class MsgHandler implements WxMpMessageHandler {
|
|||||||
WxMpUser wxmpUser = weixinService.getUserService()
|
WxMpUser wxmpUser = weixinService.getUserService()
|
||||||
.userInfo(wxMessage.getFromUser(), null);
|
.userInfo(wxMessage.getFromUser(), null);
|
||||||
if (wxmpUser != null) {
|
if (wxmpUser != null) {
|
||||||
MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
||||||
if (wxAccount != null) {
|
if (wxAccount != null) {
|
||||||
|
|
||||||
if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) {
|
if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) {
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||||
@ -9,13 +9,17 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收客服会话管理的事件处理器
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class KfSessionHandler implements WxMpMessageHandler {
|
public class KfSessionHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||||
Map<String, Object> context, WxMpService wxMpService,
|
WxMpService wxMpService, WxSessionManager sessionManager) {
|
||||||
WxSessionManager sessionManager) {
|
|
||||||
// TODO 对会话做处理
|
// TODO 对会话做处理
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.mp.builder.TextBuilder;
|
import cn.iocoder.yudao.module.mp.builder.TextBuilder;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -13,14 +13,18 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上报地理位置的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO @芋艿:需要实现一下~
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LocationHandler implements WxMpMessageHandler {
|
public class LocationHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||||
Map<String, Object> context, WxMpService wxMpService,
|
WxMpService wxMpService, WxSessionManager sessionManager) {
|
||||||
WxSessionManager sessionManager) {
|
|
||||||
if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) {
|
if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) {
|
||||||
//TODO 接收处理用户发送的地理位置消息
|
//TODO 接收处理用户发送的地理位置消息
|
||||||
try {
|
try {
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -11,13 +11,18 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存微信消息的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO 芋艿:实现一下
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LogHandler implements WxMpMessageHandler {
|
public class LogHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
|
||||||
Map<String, Object> context, WxMpService wxMpService,
|
WxMpService wxMpService, WxSessionManager sessionManager) {
|
||||||
WxSessionManager sessionManager) {
|
|
||||||
log.info("接收到请求消息,内容:{}", JsonUtils.toJsonString(wxMessage));
|
log.info("接收到请求消息,内容:{}", JsonUtils.toJsonString(wxMessage));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||||
@ -11,6 +11,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
|
import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义菜单的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO 芋艿:待实现
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class MenuHandler implements WxMpMessageHandler {
|
public class MenuHandler implements WxMpMessageHandler {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.error.WxErrorException;
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
@ -10,6 +10,9 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫码的事件处理器
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ScanHandler implements WxMpMessageHandler {
|
public class ScanHandler implements WxMpMessageHandler {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||||
@ -10,8 +10,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 门店审核事件处理
|
* 门店审核事件的事件处理器
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class StoreCheckNotifyHandler implements WxMpMessageHandler {
|
public class StoreCheckNotifyHandler implements WxMpMessageHandler {
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
|||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate.WxTextTemplateDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate.WxTextTemplateDO;
|
||||||
import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService;
|
import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService;
|
||||||
import cn.iocoder.yudao.module.mp.service.accountfanstag.WxAccountFansTagService;
|
import cn.iocoder.yudao.module.mp.service.accountfanstag.WxAccountFansTagService;
|
||||||
import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService;
|
import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService;
|
||||||
@ -23,11 +23,18 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
|||||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关注的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO 芋艿:待实现
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SubscribeHandler implements WxMpMessageHandler {
|
public class SubscribeHandler implements WxMpMessageHandler {
|
||||||
@ -35,8 +42,9 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WxTextTemplateService wxTextTemplateService;
|
private WxTextTemplateService wxTextTemplateService;
|
||||||
|
|
||||||
@Autowired
|
@Resource
|
||||||
private WxAccountService wxAccountService;
|
@Lazy // 延迟加载,解决循环依赖的问题
|
||||||
|
private MpAccountService mpAccountService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WxSubscribeTextService wxSubscribeTextService;
|
private WxSubscribeTextService wxSubscribeTextService;
|
||||||
@ -60,7 +68,7 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
|||||||
.userInfo(wxMessage.getFromUser(), null);
|
.userInfo(wxMessage.getFromUser(), null);
|
||||||
if (wxmpUser != null) {
|
if (wxmpUser != null) {
|
||||||
// 可以添加关注用户到本地数据库
|
// 可以添加关注用户到本地数据库
|
||||||
MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
||||||
if (wxAccount != null) {
|
if (wxAccount != null) {
|
||||||
WxAccountFansDO wxAccountFans = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, wxmpUser.getOpenId());
|
WxAccountFansDO wxAccountFans = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, wxmpUser.getOpenId());
|
||||||
if (wxAccountFans == null) {//insert
|
if (wxAccountFans == null) {//insert
|
||||||
@ -128,7 +136,7 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String content = "感谢关注!";//默认
|
String content = "感谢关注!";//默认
|
||||||
MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
||||||
if (wxAccount != null) {
|
if (wxAccount != null) {
|
||||||
WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.findBy(WxSubscribeTextDO::getWxAccountId, String.valueOf(wxAccount.getId()));
|
WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.findBy(WxSubscribeTextDO::getWxAccountId, String.valueOf(wxAccount.getId()));
|
||||||
if (wxSubscribeText != null) {
|
if (wxSubscribeText != null) {
|
@ -1,9 +1,9 @@
|
|||||||
package cn.iocoder.yudao.module.mp.handler;
|
package cn.iocoder.yudao.module.mp.service.handler;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO;
|
import cn.iocoder.yudao.module.mp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO;
|
||||||
import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService;
|
import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
@ -12,16 +12,24 @@ import me.chanjar.weixin.mp.api.WxMpService;
|
|||||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消关注的事件处理器
|
||||||
|
*
|
||||||
|
* // TODO 芋艿:待实现
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class UnsubscribeHandler implements WxMpMessageHandler {
|
public class UnsubscribeHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
@Autowired
|
@Resource
|
||||||
private WxAccountService wxAccountService;
|
@Lazy // 延迟加载,解决循环依赖的问题
|
||||||
|
private MpAccountService mpAccountService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WxAccountFansService wxAccountFansService;
|
private WxAccountFansService wxAccountFansService;
|
||||||
@ -34,7 +42,7 @@ public class UnsubscribeHandler implements WxMpMessageHandler {
|
|||||||
log.info("取消关注用户 OPENID: " + openId);
|
log.info("取消关注用户 OPENID: " + openId);
|
||||||
// TODO 可以更新本地数据库为取消关注状态
|
// TODO 可以更新本地数据库为取消关注状态
|
||||||
|
|
||||||
MpAccountDO wxAccountDO = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
MpAccountDO wxAccountDO = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());
|
||||||
if (wxAccountDO != null) {
|
if (wxAccountDO != null) {
|
||||||
WxAccountFansDO wxAccountFansDO = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, openId);
|
WxAccountFansDO wxAccountFansDO = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, openId);
|
||||||
if (wxAccountFansDO != null) {
|
if (wxAccountFansDO != null) {
|
Loading…
Reference in New Issue
Block a user