Commit 275a1b10f671cedbb72d0170f3a68a1ed4efa9dd
1 parent
627cb395
mp:增加 MpServiceFactory 管理创建的 MpService~
Showing
23 changed files
with
431 additions
and
249 deletions
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/MpAccountController.java
| @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.*; | 5 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.*; |
| 6 | import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert; | 6 | import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert; |
| 7 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | 7 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; |
| 8 | -import cn.iocoder.yudao.module.mp.service.account.WxAccountService; | 8 | +import cn.iocoder.yudao.module.mp.service.account.MpAccountService; |
| 9 | import io.swagger.annotations.Api; | 9 | import io.swagger.annotations.Api; |
| 10 | import io.swagger.annotations.ApiImplicitParam; | 10 | import io.swagger.annotations.ApiImplicitParam; |
| 11 | import io.swagger.annotations.ApiOperation; | 11 | import io.swagger.annotations.ApiOperation; |
| @@ -25,7 +25,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | @@ -25,7 +25,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 25 | public class MpAccountController { | 25 | public class MpAccountController { |
| 26 | 26 | ||
| 27 | @Resource | 27 | @Resource |
| 28 | - private WxAccountService wxAccountService; | 28 | + private MpAccountService wxAccountService; |
| 29 | 29 | ||
| 30 | @PostMapping("/create") | 30 | @PostMapping("/create") |
| 31 | @ApiOperation("创建公众号账户") | 31 | @ApiOperation("创建公众号账户") |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/account/MpAccountDO.java
| @@ -63,13 +63,4 @@ public class MpAccountDO extends BaseDO { | @@ -63,13 +63,4 @@ public class MpAccountDO extends BaseDO { | ||
| 63 | */ | 63 | */ |
| 64 | private String remark; | 64 | private String remark; |
| 65 | 65 | ||
| 66 | - // TODO 芋艿:需要迁移走 | ||
| 67 | - public WxMpConfigStorage toWxMpConfigStorage(RedisTemplateWxRedisOps redisTemplateWxRedisOps, WxMpProperties wxMpProperties) { | ||
| 68 | - WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisTemplateWxRedisOps, wxMpProperties.getConfigStorage().getKeyPrefix()); | ||
| 69 | - wxMpRedisConfig.setAppId(appId); | ||
| 70 | - wxMpRedisConfig.setSecret(appSecret); | ||
| 71 | - wxMpRedisConfig.setToken(token); | ||
| 72 | - wxMpRedisConfig.setAesKey(aesKey); | ||
| 73 | - return wxMpRedisConfig; | ||
| 74 | - } | ||
| 75 | } | 66 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/account/MpAccountMapper.java
| @@ -6,6 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | @@ -6,6 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 6 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO; | 6 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO; |
| 7 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | 7 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; |
| 8 | import org.apache.ibatis.annotations.Mapper; | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | +import org.apache.ibatis.annotations.Select; | ||
| 10 | + | ||
| 11 | +import java.time.LocalDateTime; | ||
| 9 | 12 | ||
| 10 | @Mapper | 13 | @Mapper |
| 11 | public interface MpAccountMapper extends BaseMapperX<MpAccountDO> { | 14 | public interface MpAccountMapper extends BaseMapperX<MpAccountDO> { |
| @@ -18,4 +21,7 @@ public interface MpAccountMapper extends BaseMapperX<MpAccountDO> { | @@ -18,4 +21,7 @@ public interface MpAccountMapper extends BaseMapperX<MpAccountDO> { | ||
| 18 | .orderByDesc(MpAccountDO::getId)); | 21 | .orderByDesc(MpAccountDO::getId)); |
| 19 | } | 22 | } |
| 20 | 23 | ||
| 24 | + @Select("SELECT COUNT(*) FROM mp_account WHERE update_time > #{maxUpdateTime}") | ||
| 25 | + Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime); | ||
| 26 | + | ||
| 21 | } | 27 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/mp/config/MpConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mp.framework.mp.config; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mp.framework.mp.core.DefaultMpServiceFactory; | ||
| 4 | +import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; | ||
| 5 | +import cn.iocoder.yudao.module.mp.service.fansmsgres.NullHandler; | ||
| 6 | +import cn.iocoder.yudao.module.mp.service.handler.*; | ||
| 7 | +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; | ||
| 8 | +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; | ||
| 9 | +import org.springframework.context.annotation.Bean; | ||
| 10 | +import org.springframework.context.annotation.Configuration; | ||
| 11 | +import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * 微信公众号的配置类 | ||
| 15 | + * | ||
| 16 | + * @author 芋道源码 | ||
| 17 | + */ | ||
| 18 | +@Configuration | ||
| 19 | +public class MpConfiguration { | ||
| 20 | + | ||
| 21 | + @Bean | ||
| 22 | + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") | ||
| 23 | + public RedisTemplateWxRedisOps redisTemplateWxRedisOps(StringRedisTemplate stringRedisTemplate) { | ||
| 24 | + return new RedisTemplateWxRedisOps(stringRedisTemplate); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @Bean | ||
| 28 | + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") | ||
| 29 | + public MpServiceFactory mpServiceFactory(RedisTemplateWxRedisOps redisTemplateWxRedisOps, | ||
| 30 | + WxMpProperties wxMpProperties, | ||
| 31 | + LogHandler logHandler, | ||
| 32 | + KfSessionHandler kfSessionHandler, | ||
| 33 | + StoreCheckNotifyHandler storeCheckNotifyHandler, | ||
| 34 | + MenuHandler menuHandler, | ||
| 35 | + NullHandler nullHandler, | ||
| 36 | + SubscribeHandler subscribeHandler, | ||
| 37 | + UnsubscribeHandler unsubscribeHandler, | ||
| 38 | + LocationHandler locationHandler, | ||
| 39 | + ScanHandler scanHandler, | ||
| 40 | + DefaultMessageHandler msgHandler) { | ||
| 41 | + return new DefaultMpServiceFactory(redisTemplateWxRedisOps, wxMpProperties, | ||
| 42 | + logHandler, kfSessionHandler, storeCheckNotifyHandler, menuHandler, | ||
| 43 | + nullHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler, msgHandler); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | +} |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/mp/core/DefaultMpServiceFactory.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mp.framework.mp.core; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||
| 4 | +import cn.iocoder.yudao.module.mp.service.fansmsgres.NullHandler; | ||
| 5 | +import cn.iocoder.yudao.module.mp.service.handler.*; | ||
| 6 | +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; | ||
| 7 | +import com.google.common.collect.Maps; | ||
| 8 | +import lombok.RequiredArgsConstructor; | ||
| 9 | +import lombok.extern.slf4j.Slf4j; | ||
| 10 | +import me.chanjar.weixin.common.api.WxConsts; | ||
| 11 | +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; | ||
| 12 | +import me.chanjar.weixin.mp.api.WxMpMessageRouter; | ||
| 13 | +import me.chanjar.weixin.mp.api.WxMpService; | ||
| 14 | +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | ||
| 15 | +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; | ||
| 16 | +import me.chanjar.weixin.mp.constant.WxMpEventConstants; | ||
| 17 | + | ||
| 18 | +import java.util.List; | ||
| 19 | +import java.util.Map; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * 默认的 {@link MpServiceFactory} 实现类 | ||
| 23 | + * | ||
| 24 | + * @author 芋道源码 | ||
| 25 | + */ | ||
| 26 | +@Slf4j | ||
| 27 | +@RequiredArgsConstructor | ||
| 28 | +public class DefaultMpServiceFactory implements MpServiceFactory { | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 微信 appId 与 WxMpService 的映射 | ||
| 32 | + */ | ||
| 33 | + private volatile Map<String, WxMpService> mpServices; | ||
| 34 | + /** | ||
| 35 | + * 微信 appId 与 WxMpMessageRouter 的映射 | ||
| 36 | + */ | ||
| 37 | + private volatile Map<String, WxMpMessageRouter> mpMessageRouters; | ||
| 38 | + | ||
| 39 | + private final RedisTemplateWxRedisOps redisTemplateWxRedisOps; | ||
| 40 | + private final WxMpProperties mpProperties; | ||
| 41 | + | ||
| 42 | + // ========== 各种 Handler ========== | ||
| 43 | + | ||
| 44 | + private final LogHandler logHandler; | ||
| 45 | + private final KfSessionHandler kfSessionHandler; | ||
| 46 | + private final StoreCheckNotifyHandler storeCheckNotifyHandler; | ||
| 47 | + private final MenuHandler menuHandler; | ||
| 48 | + private final NullHandler nullHandler; | ||
| 49 | + private final SubscribeHandler subscribeHandler; | ||
| 50 | + private final UnsubscribeHandler unsubscribeHandler; | ||
| 51 | + private final LocationHandler locationHandler; | ||
| 52 | + private final ScanHandler scanHandler; | ||
| 53 | + private final DefaultMessageHandler msgHandler; | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public void init(List<MpAccountDO> list) { | ||
| 57 | + Map<String, WxMpService> mpServices = Maps.newHashMap(); | ||
| 58 | + Map<String, WxMpMessageRouter> mpMessageRouters = Maps.newHashMap(); | ||
| 59 | + // 处理 list | ||
| 60 | + list.forEach(account -> { | ||
| 61 | + // 构建 WxMpService 对象 | ||
| 62 | + WxMpService mpService = buildMpService(account); | ||
| 63 | + mpServices.put(account.getAppId(), mpService); | ||
| 64 | + // 构建 WxMpMessageRouter 对象 | ||
| 65 | + WxMpMessageRouter mpMessageRouter = buildMpMessageRouter(mpService); | ||
| 66 | + mpMessageRouters.put(account.getAppId(), mpMessageRouter); | ||
| 67 | + }); | ||
| 68 | + | ||
| 69 | + // 设置到缓存 | ||
| 70 | + this.mpServices = mpServices; | ||
| 71 | + this.mpMessageRouters = mpMessageRouters; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + @Override | ||
| 75 | + public WxMpService getMpService(String appId) { | ||
| 76 | + return mpServices.get(appId); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public WxMpMessageRouter getMpMessageRouter(String appId) { | ||
| 81 | + return mpMessageRouters.get(appId); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + private WxMpService buildMpService(MpAccountDO account) { | ||
| 85 | + // 第一步,创建 WxMpRedisConfigImpl 对象 | ||
| 86 | + // TODO 芋艿:需要确认下,redis key 的存储结构 | ||
| 87 | + WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( | ||
| 88 | + redisTemplateWxRedisOps, mpProperties.getConfigStorage().getKeyPrefix()); | ||
| 89 | + configStorage.setAppId(account.getAppId()); | ||
| 90 | + configStorage.setSecret(account.getAppSecret()); | ||
| 91 | + configStorage.setToken(account.getToken()); | ||
| 92 | + configStorage.setAesKey(account.getAesKey()); | ||
| 93 | + | ||
| 94 | + // 第二步,创建 WxMpService 对象 | ||
| 95 | + WxMpService service = new WxMpServiceImpl(); | ||
| 96 | + service.setWxMpConfigStorage(configStorage); | ||
| 97 | + return null; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + private WxMpMessageRouter buildMpMessageRouter(WxMpService mpService) { | ||
| 101 | + final WxMpMessageRouter newRouter = new WxMpMessageRouter(mpService); | ||
| 102 | + // 记录所有事件的日志(异步执行) | ||
| 103 | + newRouter.rule().handler(logHandler).next(); | ||
| 104 | + | ||
| 105 | + // 接收客服会话管理事件 | ||
| 106 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 107 | + .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION) | ||
| 108 | + .handler(kfSessionHandler).end(); | ||
| 109 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 110 | + .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION) | ||
| 111 | + .handler(kfSessionHandler) | ||
| 112 | + .end(); | ||
| 113 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 114 | + .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION) | ||
| 115 | + .handler(kfSessionHandler).end(); | ||
| 116 | + | ||
| 117 | + // 门店审核事件 | ||
| 118 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 119 | + .event(WxMpEventConstants.POI_CHECK_NOTIFY) | ||
| 120 | + .handler(storeCheckNotifyHandler).end(); | ||
| 121 | + | ||
| 122 | + // 自定义菜单事件 | ||
| 123 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 124 | + .event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end(); | ||
| 125 | + | ||
| 126 | + // 点击菜单连接事件 | ||
| 127 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 128 | + .event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end(); | ||
| 129 | + | ||
| 130 | + // 关注事件 | ||
| 131 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 132 | + .event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler) | ||
| 133 | + .end(); | ||
| 134 | + | ||
| 135 | + // 取消关注事件 | ||
| 136 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 137 | + .event(WxConsts.EventType.UNSUBSCRIBE) | ||
| 138 | + .handler(unsubscribeHandler).end(); | ||
| 139 | + | ||
| 140 | + // 上报地理位置事件 | ||
| 141 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 142 | + .event(WxConsts.EventType.LOCATION).handler(locationHandler) | ||
| 143 | + .end(); | ||
| 144 | + | ||
| 145 | + // 接收地理位置消息 | ||
| 146 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION) | ||
| 147 | + .handler(locationHandler).end(); | ||
| 148 | + | ||
| 149 | + // 扫码事件 | ||
| 150 | + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 151 | + .event(WxConsts.EventType.SCAN).handler(scanHandler).end(); | ||
| 152 | + | ||
| 153 | + // 默认 | ||
| 154 | + newRouter.rule().async(false).handler(msgHandler).end(); | ||
| 155 | + return newRouter; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | +} |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/mp/core/MpServiceFactory.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mp.framework.mp.core; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||
| 4 | +import me.chanjar.weixin.mp.api.WxMpMessageRouter; | ||
| 5 | +import me.chanjar.weixin.mp.api.WxMpService; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * {@link WxMpService} 工厂接口 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +public interface MpServiceFactory { | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 基于微信公众号的账号,初始化对应的 WxMpService 与 WxMpMessageRouter 实例 | ||
| 18 | + * | ||
| 19 | + * @param list 公众号的账号列表 | ||
| 20 | + */ | ||
| 21 | + void init(List<MpAccountDO> list); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 获得 appId 对应的 WxMpService 实例 | ||
| 25 | + * | ||
| 26 | + * @param appId 微信公众号 appId | ||
| 27 | + * @return WxMpService 实例 | ||
| 28 | + */ | ||
| 29 | + WxMpService getMpService(String appId); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 获得 appId 对应的 WxMpMessageRouter 实例 | ||
| 33 | + * | ||
| 34 | + * @param appId 微信公众号 appId | ||
| 35 | + * @return WxMpMessageRouter 实例 | ||
| 36 | + */ | ||
| 37 | + WxMpMessageRouter getMpMessageRouter(String appId); | ||
| 38 | +} |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/package-info.java
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/weixin/WxMpMessageRouterConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.module.mp.framework.weixin; | ||
| 2 | - | ||
| 3 | - | ||
| 4 | -import cn.iocoder.yudao.module.mp.handler.*; | ||
| 5 | -import lombok.RequiredArgsConstructor; | ||
| 6 | -import lombok.extern.slf4j.Slf4j; | ||
| 7 | -import me.chanjar.weixin.common.api.WxConsts; | ||
| 8 | -import me.chanjar.weixin.mp.api.WxMpMessageRouter; | ||
| 9 | -import me.chanjar.weixin.mp.api.WxMpService; | ||
| 10 | -import me.chanjar.weixin.mp.constant.WxMpEventConstants; | ||
| 11 | -import org.springframework.context.annotation.Bean; | ||
| 12 | -import org.springframework.stereotype.Component; | ||
| 13 | - | ||
| 14 | -import javax.annotation.Resource; | ||
| 15 | - | ||
| 16 | -/** | ||
| 17 | - * @author fengdan | ||
| 18 | - */ | ||
| 19 | -@Slf4j | ||
| 20 | -@Component | ||
| 21 | -@RequiredArgsConstructor | ||
| 22 | -public class WxMpMessageRouterConfiguration { | ||
| 23 | - | ||
| 24 | - @Resource | ||
| 25 | - private WxMpService wxMpService; | ||
| 26 | - @Resource | ||
| 27 | - private LogHandler logHandler; | ||
| 28 | - @Resource | ||
| 29 | - private KfSessionHandler kfSessionHandler; | ||
| 30 | - @Resource | ||
| 31 | - private StoreCheckNotifyHandler storeCheckNotifyHandler; | ||
| 32 | - @Resource | ||
| 33 | - private MenuHandler menuHandler; | ||
| 34 | - @Resource | ||
| 35 | - private NullHandler nullHandler; | ||
| 36 | - @Resource | ||
| 37 | - private SubscribeHandler subscribeHandler; | ||
| 38 | - @Resource | ||
| 39 | - private UnsubscribeHandler unsubscribeHandler; | ||
| 40 | - @Resource | ||
| 41 | - private LocationHandler locationHandler; | ||
| 42 | - @Resource | ||
| 43 | - private ScanHandler scanHandler; | ||
| 44 | - @Resource | ||
| 45 | - private MsgHandler msgHandler; | ||
| 46 | - | ||
| 47 | - @Bean | ||
| 48 | - public WxMpMessageRouter messageRouter() { | ||
| 49 | - final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService); | ||
| 50 | - // 记录所有事件的日志 (异步执行) | ||
| 51 | - newRouter.rule().handler(logHandler).next(); | ||
| 52 | - | ||
| 53 | - // 接收客服会话管理事件 | ||
| 54 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 55 | - .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION) | ||
| 56 | - .handler(kfSessionHandler).end(); | ||
| 57 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 58 | - .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION) | ||
| 59 | - .handler(kfSessionHandler) | ||
| 60 | - .end(); | ||
| 61 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 62 | - .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION) | ||
| 63 | - .handler(kfSessionHandler).end(); | ||
| 64 | - | ||
| 65 | - // 门店审核事件 | ||
| 66 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 67 | - .event(WxMpEventConstants.POI_CHECK_NOTIFY) | ||
| 68 | - .handler(storeCheckNotifyHandler).end(); | ||
| 69 | - | ||
| 70 | - // 自定义菜单事件 | ||
| 71 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 72 | - .event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end(); | ||
| 73 | - | ||
| 74 | - // 点击菜单连接事件 | ||
| 75 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 76 | - .event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end(); | ||
| 77 | - | ||
| 78 | - // 关注事件 | ||
| 79 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 80 | - .event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler) | ||
| 81 | - .end(); | ||
| 82 | - | ||
| 83 | - // 取消关注事件 | ||
| 84 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 85 | - .event(WxConsts.EventType.UNSUBSCRIBE) | ||
| 86 | - .handler(unsubscribeHandler).end(); | ||
| 87 | - | ||
| 88 | - // 上报地理位置事件 | ||
| 89 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 90 | - .event(WxConsts.EventType.LOCATION).handler(locationHandler) | ||
| 91 | - .end(); | ||
| 92 | - | ||
| 93 | - // 接收地理位置消息 | ||
| 94 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION) | ||
| 95 | - .handler(locationHandler).end(); | ||
| 96 | - | ||
| 97 | - // 扫码事件 | ||
| 98 | - newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) | ||
| 99 | - .event(WxConsts.EventType.SCAN).handler(scanHandler).end(); | ||
| 100 | - | ||
| 101 | - // 默认 | ||
| 102 | - newRouter.rule().async(false).handler(msgHandler).end(); | ||
| 103 | - | ||
| 104 | - return newRouter; | ||
| 105 | - } | ||
| 106 | -} |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/costomer/WxConfigDataRefreshConsumer.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/costomer/MpConfigRefreshConsumer.java
| 1 | package cn.iocoder.yudao.module.mp.mq.costomer; | 1 | package cn.iocoder.yudao.module.mp.mq.costomer; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage; | ||
| 5 | -import cn.iocoder.yudao.module.mp.service.account.WxAccountService; | 4 | +import cn.iocoder.yudao.module.mp.mq.message.MpConfigRefreshMessage; |
| 5 | +import cn.iocoder.yudao.module.mp.service.account.MpAccountService; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
| 8 | 8 | ||
| 9 | import javax.annotation.Resource; | 9 | import javax.annotation.Resource; |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | - * 针对 {@link WxConfigDataRefreshMessage} 的消费者 | 12 | + * 针对 {@link MpConfigRefreshMessage} 的消费者 |
| 13 | * | 13 | * |
| 14 | * @author lyz | 14 | * @author lyz |
| 15 | */ | 15 | */ |
| 16 | @Component | 16 | @Component |
| 17 | @Slf4j | 17 | @Slf4j |
| 18 | -public class WxConfigDataRefreshConsumer extends AbstractChannelMessageListener<WxConfigDataRefreshMessage> { | 18 | +public class MpConfigRefreshConsumer extends AbstractChannelMessageListener<MpConfigRefreshMessage> { |
| 19 | 19 | ||
| 20 | @Resource | 20 | @Resource |
| 21 | - private WxAccountService wxAccountService; | 21 | + private MpAccountService wxAccountService; |
| 22 | 22 | ||
| 23 | @Override | 23 | @Override |
| 24 | - public void onMessage(WxConfigDataRefreshMessage message) { | ||
| 25 | - log.info("[onMessage][收到 WxConfigData 刷新消息]"); | ||
| 26 | - wxAccountService.initLoadWxMpConfigStorages(); | 24 | + public void onMessage(MpConfigRefreshMessage message) { |
| 25 | + log.info("[onMessage][收到 MpConfig 刷新消息]"); | ||
| 26 | + wxAccountService.initLocalCache(); | ||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | } | 29 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/message/WxConfigDataRefreshMessage.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/message/MpConfigRefreshMessage.java
| @@ -9,11 +9,11 @@ import lombok.EqualsAndHashCode; | @@ -9,11 +9,11 @@ import lombok.EqualsAndHashCode; | ||
| 9 | */ | 9 | */ |
| 10 | @Data | 10 | @Data |
| 11 | @EqualsAndHashCode(callSuper = true) | 11 | @EqualsAndHashCode(callSuper = true) |
| 12 | -public class WxConfigDataRefreshMessage extends AbstractChannelMessage { | 12 | +public class MpConfigRefreshMessage extends AbstractChannelMessage { |
| 13 | 13 | ||
| 14 | @Override | 14 | @Override |
| 15 | public String getChannel() { | 15 | public String getChannel() { |
| 16 | - return "wechat-mp.wx-config-data.refresh"; | 16 | + return "mp.config-data.refresh"; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | } | 19 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/producer/WxMpConfigDataProducer.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/producer/MpConfigProducer.java
| 1 | package cn.iocoder.yudao.module.mp.mq.producer; | 1 | package cn.iocoder.yudao.module.mp.mq.producer; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | 3 | import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; |
| 4 | -import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage; | 4 | +import cn.iocoder.yudao.module.mp.mq.message.MpConfigRefreshMessage; |
| 5 | import org.springframework.stereotype.Component; | 5 | import org.springframework.stereotype.Component; |
| 6 | 6 | ||
| 7 | import javax.annotation.Resource; | 7 | import javax.annotation.Resource; |
| @@ -10,16 +10,16 @@ import javax.annotation.Resource; | @@ -10,16 +10,16 @@ import javax.annotation.Resource; | ||
| 10 | * 微信配置数据相关消息的 Producer | 10 | * 微信配置数据相关消息的 Producer |
| 11 | */ | 11 | */ |
| 12 | @Component | 12 | @Component |
| 13 | -public class WxMpConfigDataProducer { | 13 | +public class MpConfigProducer { |
| 14 | 14 | ||
| 15 | @Resource | 15 | @Resource |
| 16 | private RedisMQTemplate redisMQTemplate; | 16 | private RedisMQTemplate redisMQTemplate; |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | - * 发送 {@link WxConfigDataRefreshMessage} 消息 | 19 | + * 发送 {@link MpConfigRefreshMessage} 消息 |
| 20 | */ | 20 | */ |
| 21 | public void sendDictDataRefreshMessage() { | 21 | public void sendDictDataRefreshMessage() { |
| 22 | - WxConfigDataRefreshMessage message = new WxConfigDataRefreshMessage(); | 22 | + MpConfigRefreshMessage message = new MpConfigRefreshMessage(); |
| 23 | redisMQTemplate.send(message); | 23 | redisMQTemplate.send(message); |
| 24 | } | 24 | } |
| 25 | 25 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountService.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/MpAccountService.java
| @@ -14,7 +14,12 @@ import javax.validation.Valid; | @@ -14,7 +14,12 @@ import javax.validation.Valid; | ||
| 14 | * | 14 | * |
| 15 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 16 | */ | 16 | */ |
| 17 | -public interface WxAccountService { | 17 | +public interface MpAccountService { |
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 初始化缓存 | ||
| 21 | + */ | ||
| 22 | + void initLocalCache(); | ||
| 18 | 23 | ||
| 19 | /** | 24 | /** |
| 20 | * 创建公众号账户 | 25 | * 创建公众号账户 |
| @@ -64,8 +69,4 @@ public interface WxAccountService { | @@ -64,8 +69,4 @@ public interface WxAccountService { | ||
| 64 | */ | 69 | */ |
| 65 | MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val); | 70 | MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val); |
| 66 | 71 | ||
| 67 | - /** | ||
| 68 | - * 初始化 | ||
| 69 | - */ | ||
| 70 | - void initLoadWxMpConfigStorages(); | ||
| 71 | } | 72 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountServiceImpl.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/MpAccountServiceImpl.java
| @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.mp.service.account; | @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.mp.service.account; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | 3 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | ||
| 6 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountCreateReqVO; | 7 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountCreateReqVO; |
| 7 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO; | 8 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountPageReqVO; |
| 8 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountUpdateReqVO; | 9 | import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountUpdateReqVO; |
| @@ -10,25 +11,20 @@ import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert; | @@ -10,25 +11,20 @@ import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert; | ||
| 10 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | 11 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; |
| 11 | import cn.iocoder.yudao.module.mp.dal.mysql.account.MpAccountMapper; | 12 | import cn.iocoder.yudao.module.mp.dal.mysql.account.MpAccountMapper; |
| 12 | import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants; | 13 | import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants; |
| 13 | -import cn.iocoder.yudao.module.mp.mq.producer.WxMpConfigDataProducer; | 14 | +import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; |
| 15 | +import cn.iocoder.yudao.module.mp.mq.producer.MpConfigProducer; | ||
| 14 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; | 16 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; |
| 15 | -import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; | 17 | +import lombok.Getter; |
| 16 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
| 17 | -import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; | ||
| 18 | -import me.chanjar.weixin.mp.api.WxMpService; | ||
| 19 | -import me.chanjar.weixin.mp.config.WxMpConfigStorage; | ||
| 20 | import org.springframework.context.annotation.Lazy; | 19 | import org.springframework.context.annotation.Lazy; |
| 21 | -import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 22 | import org.springframework.scheduling.annotation.Scheduled; | 20 | import org.springframework.scheduling.annotation.Scheduled; |
| 23 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
| 24 | -import org.springframework.util.CollectionUtils; | ||
| 25 | import org.springframework.validation.annotation.Validated; | 22 | import org.springframework.validation.annotation.Validated; |
| 26 | 23 | ||
| 27 | import javax.annotation.PostConstruct; | 24 | import javax.annotation.PostConstruct; |
| 28 | import javax.annotation.Resource; | 25 | import javax.annotation.Resource; |
| 29 | -import java.util.HashMap; | 26 | +import java.time.LocalDateTime; |
| 30 | import java.util.List; | 27 | import java.util.List; |
| 31 | -import java.util.Map; | ||
| 32 | 28 | ||
| 33 | 29 | ||
| 34 | /** | 30 | /** |
| @@ -39,33 +35,78 @@ import java.util.Map; | @@ -39,33 +35,78 @@ import java.util.Map; | ||
| 39 | @Slf4j | 35 | @Slf4j |
| 40 | @Service | 36 | @Service |
| 41 | @Validated | 37 | @Validated |
| 42 | -public class WxAccountServiceImpl implements WxAccountService { | 38 | +public class MpAccountServiceImpl implements MpAccountService { |
| 43 | 39 | ||
| 40 | + /** | ||
| 41 | + * 定时执行 {@link #schedulePeriodicRefresh()} 的周期 | ||
| 42 | + * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高 | ||
| 43 | + */ | ||
| 44 | private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; | 44 | private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; |
| 45 | 45 | ||
| 46 | + /** | ||
| 47 | + * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新 | ||
| 48 | + */ | ||
| 49 | + @Getter | ||
| 50 | + private volatile LocalDateTime maxUpdateTime; | ||
| 51 | + | ||
| 46 | @Resource | 52 | @Resource |
| 47 | - private MpAccountMapper wxAccountMapper; | ||
| 48 | - @Resource | ||
| 49 | - private WxMpConfigDataProducer wxMpConfigDataProducer; | ||
| 50 | - @Resource | ||
| 51 | - private StringRedisTemplate stringRedisTemplate; | ||
| 52 | - @Resource | ||
| 53 | - private WxMpService wxMpService; | 53 | + private MpAccountMapper mpAccountMapper; |
| 54 | + | ||
| 54 | @Resource | 55 | @Resource |
| 55 | - private WxMpProperties wxMpProperties; | 56 | + @Lazy // 延迟加载,解决循环依赖的问题 |
| 57 | + private MpServiceFactory mpServiceFactory; | ||
| 58 | + | ||
| 56 | @Resource | 59 | @Resource |
| 57 | - @Lazy // 注入自己,所以延迟加载 | ||
| 58 | - private WxAccountService self; | 60 | + private MpConfigProducer mpConfigDataProducer; |
| 61 | + | ||
| 62 | + @Override | ||
| 63 | + @PostConstruct | ||
| 64 | + public void initLocalCache() { | ||
| 65 | + initLocalCacheIfUpdate(null); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) | ||
| 69 | + public void schedulePeriodicRefresh() { | ||
| 70 | + initLocalCacheIfUpdate(this.maxUpdateTime); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 刷新本地缓存 | ||
| 75 | + * | ||
| 76 | + * @param maxUpdateTime 最大更新时间 | ||
| 77 | + * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存 | ||
| 78 | + * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存 | ||
| 79 | + */ | ||
| 80 | + private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) { | ||
| 81 | + // 注意:忽略自动多租户,因为要全局初始化缓存 | ||
| 82 | + TenantUtils.executeIgnore(() -> { | ||
| 83 | + // 第一步:基于 maxUpdateTime 判断缓存是否刷新。 | ||
| 84 | + // 如果没有增量的数据变化,则不进行本地缓存的刷新 | ||
| 85 | + if (maxUpdateTime != null | ||
| 86 | + && mpAccountMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) { | ||
| 87 | + log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime); | ||
| 88 | + return; | ||
| 89 | + } | ||
| 90 | + List<MpAccountDO> accounts = mpAccountMapper.selectList(); | ||
| 91 | + log.info("[initLocalCacheIfUpdate][缓存公众号账号,数量为:{}]", accounts.size()); | ||
| 92 | + | ||
| 93 | + // 第二步:构建缓存。创建或更新支付 Client | ||
| 94 | + mpServiceFactory.init(accounts); | ||
| 95 | + | ||
| 96 | + // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。 | ||
| 97 | + this.maxUpdateTime = CollectionUtils.getMaxValue(accounts, MpAccountDO::getUpdateTime); | ||
| 98 | + }); | ||
| 99 | + } | ||
| 59 | 100 | ||
| 60 | @Override | 101 | @Override |
| 61 | public Long createAccount(MpAccountCreateReqVO createReqVO) { | 102 | public Long createAccount(MpAccountCreateReqVO createReqVO) { |
| 62 | // TODO 芋艿:校验唯一性 | 103 | // TODO 芋艿:校验唯一性 |
| 63 | // 插入 | 104 | // 插入 |
| 64 | MpAccountDO wxAccount = MpAccountConvert.INSTANCE.convert(createReqVO); | 105 | MpAccountDO wxAccount = MpAccountConvert.INSTANCE.convert(createReqVO); |
| 65 | - wxAccountMapper.insert(wxAccount); | 106 | + mpAccountMapper.insert(wxAccount); |
| 66 | 107 | ||
| 67 | // TODO 芋艿:刷新的方式 | 108 | // TODO 芋艿:刷新的方式 |
| 68 | - wxMpConfigDataProducer.sendDictDataRefreshMessage(); | 109 | + mpConfigDataProducer.sendDictDataRefreshMessage(); |
| 69 | // 返回 | 110 | // 返回 |
| 70 | return wxAccount.getId(); | 111 | return wxAccount.getId(); |
| 71 | } | 112 | } |
| @@ -77,10 +118,10 @@ public class WxAccountServiceImpl implements WxAccountService { | @@ -77,10 +118,10 @@ public class WxAccountServiceImpl implements WxAccountService { | ||
| 77 | validateWxAccountExists(updateReqVO.getId()); | 118 | validateWxAccountExists(updateReqVO.getId()); |
| 78 | // 更新 | 119 | // 更新 |
| 79 | MpAccountDO updateObj = MpAccountConvert.INSTANCE.convert(updateReqVO); | 120 | MpAccountDO updateObj = MpAccountConvert.INSTANCE.convert(updateReqVO); |
| 80 | - wxAccountMapper.updateById(updateObj); | 121 | + mpAccountMapper.updateById(updateObj); |
| 81 | 122 | ||
| 82 | // TODO 芋艿:刷新的方式 | 123 | // TODO 芋艿:刷新的方式 |
| 83 | - wxMpConfigDataProducer.sendDictDataRefreshMessage(); | 124 | + mpConfigDataProducer.sendDictDataRefreshMessage(); |
| 84 | } | 125 | } |
| 85 | 126 | ||
| 86 | @Override | 127 | @Override |
| @@ -88,70 +129,31 @@ public class WxAccountServiceImpl implements WxAccountService { | @@ -88,70 +129,31 @@ public class WxAccountServiceImpl implements WxAccountService { | ||
| 88 | // 校验存在 | 129 | // 校验存在 |
| 89 | validateWxAccountExists(id); | 130 | validateWxAccountExists(id); |
| 90 | // 删除 | 131 | // 删除 |
| 91 | - wxAccountMapper.deleteById(id); | 132 | + mpAccountMapper.deleteById(id); |
| 92 | 133 | ||
| 93 | // TODO 芋艿:刷新的方式 | 134 | // TODO 芋艿:刷新的方式 |
| 94 | - wxMpConfigDataProducer.sendDictDataRefreshMessage(); | 135 | + mpConfigDataProducer.sendDictDataRefreshMessage(); |
| 95 | } | 136 | } |
| 96 | 137 | ||
| 97 | private void validateWxAccountExists(Long id) { | 138 | private void validateWxAccountExists(Long id) { |
| 98 | - if (wxAccountMapper.selectById(id) == null) { | 139 | + if (mpAccountMapper.selectById(id) == null) { |
| 99 | throw ServiceExceptionUtil.exception(ErrorCodeConstants.WX_ACCOUNT_NOT_EXISTS); | 140 | throw ServiceExceptionUtil.exception(ErrorCodeConstants.WX_ACCOUNT_NOT_EXISTS); |
| 100 | } | 141 | } |
| 101 | } | 142 | } |
| 102 | 143 | ||
| 103 | @Override | 144 | @Override |
| 104 | public MpAccountDO getAccount(Long id) { | 145 | public MpAccountDO getAccount(Long id) { |
| 105 | - return wxAccountMapper.selectById(id); | 146 | + return mpAccountMapper.selectById(id); |
| 106 | } | 147 | } |
| 107 | 148 | ||
| 108 | @Override | 149 | @Override |
| 109 | public PageResult<MpAccountDO> getAccountPage(MpAccountPageReqVO pageReqVO) { | 150 | public PageResult<MpAccountDO> getAccountPage(MpAccountPageReqVO pageReqVO) { |
| 110 | - return wxAccountMapper.selectPage(pageReqVO); | 151 | + return mpAccountMapper.selectPage(pageReqVO); |
| 111 | } | 152 | } |
| 112 | 153 | ||
| 113 | @Override | 154 | @Override |
| 114 | public MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val) { | 155 | public MpAccountDO findBy(SFunction<MpAccountDO, ?> field, Object val) { |
| 115 | - return wxAccountMapper.selectOne(field, val); | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - @PostConstruct | ||
| 119 | - @TenantIgnore | ||
| 120 | - @Override | ||
| 121 | - public void initLoadWxMpConfigStorages() { | ||
| 122 | - // TODO 芋艿:刷新的方式 | ||
| 123 | - List<MpAccountDO> wxAccountList = this.wxAccountMapper.selectList(); | ||
| 124 | - if (CollectionUtils.isEmpty(wxAccountList)) { | ||
| 125 | - log.info("未读取到公众号配置,请在管理后台添加"); | ||
| 126 | - return; | ||
| 127 | - } | ||
| 128 | - log.info("加载到{}条公众号配置", wxAccountList.size()); | ||
| 129 | - wxAccountList.forEach(account -> addAccountToRuntime(account, new RedisTemplateWxRedisOps(stringRedisTemplate))); | ||
| 130 | - log.info("公众号配置加载完成"); | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - /** | ||
| 134 | - * 添加账号到当前程序,如首次添加需初始化configStorageMap | ||
| 135 | - * | ||
| 136 | - * @param account 公众号 | ||
| 137 | - */ | ||
| 138 | - private synchronized void addAccountToRuntime(MpAccountDO account, RedisTemplateWxRedisOps redisOps) { | ||
| 139 | - String appId = account.getAppId(); | ||
| 140 | - WxMpConfigStorage wxMpRedisConfig = account.toWxMpConfigStorage(redisOps, wxMpProperties); | ||
| 141 | - try { | ||
| 142 | - wxMpService.addConfigStorage(appId, wxMpRedisConfig); | ||
| 143 | - } catch (NullPointerException e) { | ||
| 144 | - log.info("需初始化configStorageMap..."); | ||
| 145 | - Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4); | ||
| 146 | - configStorages.put(appId, wxMpRedisConfig); | ||
| 147 | - wxMpService.setMultiConfigStorages(configStorages, appId); | ||
| 148 | - } | 156 | + return mpAccountMapper.selectOne(field, val); |
| 149 | } | 157 | } |
| 150 | 158 | ||
| 151 | - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) | ||
| 152 | - public void schedulePeriodicRefresh() { | ||
| 153 | - self.initLoadWxMpConfigStorages(); | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - | ||
| 157 | } | 159 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/NullHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/fansmsgres/NullHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.fansmsgres; |
| 2 | 2 | ||
| 3 | import me.chanjar.weixin.common.session.WxSessionManager; | 3 | import me.chanjar.weixin.common.session.WxSessionManager; |
| 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; | 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; |
| @@ -9,13 +9,15 @@ import org.springframework.stereotype.Component; | @@ -9,13 +9,15 @@ import org.springframework.stereotype.Component; | ||
| 9 | 9 | ||
| 10 | import java.util.Map; | 10 | import java.util.Map; |
| 11 | 11 | ||
| 12 | +/** | ||
| 13 | + * 点击菜单连接的事件处理器 | ||
| 14 | + */ | ||
| 12 | @Component | 15 | @Component |
| 13 | public class NullHandler implements WxMpMessageHandler { | 16 | public class NullHandler implements WxMpMessageHandler { |
| 14 | 17 | ||
| 15 | @Override | 18 | @Override |
| 16 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||
| 17 | - Map<String, Object> context, WxMpService wxMpService, | ||
| 18 | - WxSessionManager sessionManager) { | 19 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 20 | + WxMpService wxMpService, WxSessionManager sessionManager) { | ||
| 19 | return null; | 21 | return null; |
| 20 | } | 22 | } |
| 21 | 23 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/MsgHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/DefaultMessageHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.io.FileUtil; | 3 | import cn.hutool.core.io.FileUtil; |
| 4 | import cn.hutool.http.HtmlUtil; | 4 | import cn.hutool.http.HtmlUtil; |
| @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.infra.api.file.FileApi; | @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.infra.api.file.FileApi; | ||
| 8 | import cn.iocoder.yudao.module.mp.builder.TextBuilder; | 8 | import cn.iocoder.yudao.module.mp.builder.TextBuilder; |
| 9 | import cn.iocoder.yudao.module.mp.controller.admin.fansmsg.vo.WxFansMsgCreateReqVO; | 9 | import cn.iocoder.yudao.module.mp.controller.admin.fansmsg.vo.WxFansMsgCreateReqVO; |
| 10 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | 10 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; |
| 11 | -import cn.iocoder.yudao.module.mp.service.account.WxAccountService; | 11 | +import cn.iocoder.yudao.module.mp.service.account.MpAccountService; |
| 12 | import cn.iocoder.yudao.module.mp.service.fansmsg.WxFansMsgService; | 12 | import cn.iocoder.yudao.module.mp.service.fansmsg.WxFansMsgService; |
| 13 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 14 | import me.chanjar.weixin.common.api.WxConsts; | 14 | import me.chanjar.weixin.common.api.WxConsts; |
| @@ -21,6 +21,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | @@ -21,6 +21,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | ||
| 21 | import me.chanjar.weixin.mp.bean.result.WxMpUser; | 21 | import me.chanjar.weixin.mp.bean.result.WxMpUser; |
| 22 | import org.apache.commons.lang3.StringUtils; | 22 | import org.apache.commons.lang3.StringUtils; |
| 23 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 24 | +import org.springframework.context.annotation.Lazy; | ||
| 24 | import org.springframework.stereotype.Component; | 25 | import org.springframework.stereotype.Component; |
| 25 | 26 | ||
| 26 | import javax.annotation.Resource; | 27 | import javax.annotation.Resource; |
| @@ -28,11 +29,18 @@ import java.io.File; | @@ -28,11 +29,18 @@ import java.io.File; | ||
| 28 | import java.io.UnsupportedEncodingException; | 29 | import java.io.UnsupportedEncodingException; |
| 29 | import java.util.Map; | 30 | import java.util.Map; |
| 30 | 31 | ||
| 32 | +/** | ||
| 33 | + * 默认所有消息的事件处理器 | ||
| 34 | + * | ||
| 35 | + * // TODO 芋艿:待实现 | ||
| 36 | + */ | ||
| 31 | @Component | 37 | @Component |
| 32 | @Slf4j | 38 | @Slf4j |
| 33 | -public class MsgHandler implements WxMpMessageHandler { | ||
| 34 | - @Autowired | ||
| 35 | - private WxAccountService wxAccountService; | 39 | +public class DefaultMessageHandler implements WxMpMessageHandler { |
| 40 | + | ||
| 41 | + @Resource | ||
| 42 | + @Lazy // 延迟加载,解决循环依赖的问题 | ||
| 43 | + private MpAccountService mpAccountService; | ||
| 36 | 44 | ||
| 37 | @Autowired | 45 | @Autowired |
| 38 | private WxFansMsgService wxFansMsgService; | 46 | private WxFansMsgService wxFansMsgService; |
| @@ -55,7 +63,7 @@ public class MsgHandler implements WxMpMessageHandler { | @@ -55,7 +63,7 @@ public class MsgHandler implements WxMpMessageHandler { | ||
| 55 | WxMpUser wxmpUser = weixinService.getUserService() | 63 | WxMpUser wxmpUser = weixinService.getUserService() |
| 56 | .userInfo(wxMessage.getFromUser(), null); | 64 | .userInfo(wxMessage.getFromUser(), null); |
| 57 | if (wxmpUser != null) { | 65 | if (wxmpUser != null) { |
| 58 | - MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); | 66 | + MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); |
| 59 | if (wxAccount != null) { | 67 | if (wxAccount != null) { |
| 60 | 68 | ||
| 61 | if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) { | 69 | if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) { |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/KfSessionHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/KfSessionHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import me.chanjar.weixin.common.session.WxSessionManager; | 3 | import me.chanjar.weixin.common.session.WxSessionManager; |
| 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; | 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; |
| @@ -9,14 +9,18 @@ import org.springframework.stereotype.Component; | @@ -9,14 +9,18 @@ import org.springframework.stereotype.Component; | ||
| 9 | 9 | ||
| 10 | import java.util.Map; | 10 | import java.util.Map; |
| 11 | 11 | ||
| 12 | +/** | ||
| 13 | + * 接收客服会话管理的事件处理器 | ||
| 14 | + * | ||
| 15 | + * @author 芋道源码 | ||
| 16 | + */ | ||
| 12 | @Component | 17 | @Component |
| 13 | public class KfSessionHandler implements WxMpMessageHandler { | 18 | public class KfSessionHandler implements WxMpMessageHandler { |
| 14 | 19 | ||
| 15 | @Override | 20 | @Override |
| 16 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||
| 17 | - Map<String, Object> context, WxMpService wxMpService, | ||
| 18 | - WxSessionManager sessionManager) { | ||
| 19 | - //TODO 对会话做处理 | 21 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 22 | + WxMpService wxMpService, WxSessionManager sessionManager) { | ||
| 23 | + // TODO 对会话做处理 | ||
| 20 | return null; | 24 | return null; |
| 21 | } | 25 | } |
| 22 | 26 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/LocationHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/LocationHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.mp.builder.TextBuilder; | 3 | import cn.iocoder.yudao.module.mp.builder.TextBuilder; |
| 4 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
| @@ -13,14 +13,18 @@ import java.util.Map; | @@ -13,14 +13,18 @@ import java.util.Map; | ||
| 13 | 13 | ||
| 14 | import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; | 14 | import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; |
| 15 | 15 | ||
| 16 | +/** | ||
| 17 | + * 上报地理位置的事件处理器 | ||
| 18 | + * | ||
| 19 | + * // TODO @芋艿:需要实现一下~ | ||
| 20 | + */ | ||
| 16 | @Component | 21 | @Component |
| 17 | @Slf4j | 22 | @Slf4j |
| 18 | public class LocationHandler implements WxMpMessageHandler { | 23 | public class LocationHandler implements WxMpMessageHandler { |
| 19 | 24 | ||
| 20 | @Override | 25 | @Override |
| 21 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||
| 22 | - Map<String, Object> context, WxMpService wxMpService, | ||
| 23 | - WxSessionManager sessionManager) { | 26 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 27 | + WxMpService wxMpService, WxSessionManager sessionManager) { | ||
| 24 | if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) { | 28 | if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) { |
| 25 | //TODO 接收处理用户发送的地理位置消息 | 29 | //TODO 接收处理用户发送的地理位置消息 |
| 26 | try { | 30 | try { |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/LogHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/LogHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 4 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
| @@ -11,13 +11,18 @@ import org.springframework.stereotype.Component; | @@ -11,13 +11,18 @@ import org.springframework.stereotype.Component; | ||
| 11 | 11 | ||
| 12 | import java.util.Map; | 12 | import java.util.Map; |
| 13 | 13 | ||
| 14 | +/** | ||
| 15 | + * 保存微信消息的事件处理器 | ||
| 16 | + * | ||
| 17 | + * // TODO 芋艿:实现一下 | ||
| 18 | + */ | ||
| 14 | @Component | 19 | @Component |
| 15 | @Slf4j | 20 | @Slf4j |
| 16 | public class LogHandler implements WxMpMessageHandler { | 21 | public class LogHandler implements WxMpMessageHandler { |
| 22 | + | ||
| 17 | @Override | 23 | @Override |
| 18 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||
| 19 | - Map<String, Object> context, WxMpService wxMpService, | ||
| 20 | - WxSessionManager sessionManager) { | 24 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 25 | + WxMpService wxMpService, WxSessionManager sessionManager) { | ||
| 21 | log.info("接收到请求消息,内容:{}", JsonUtils.toJsonString(wxMessage)); | 26 | log.info("接收到请求消息,内容:{}", JsonUtils.toJsonString(wxMessage)); |
| 22 | return null; | 27 | return null; |
| 23 | } | 28 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/MenuHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/MenuHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import me.chanjar.weixin.common.session.WxSessionManager; | 3 | import me.chanjar.weixin.common.session.WxSessionManager; |
| 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; | 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; |
| @@ -11,6 +11,11 @@ import java.util.Map; | @@ -11,6 +11,11 @@ import java.util.Map; | ||
| 11 | 11 | ||
| 12 | import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; | 12 | import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; |
| 13 | 13 | ||
| 14 | +/** | ||
| 15 | + * 自定义菜单的事件处理器 | ||
| 16 | + * | ||
| 17 | + * // TODO 芋艿:待实现 | ||
| 18 | + */ | ||
| 14 | @Component | 19 | @Component |
| 15 | public class MenuHandler implements WxMpMessageHandler { | 20 | public class MenuHandler implements WxMpMessageHandler { |
| 16 | 21 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/ScanHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/ScanHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import me.chanjar.weixin.common.error.WxErrorException; | 3 | import me.chanjar.weixin.common.error.WxErrorException; |
| 4 | import me.chanjar.weixin.common.session.WxSessionManager; | 4 | import me.chanjar.weixin.common.session.WxSessionManager; |
| @@ -10,6 +10,9 @@ import org.springframework.stereotype.Component; | @@ -10,6 +10,9 @@ import org.springframework.stereotype.Component; | ||
| 10 | 10 | ||
| 11 | import java.util.Map; | 11 | import java.util.Map; |
| 12 | 12 | ||
| 13 | +/** | ||
| 14 | + * 扫码的事件处理器 | ||
| 15 | + */ | ||
| 13 | @Component | 16 | @Component |
| 14 | public class ScanHandler implements WxMpMessageHandler { | 17 | public class ScanHandler implements WxMpMessageHandler { |
| 15 | 18 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/StoreCheckNotifyHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/StoreCheckNotifyHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import me.chanjar.weixin.common.session.WxSessionManager; | 3 | import me.chanjar.weixin.common.session.WxSessionManager; |
| 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; | 4 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; |
| @@ -10,8 +10,7 @@ import org.springframework.stereotype.Component; | @@ -10,8 +10,7 @@ import org.springframework.stereotype.Component; | ||
| 10 | import java.util.Map; | 10 | import java.util.Map; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| 13 | - * 门店审核事件处理 | ||
| 14 | - * | 13 | + * 门店审核事件的事件处理器 |
| 15 | */ | 14 | */ |
| 16 | @Component | 15 | @Component |
| 17 | public class StoreCheckNotifyHandler implements WxMpMessageHandler { | 16 | public class StoreCheckNotifyHandler implements WxMpMessageHandler { |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/SubscribeHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/SubscribeHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.date.DateUtil; | 3 | import cn.hutool.core.date.DateUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||
| 9 | import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO; | 9 | import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO; |
| 10 | import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO; | 10 | import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO; |
| 11 | import cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate.WxTextTemplateDO; | 11 | import cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate.WxTextTemplateDO; |
| 12 | -import cn.iocoder.yudao.module.mp.service.account.WxAccountService; | 12 | +import cn.iocoder.yudao.module.mp.service.account.MpAccountService; |
| 13 | import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService; | 13 | import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService; |
| 14 | import cn.iocoder.yudao.module.mp.service.accountfanstag.WxAccountFansTagService; | 14 | import cn.iocoder.yudao.module.mp.service.accountfanstag.WxAccountFansTagService; |
| 15 | import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService; | 15 | import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService; |
| @@ -23,11 +23,18 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | @@ -23,11 +23,18 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | ||
| 23 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | 23 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; |
| 24 | import me.chanjar.weixin.mp.bean.result.WxMpUser; | 24 | import me.chanjar.weixin.mp.bean.result.WxMpUser; |
| 25 | import org.springframework.beans.factory.annotation.Autowired; | 25 | import org.springframework.beans.factory.annotation.Autowired; |
| 26 | +import org.springframework.context.annotation.Lazy; | ||
| 26 | import org.springframework.stereotype.Component; | 27 | import org.springframework.stereotype.Component; |
| 27 | 28 | ||
| 29 | +import javax.annotation.Resource; | ||
| 28 | import java.io.UnsupportedEncodingException; | 30 | import java.io.UnsupportedEncodingException; |
| 29 | import java.util.Map; | 31 | import java.util.Map; |
| 30 | 32 | ||
| 33 | +/** | ||
| 34 | + * 关注的事件处理器 | ||
| 35 | + * | ||
| 36 | + * // TODO 芋艿:待实现 | ||
| 37 | + */ | ||
| 31 | @Component | 38 | @Component |
| 32 | @Slf4j | 39 | @Slf4j |
| 33 | public class SubscribeHandler implements WxMpMessageHandler { | 40 | public class SubscribeHandler implements WxMpMessageHandler { |
| @@ -35,8 +42,9 @@ public class SubscribeHandler implements WxMpMessageHandler { | @@ -35,8 +42,9 @@ public class SubscribeHandler implements WxMpMessageHandler { | ||
| 35 | @Autowired | 42 | @Autowired |
| 36 | private WxTextTemplateService wxTextTemplateService; | 43 | private WxTextTemplateService wxTextTemplateService; |
| 37 | 44 | ||
| 38 | - @Autowired | ||
| 39 | - private WxAccountService wxAccountService; | 45 | + @Resource |
| 46 | + @Lazy // 延迟加载,解决循环依赖的问题 | ||
| 47 | + private MpAccountService mpAccountService; | ||
| 40 | 48 | ||
| 41 | @Autowired | 49 | @Autowired |
| 42 | private WxSubscribeTextService wxSubscribeTextService; | 50 | private WxSubscribeTextService wxSubscribeTextService; |
| @@ -60,7 +68,7 @@ public class SubscribeHandler implements WxMpMessageHandler { | @@ -60,7 +68,7 @@ public class SubscribeHandler implements WxMpMessageHandler { | ||
| 60 | .userInfo(wxMessage.getFromUser(), null); | 68 | .userInfo(wxMessage.getFromUser(), null); |
| 61 | if (wxmpUser != null) { | 69 | if (wxmpUser != null) { |
| 62 | // 可以添加关注用户到本地数据库 | 70 | // 可以添加关注用户到本地数据库 |
| 63 | - MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); | 71 | + MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); |
| 64 | if (wxAccount != null) { | 72 | if (wxAccount != null) { |
| 65 | WxAccountFansDO wxAccountFans = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, wxmpUser.getOpenId()); | 73 | WxAccountFansDO wxAccountFans = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, wxmpUser.getOpenId()); |
| 66 | if (wxAccountFans == null) {//insert | 74 | if (wxAccountFans == null) {//insert |
| @@ -128,7 +136,7 @@ public class SubscribeHandler implements WxMpMessageHandler { | @@ -128,7 +136,7 @@ public class SubscribeHandler implements WxMpMessageHandler { | ||
| 128 | 136 | ||
| 129 | try { | 137 | try { |
| 130 | String content = "感谢关注!";//默认 | 138 | String content = "感谢关注!";//默认 |
| 131 | - MpAccountDO wxAccount = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); | 139 | + MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); |
| 132 | if (wxAccount != null) { | 140 | if (wxAccount != null) { |
| 133 | WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.findBy(WxSubscribeTextDO::getWxAccountId, String.valueOf(wxAccount.getId())); | 141 | WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.findBy(WxSubscribeTextDO::getWxAccountId, String.valueOf(wxAccount.getId())); |
| 134 | if (wxSubscribeText != null) { | 142 | if (wxSubscribeText != null) { |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/UnsubscribeHandler.java renamed to yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/UnsubscribeHandler.java
| 1 | -package cn.iocoder.yudao.module.mp.handler; | 1 | +package cn.iocoder.yudao.module.mp.service.handler; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.mp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO; | 3 | import cn.iocoder.yudao.module.mp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO; |
| 4 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | 4 | import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; |
| 5 | import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO; | 5 | import cn.iocoder.yudao.module.mp.dal.dataobject.accountfans.WxAccountFansDO; |
| 6 | -import cn.iocoder.yudao.module.mp.service.account.WxAccountService; | 6 | +import cn.iocoder.yudao.module.mp.service.account.MpAccountService; |
| 7 | import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService; | 7 | import cn.iocoder.yudao.module.mp.service.accountfans.WxAccountFansService; |
| 8 | import lombok.extern.slf4j.Slf4j; | 8 | import lombok.extern.slf4j.Slf4j; |
| 9 | import me.chanjar.weixin.common.session.WxSessionManager; | 9 | import me.chanjar.weixin.common.session.WxSessionManager; |
| @@ -12,16 +12,24 @@ import me.chanjar.weixin.mp.api.WxMpService; | @@ -12,16 +12,24 @@ import me.chanjar.weixin.mp.api.WxMpService; | ||
| 12 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | 12 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; |
| 13 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | 13 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; |
| 14 | import org.springframework.beans.factory.annotation.Autowired; | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 15 | +import org.springframework.context.annotation.Lazy; | ||
| 15 | import org.springframework.stereotype.Component; | 16 | import org.springframework.stereotype.Component; |
| 16 | 17 | ||
| 18 | +import javax.annotation.Resource; | ||
| 17 | import java.util.Map; | 19 | import java.util.Map; |
| 18 | 20 | ||
| 21 | +/** | ||
| 22 | + * 取消关注的事件处理器 | ||
| 23 | + * | ||
| 24 | + * // TODO 芋艿:待实现 | ||
| 25 | + */ | ||
| 19 | @Component | 26 | @Component |
| 20 | @Slf4j | 27 | @Slf4j |
| 21 | public class UnsubscribeHandler implements WxMpMessageHandler { | 28 | public class UnsubscribeHandler implements WxMpMessageHandler { |
| 22 | 29 | ||
| 23 | - @Autowired | ||
| 24 | - private WxAccountService wxAccountService; | 30 | + @Resource |
| 31 | + @Lazy // 延迟加载,解决循环依赖的问题 | ||
| 32 | + private MpAccountService mpAccountService; | ||
| 25 | 33 | ||
| 26 | @Autowired | 34 | @Autowired |
| 27 | private WxAccountFansService wxAccountFansService; | 35 | private WxAccountFansService wxAccountFansService; |
| @@ -34,7 +42,7 @@ public class UnsubscribeHandler implements WxMpMessageHandler { | @@ -34,7 +42,7 @@ public class UnsubscribeHandler implements WxMpMessageHandler { | ||
| 34 | log.info("取消关注用户 OPENID: " + openId); | 42 | log.info("取消关注用户 OPENID: " + openId); |
| 35 | // TODO 可以更新本地数据库为取消关注状态 | 43 | // TODO 可以更新本地数据库为取消关注状态 |
| 36 | 44 | ||
| 37 | - MpAccountDO wxAccountDO = wxAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); | 45 | + MpAccountDO wxAccountDO = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser()); |
| 38 | if (wxAccountDO != null) { | 46 | if (wxAccountDO != null) { |
| 39 | WxAccountFansDO wxAccountFansDO = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, openId); | 47 | WxAccountFansDO wxAccountFansDO = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, openId); |
| 40 | if (wxAccountFansDO != null) { | 48 | if (wxAccountFansDO != null) { |