Переглянути джерело

简化本地缓存的实现,萌新更容易看懂!

YunaiV 2 роки тому
батько
коміт
c744e115e3
37 змінених файлів з 111 додано та 657 видалено
  1. 3 6
      yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
  2. 0 11
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileConfigMapper.java
  3. 1 1
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/consumer/file/FileConfigRefreshConsumer.java
  4. 1 1
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java
  5. 4 44
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java
  6. 1 5
      yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
  7. 3 8
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java
  8. 3 36
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java
  9. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java
  10. 0 6
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2ClientMapper.java
  11. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java
  12. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java
  13. 0 14
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuBatchInsertMapper.java
  14. 7 11
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuMapper.java
  15. 0 14
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleBatchInsertMapper.java
  16. 7 16
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java
  17. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sensitiveword/SensitiveWordMapper.java
  18. 0 6
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsChannelMapper.java
  19. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java
  20. 3 8
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java
  21. 6 41
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java
  22. 2 41
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java
  23. 6 40
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
  24. 11 68
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
  25. 3 41
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
  26. 3 42
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
  27. 3 42
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java
  28. 10 48
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java
  29. 1 4
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
  30. 7 13
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java
  31. 0 3
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java
  32. 7 17
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java
  33. 10 22
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
  34. 0 3
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java
  35. 0 2
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
  36. 8 13
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java
  37. 1 5
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java

+ 3 - 6
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java

@@ -81,22 +81,19 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
     }
 
     /**
-     * 逐条插入,适合少量数据插入,或者对性能要求不高的场景
-     * <p>
-     * 如果大量,请使用 {@link com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch(Collection)} 方法
-     * 使用示例,可见 RoleMenuBatchInsertMapper、UserRoleBatchInsertMapper 类
+     * 批量插入,适合大量数据插入
      *
      * @param entities 实体们
      */
     default void insertBatch(Collection<T> entities) {
-        entities.forEach(this::insert);
+        Db.saveBatch(entities);
     }
 
     /**
      * 批量插入,适合大量数据插入
      *
      * @param entities 实体们
-     * @param size     插入数量 Db.saveBatch 默认为1000
+     * @param size     插入数量 Db.saveBatch 默认为 1000
      */
     default void insertBatch(Collection<T> entities, int size) {
         Db.saveBatch(entities, size);

+ 0 - 11
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileConfigMapper.java

@@ -6,15 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
-
-/**
- * 文件配置 Mapper
- *
- * @author 芋道源码
- */
 @Mapper
 public interface FileConfigMapper extends BaseMapperX<FileConfigDO> {
 
@@ -26,7 +18,4 @@ public interface FileConfigMapper extends BaseMapperX<FileConfigDO> {
                 .orderByDesc(FileConfigDO::getId));
     }
 
-    @Select("SELECT COUNT(*) FROM infra_file_config WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 1 - 1
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/consumer/file/FileConfigRefreshConsumer.java

@@ -23,7 +23,7 @@ public class FileConfigRefreshConsumer extends AbstractChannelMessageListener<Fi
     @Override
     public void onMessage(FileConfigRefreshMessage message) {
         log.info("[onMessage][收到 FileConfig 刷新消息]");
-        fileConfigService.initFileClients();
+        fileConfigService.initLocalCache();
     }
 
 }

+ 1 - 1
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java

@@ -21,7 +21,7 @@ public interface FileConfigService {
     /**
      * 初始化文件客户端
      */
-    void initFileClients();
+    void initLocalCache();
 
     /**
      * 创建文件配置

+ 4 - 44
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.infra.service.file;
 import cn.hutool.core.io.resource.ResourceUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
 import cn.iocoder.yudao.framework.file.core.client.FileClient;
@@ -19,7 +18,6 @@ import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
 import cn.iocoder.yudao.module.infra.mq.producer.file.FileConfigProducer;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -29,7 +27,6 @@ import org.springframework.validation.annotation.Validated;
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import javax.validation.Validator;
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -48,18 +45,6 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_CONFIG
 @Slf4j
 public class FileConfigServiceImpl implements FileConfigService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
-    /**
-     * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime maxUpdateTime;
-
     @Resource
     private FileClientFactory fileClientFactory;
     /**
@@ -79,34 +64,12 @@ public class FileConfigServiceImpl implements FileConfigService {
 
     @Override
     @PostConstruct
-    public void initFileClients() {
-        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) {
-        // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-        // 如果没有增量的数据变化,则不进行本地缓存的刷新
-        if (maxUpdateTime != null
-                && fileConfigMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-            log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-            return;
-        }
+    public void initLocalCache() {
+        // 第一步:查询数据
         List<FileConfigDO> configs = fileConfigMapper.selectList();
-        log.info("[initLocalCacheIfUpdate][缓存文件配置,数量为:{}]", configs.size());
+        log.info("[initLocalCache][缓存文件配置,数量为:{}]", configs.size());
 
-        // 第二步:构建缓存创建或更新文件 Client
+        // 第二步:构建缓存:创建或更新文件 Client
         configs.forEach(config -> {
             fileClientFactory.createOrUpdateFileClient(config.getId(), config.getStorage(), config.getConfig());
             // 如果是 master,进行设置
@@ -114,9 +77,6 @@ public class FileConfigServiceImpl implements FileConfigService {
                 masterFileClient = fileClientFactory.getFileClient(config.getId());
             }
         });
-
-        // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-        this.maxUpdateTime = CollectionUtils.getMaxValue(configs, FileConfigDO::getUpdateTime);
     }
 
     @Override

+ 1 - 5
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java

@@ -30,7 +30,6 @@ import java.util.Map;
 import static cn.hutool.core.util.RandomUtil.randomEle;
 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
@@ -74,16 +73,13 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
         when(fileClientFactory.getFileClient(eq(1L))).thenReturn(masterFileClient);
 
         // 调用
-        fileConfigService.initFileClients();
+        fileConfigService.initLocalCache();
         // 断言 fileClientFactory 调用
         verify(fileClientFactory).createOrUpdateFileClient(eq(1L),
                 eq(configDO1.getStorage()), eq(configDO1.getConfig()));
         verify(fileClientFactory).createOrUpdateFileClient(eq(2L),
                 eq(configDO2.getStorage()), eq(configDO2.getConfig()));
         assertSame(masterFileClient, fileConfigService.getMasterFileClient());
-        // 断言 maxUpdateTime 缓存
-        assertEquals(max(configDO1.getUpdateTime(), configDO2.getUpdateTime()),
-                fileConfigService.getMaxUpdateTime());
     }
 
     @Test

+ 3 - 8
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java

@@ -8,9 +8,7 @@ import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChann
 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -21,9 +19,6 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
         return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
     }
 
-    @Select("SELECT COUNT(*) FROM pay_channel WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
     default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
         return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
                 .eqIfPresent("code", reqVO.getCode())
@@ -67,14 +62,14 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
      * 根据条件获取渠道
      *
      * @param merchantId 商户编号
-     * @param appid      应用编号 // TODO @aquan:appid =》appId
+     * @param appI      应用编号
      * @param code       渠道编码
      * @return 数量
      */
-    default PayChannelDO selectOne(Long merchantId, Long appid, String code) {
+    default PayChannelDO selectOne(Long merchantId, Long appI, String code) {
         return this.selectOne((new QueryWrapper<PayChannelDO>().lambda()
                 .eq(PayChannelDO::getMerchantId, merchantId)
-                .eq(PayChannelDO::getAppId, appid)
+                .eq(PayChannelDO::getAppId, appI)
                 .eq(PayChannelDO::getCode, code)
         ));
     }

+ 3 - 36
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java

@@ -5,7 +5,6 @@ import cn.hutool.json.JSONUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 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.pay.core.client.PayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
@@ -19,7 +18,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayChannelMapper;
 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
@@ -44,12 +42,6 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_E
 @Validated
 public class PayChannelServiceImpl implements PayChannelService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
      */
@@ -70,40 +62,15 @@ public class PayChannelServiceImpl implements PayChannelService {
     @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
-                    && channelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-                return;
-            }
+            // 第一步:查询数据
             List<PayChannelDO> channels = channelMapper.selectList();
-            log.info("[initLocalCacheIfUpdate][缓存支付渠道,数量为:{}]", channels.size());
+            log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size());
 
-            // 第二步:构建缓存创建或更新支付 Client
+            // 第二步:构建缓存:创建或更新支付 Client
             channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
                     payChannel.getCode(), payChannel.getConfig()));
-
-            // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-            this.maxUpdateTime = CollectionUtils.getMaxValue(channels, PayChannelDO::getUpdateTime);
         });
     }
 

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java

@@ -6,9 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqV
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.List;
 
 @Mapper
@@ -30,7 +28,4 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
         return selectCount(DeptDO::getParentId, parentId);
     }
 
-    @Select("SELECT COUNT(*) FROM system_dept WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 6
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2ClientMapper.java

@@ -6,9 +6,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2ClientPageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-
-import java.time.LocalDateTime;
 
 
 /**
@@ -30,7 +27,4 @@ public interface OAuth2ClientMapper extends BaseMapperX<OAuth2ClientDO> {
         return selectOne(OAuth2ClientDO::getClientId, clientId);
     }
 
-    @Select("SELECT COUNT(*) FROM system_oauth2_client WHERE update_time > #{maxUpdateTime}")
-    int selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java

@@ -6,9 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuLi
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.List;
 
 @Mapper
@@ -28,7 +26,4 @@ public interface MenuMapper extends BaseMapperX<MenuDO> {
                 .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
     }
 
-    @Select("SELECT COUNT(*) FROM system_menu WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java

@@ -8,10 +8,8 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleEx
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 import org.springframework.lang.Nullable;
 
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -47,7 +45,4 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
         return selectList(RoleDO::getStatus, statuses);
     }
 
-    @Select("SELECT COUNT(*) FROM system_role WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 14
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuBatchInsertMapper.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.system.dal.mysql.permission;
-
-import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Repository;
-
-/**
- * 实体 {@link RoleMenuDO} 的批量插入 Mapper
- *
- * @author 芋道源码
- */
-@Repository
-public class RoleMenuBatchInsertMapper extends ServiceImpl<RoleMenuMapper, RoleMenuDO> {
-}

+ 7 - 11
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuMapper.java

@@ -2,13 +2,11 @@ package cn.iocoder.yudao.module.system.dal.mysql.permission;
 
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 import org.springframework.stereotype.Repository;
 
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -20,23 +18,21 @@ public interface RoleMenuMapper extends BaseMapperX<RoleMenuDO> {
     }
 
     default List<RoleMenuDO> selectListByRoleId(Long roleId) {
-        return selectList(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
+        return selectList(RoleMenuDO::getRoleId, roleId);
     }
 
     default void deleteListByRoleIdAndMenuIds(Long roleId, Collection<Long> menuIds) {
-        delete(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId)
-                .in("menu_id", menuIds));
+        delete(new LambdaQueryWrapper<RoleMenuDO>()
+                .eq(RoleMenuDO::getRoleId, roleId)
+                .in(RoleMenuDO::getMenuId, menuIds));
     }
 
     default void deleteListByMenuId(Long menuId) {
-        delete(new QueryWrapper<RoleMenuDO>().eq("menu_id", menuId));
+        delete(new LambdaQueryWrapper<RoleMenuDO>().eq(RoleMenuDO::getMenuId, menuId));
     }
 
     default void deleteListByRoleId(Long roleId) {
-        delete(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
+        delete(new LambdaQueryWrapper<RoleMenuDO>().eq(RoleMenuDO::getRoleId, roleId));
     }
 
-    @Select("SELECT COUNT(*) FROM system_role_menu WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 14
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleBatchInsertMapper.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.system.dal.mysql.permission;
-
-import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Repository;
-
-/**
- * 实体 {@link UserRoleDO} 的批量插入 Mapper
- *
- * @author 芋道源码
- */
-@Repository
-public class UserRoleBatchInsertMapper extends ServiceImpl<UserRoleMapper, UserRoleDO> {
-}

+ 7 - 16
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java

@@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.system.dal.mysql.permission;
 
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -14,32 +12,25 @@ import java.util.List;
 public interface UserRoleMapper extends BaseMapperX<UserRoleDO> {
 
     default List<UserRoleDO> selectListByUserId(Long userId) {
-        return selectList(new QueryWrapper<UserRoleDO>().eq("user_id", userId));
-    }
-
-    default List<UserRoleDO> selectListByRoleId(Long roleId) {
-        return selectList(new QueryWrapper<UserRoleDO>().eq("role_id", roleId));
+        return selectList(UserRoleDO::getUserId, userId);
     }
 
     default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {
-        delete(new QueryWrapper<UserRoleDO>().eq("user_id", userId)
-                .in("role_id", roleIds));
+        delete(new LambdaQueryWrapper<UserRoleDO>()
+                .eq(UserRoleDO::getUserId, userId)
+                .in(UserRoleDO::getRoleId, roleIds));
     }
 
     default void deleteListByUserId(Long userId) {
-        delete(new QueryWrapper<UserRoleDO>().eq("user_id", userId));
+        delete(new LambdaQueryWrapper<UserRoleDO>().eq(UserRoleDO::getUserId, userId));
     }
 
     default void deleteListByRoleId(Long roleId) {
-        delete(new QueryWrapper<UserRoleDO>().eq("role_id", roleId));
+        delete(new LambdaQueryWrapper<UserRoleDO>().eq(UserRoleDO::getRoleId, roleId));
     }
 
-
     default List<UserRoleDO> selectListByRoleIds(Collection<Long> roleIds) {
         return selectList(UserRoleDO::getRoleId, roleIds);
     }
 
-    @Select("SELECT COUNT(*) FROM system_user_role WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sensitiveword/SensitiveWordMapper.java

@@ -7,9 +7,7 @@ import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.Sensitiv
 import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -42,7 +40,4 @@ public interface SensitiveWordMapper extends BaseMapperX<SensitiveWordDO> {
         return selectOne(SensitiveWordDO::getName, name);
     }
 
-    @Select("SELECT COUNT(*) FROM system_sensitive_word WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 6
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsChannelMapper.java

@@ -6,9 +6,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-
-import java.time.LocalDateTime;
 
 @Mapper
 public interface SmsChannelMapper extends BaseMapperX<SmsChannelDO> {
@@ -21,7 +18,4 @@ public interface SmsChannelMapper extends BaseMapperX<SmsChannelDO> {
                 .orderByDesc(SmsChannelDO::getId));
     }
 
-    @Select("SELECT COUNT(*) FROM system_sms_channel WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java

@@ -7,17 +7,12 @@ import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTempla
 import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.List;
 
 @Mapper
 public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
 
-    @Select("SELECT COUNT(*) FROM system_sms_template WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
     default SmsTemplateDO selectByCode(String code) {
         return selectOne(SmsTemplateDO::getCode, code);
     }

+ 3 - 8
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java

@@ -1,15 +1,13 @@
 package cn.iocoder.yudao.module.system.dal.mysql.tenant;
 
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
 
-import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -52,7 +50,4 @@ public interface TenantMapper extends BaseMapperX<TenantDO> {
         return selectList(TenantDO::getPackageId, packageId);
     }
 
-    @Select("SELECT COUNT(*) FROM system_tenant WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
-
 }

+ 6 - 41
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java

@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
+import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
@@ -40,19 +41,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 @Slf4j
 public class DeptServiceImpl implements DeptService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 部门缓存
      * key:部门编号 {@link DeptDO#getId()}
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
-    @SuppressWarnings("FieldCanBeLocal")
+    @Getter
     private volatile Map<Long, DeptDO> deptCache;
     /**
      * 父部门缓存
@@ -61,11 +56,8 @@ public class DeptServiceImpl implements DeptService {
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter
     private volatile Multimap<Long, DeptDO> parentDeptCache;
-    /**
-     * 缓存部门的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    private volatile LocalDateTime maxUpdateTime;
 
     @Resource
     private DeptMapper deptMapper;
@@ -79,48 +71,21 @@ public class DeptServiceImpl implements DeptService {
     @Override
     @PostConstruct
     public synchronized 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
-                    && deptMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-                return;
-            }
+            // 第一步:查询数据
             List<DeptDO> depts = deptMapper.selectList();
-            log.info("[initLocalCacheIfUpdate][缓存部门,数量为:{}]", depts.size());
+            log.info("[initLocalCache][缓存部门,数量为:{}]", depts.size());
 
-            // 第二步:构建缓存。创建或更新支付 Client
-            // 构建缓存
+            // 第二步:构建缓存
             ImmutableMap.Builder<Long, DeptDO> builder = ImmutableMap.builder();
             ImmutableMultimap.Builder<Long, DeptDO> parentBuilder = ImmutableMultimap.builder();
             depts.forEach(sysRoleDO -> {
                 builder.put(sysRoleDO.getId(), sysRoleDO);
                 parentBuilder.put(sysRoleDO.getParentId(), sysRoleDO);
             });
-            // 设置缓存
             deptCache = builder.build();
             parentDeptCache = parentBuilder.build();
-
-            // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-            this.maxUpdateTime = CollectionUtils.getMaxValue(depts, DeptDO::getUpdateTime);
         });
     }
 

+ 2 - 41
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java

@@ -17,20 +17,17 @@ import com.google.common.annotations.VisibleForTesting;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
-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.Collection;
 import java.util.List;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 
 /**
@@ -43,12 +40,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 @Slf4j
 public class OAuth2ClientServiceImpl implements OAuth2ClientService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 客户端缓存
      * key:客户端编号 {@link OAuth2ClientDO#getClientId()} ()}
@@ -58,11 +49,6 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
     @Getter // 解决单测
     @Setter // 解决单测
     private volatile Map<String, OAuth2ClientDO> clientCache;
-    /**
-     * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime maxUpdateTime;
 
     @Resource
     private OAuth2ClientMapper oauth2ClientMapper;
@@ -76,37 +62,12 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
     @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) {
-        // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-        // 如果没有增量的数据变化,则不进行本地缓存的刷新
-        if (maxUpdateTime != null
-                && oauth2ClientMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-            log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-            return;
-        }
+        // 第一步:查询数据
         List<OAuth2ClientDO> clients = oauth2ClientMapper.selectList();
-        log.info("[initLocalCacheIfUpdate][缓存 OAuth2 客户端,数量为:{}]", clients.size());
+        log.info("[initLocalCache][缓存 OAuth2 客户端,数量为:{}]", clients.size());
 
         // 第二步:构建缓存。
         clientCache = convertMap(clients, OAuth2ClientDO::getClientId);
-
-        // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-        this.maxUpdateTime = getMaxValue(clients, OAuth2ClientDO::getUpdateTime);
     }
 
     @Override

+ 6 - 40
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java

@@ -18,9 +18,9 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
+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.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -28,7 +28,6 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -43,18 +42,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 @Slf4j
 public class MenuServiceImpl implements MenuService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 菜单缓存
      * key:菜单编号
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter
     private volatile Map<Long, MenuDO> menuCache;
     /**
      * 权限与菜单缓存
@@ -63,11 +57,8 @@ public class MenuServiceImpl implements MenuService {
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter
     private volatile Multimap<String, MenuDO> permissionMenuCache;
-    /**
-     * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    private volatile LocalDateTime maxUpdateTime;
 
     @Resource
     private MenuMapper menuMapper;
@@ -86,33 +77,11 @@ public class MenuServiceImpl implements MenuService {
     @Override
     @PostConstruct
     public synchronized 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) {
-        // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-        // 如果没有增量的数据变化,则不进行本地缓存的刷新
-        if (maxUpdateTime != null
-            && menuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-            log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-            return;
-        }
+        // 第一步:查询数据
         List<MenuDO> menuList = menuMapper.selectList();
-        log.info("[initLocalCacheIfUpdate][缓存菜单,数量为:{}]", menuList.size());
+        log.info("[initLocalCache][缓存菜单,数量为:{}]", menuList.size());
 
-        // 第二步:构建缓存
+        // 第二步:构建缓存
         ImmutableMap.Builder<Long, MenuDO> menuCacheBuilder = ImmutableMap.builder();
         ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
         menuList.forEach(menuDO -> {
@@ -123,9 +92,6 @@ public class MenuServiceImpl implements MenuService {
         });
         menuCache = menuCacheBuilder.build();
         permissionMenuCache = permMenuCacheBuilder.build();
-
-        // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-        this.maxUpdateTime = CollectionUtils.getMaxValue(menuList, MenuDO::getUpdateTime);
     }
 
     @Override

+ 11 - 68
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java

@@ -16,9 +16,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
-import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
-import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
@@ -32,7 +30,6 @@ import com.google.common.collect.Sets;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -40,12 +37,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.*;
 import java.util.function.Supplier;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
 import static java.util.Collections.singleton;
 
 /**
@@ -57,12 +52,6 @@ import static java.util.Collections.singleton;
 @Slf4j
 public class PermissionServiceImpl implements PermissionService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 角色编号与菜单编号的缓存映射
      * key:角色编号
@@ -83,11 +72,6 @@ public class PermissionServiceImpl implements PermissionService {
     @Getter
     @Setter // 单元测试需要
     private volatile Multimap<Long, Long> menuRoleCache;
-    /**
-     * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime roleMenuMaxUpdateTime;
 
     /**
      * 用户编号与角色编号的缓存映射
@@ -99,20 +83,11 @@ public class PermissionServiceImpl implements PermissionService {
     @Getter
     @Setter // 单元测试需要
     private volatile Map<Long, Set<Long>> userRoleCache;
-    /**
-     * 缓存 UserRole 的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime userRoleMaxUpdateTime;
 
     @Resource
     private RoleMenuMapper roleMenuMapper;
     @Resource
-    private RoleMenuBatchInsertMapper roleMenuBatchInsertMapper;
-    @Resource
     private UserRoleMapper userRoleMapper;
-    @Resource
-    private UserRoleBatchInsertMapper userRoleBatchInsertMapper;
 
     @Resource
     private RoleService roleService;
@@ -129,38 +104,22 @@ public class PermissionServiceImpl implements PermissionService {
     @Override
     @PostConstruct
     public void initLocalCache() {
-        initLocalCacheIfUpdateForRoleMenu(null);
-        initLocalCacheIfUpdateForUserRole(null);
-    }
-
-    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
-    public void schedulePeriodicRefresh() {
-        initLocalCacheIfUpdateForRoleMenu(this.roleMenuMaxUpdateTime);
-        initLocalCacheIfUpdateForUserRole(this.userRoleMaxUpdateTime);
+        initLocalCacheForRoleMenu();
+        initLocalCacheForUserRole();
     }
 
     /**
      * 刷新 RoleMenu 本地缓存
-     *
-     * @param maxUpdateTime 最大更新时间
-     *                      1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
-     *                      2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
      */
     @VisibleForTesting
-    void initLocalCacheIfUpdateForRoleMenu(LocalDateTime maxUpdateTime) {
+    void initLocalCacheForRoleMenu() {
         // 注意:忽略自动多租户,因为要全局初始化缓存
         TenantUtils.executeIgnore(() -> {
-            // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-            // 如果没有增量的数据变化,则不进行本地缓存的刷新
-            if (maxUpdateTime != null
-                    && roleMenuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                log.info("[initLocalCacheIfUpdateForRoleMenu][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-                return;
-            }
+            // 第一步:查询数据
             List<RoleMenuDO> roleMenus = roleMenuMapper.selectList();
-            log.info("[initLocalCacheIfUpdateForRoleMenu][缓存角色与菜单,数量为:{}]", roleMenus.size());
+            log.info("[initLocalCacheForRoleMenu][缓存角色与菜单,数量为:{}]", roleMenus.size());
 
-            // 第二步:构建缓存
+            // 第二步:构建缓存
             ImmutableMultimap.Builder<Long, Long> roleMenuCacheBuilder = ImmutableMultimap.builder();
             ImmutableMultimap.Builder<Long, Long> menuRoleCacheBuilder = ImmutableMultimap.builder();
             roleMenus.forEach(roleMenuDO -> {
@@ -169,40 +128,24 @@ public class PermissionServiceImpl implements PermissionService {
             });
             roleMenuCache = roleMenuCacheBuilder.build();
             menuRoleCache = menuRoleCacheBuilder.build();
-
-            // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-            this.roleMenuMaxUpdateTime = getMaxValue(roleMenus, RoleMenuDO::getUpdateTime);
         });
     }
 
     /**
      * 刷新 UserRole 本地缓存
-     *
-     * @param maxUpdateTime 最大更新时间
-     *                      1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
-     *                      2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
      */
     @VisibleForTesting
-    void initLocalCacheIfUpdateForUserRole(LocalDateTime maxUpdateTime) {
+    void initLocalCacheForUserRole() {
         // 注意:忽略自动多租户,因为要全局初始化缓存
         TenantUtils.executeIgnore(() -> {
-            // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-            // 如果没有增量的数据变化,则不进行本地缓存的刷新
-            if (maxUpdateTime != null
-                    && userRoleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                log.info("[initLocalCacheIfUpdateForUserRole][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-                return;
-            }
+            // 第一步:加载数据
             List<UserRoleDO> userRoles = userRoleMapper.selectList();
-            log.info("[initLocalCacheIfUpdateForUserRole][缓存用户与角色,数量为:{}]", userRoles.size());
+            log.info("[initLocalCacheForUserRole][缓存用户与角色,数量为:{}]", userRoles.size());
 
             // 第二步:构建缓存。
             ImmutableMultimap.Builder<Long, Long> userRoleCacheBuilder = ImmutableMultimap.builder();
             userRoles.forEach(userRoleDO -> userRoleCacheBuilder.put(userRoleDO.getUserId(), userRoleDO.getRoleId()));
             userRoleCache = CollectionUtils.convertMultiMap2(userRoles, UserRoleDO::getUserId, UserRoleDO::getRoleId);
-
-            // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-            this.userRoleMaxUpdateTime = getMaxValue(userRoles, UserRoleDO::getUpdateTime);
         });
     }
 
@@ -264,7 +207,7 @@ public class PermissionServiceImpl implements PermissionService {
         Collection<Long> deleteMenuIds = CollUtil.subtract(dbMenuIds, menuIds);
         // 执行新增和删除。对于已经授权的菜单,不用做任何处理
         if (!CollectionUtil.isEmpty(createMenuIds)) {
-            roleMenuBatchInsertMapper.saveBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
+            roleMenuMapper.insertBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
                 RoleMenuDO entity = new RoleMenuDO();
                 entity.setRoleId(roleId);
                 entity.setMenuId(menuId);
@@ -308,7 +251,7 @@ public class PermissionServiceImpl implements PermissionService {
         Collection<Long> deleteMenuIds = CollUtil.subtract(dbRoleIds, roleIds);
         // 执行新增和删除。对于已经授权的角色,不用做任何处理
         if (!CollectionUtil.isEmpty(createRoleIds)) {
-            userRoleBatchInsertMapper.saveBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
+            userRoleMapper.insertBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
                 UserRoleDO entity = new UserRoleDO();
                 entity.setUserId(userId);
                 entity.setRoleId(roleId);

+ 3 - 41
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java

@@ -22,7 +22,6 @@ import com.google.common.annotations.VisibleForTesting;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.lang.Nullable;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -31,7 +30,6 @@ import org.springframework.util.StringUtils;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -47,12 +45,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 @Slf4j
 public class RoleServiceImpl implements RoleService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 角色缓存
      * key:角色编号 {@link RoleDO#getId()}
@@ -61,11 +53,6 @@ public class RoleServiceImpl implements RoleService {
      */
     @Getter
     private volatile Map<Long, RoleDO> roleCache;
-    /**
-     * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime maxUpdateTime;
 
     @Resource
     private PermissionService permissionService;
@@ -82,39 +69,14 @@ public class RoleServiceImpl implements RoleService {
     @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
-                    && roleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-                return;
-            }
+            // 第一步:查询数据
             List<RoleDO> roleList = roleMapper.selectList();
-            log.info("[initLocalCacheIfUpdate][缓存角色,数量为:{}]", roleList.size());
+            log.info("[initLocalCache][缓存角色,数量为:{}]", roleList.size());
 
-            // 第二步:构建缓存
+            // 第二步:构建缓存
             roleCache = CollectionUtils.convertMap(roleList, RoleDO::getId);
-
-            // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-            this.maxUpdateTime = CollectionUtils.getMaxValue(roleList, RoleDO::getUpdateTime);
         });
     }
 

+ 3 - 42
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java

@@ -17,13 +17,11 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-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.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -40,12 +38,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_
 @Validated
 public class SensitiveWordServiceImpl implements SensitiveWordService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 敏感词标签缓存
      * key:敏感词编号 {@link SensitiveWordDO#getId()}
@@ -55,12 +47,6 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
     @Getter
     private volatile Set<String> sensitiveWordTagsCache = Collections.emptySet();
 
-    /**
-     * 缓存敏感词的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    @Getter
-    private volatile LocalDateTime maxUpdateTime;
-
     @Resource
     private SensitiveWordMapper sensitiveWordMapper;
 
@@ -84,42 +70,17 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
     @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) {
-        // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-        // 如果没有增量的数据变化,则不进行本地缓存的刷新
-        if (maxUpdateTime != null
-                && sensitiveWordMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-            log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-            return;
-        }
+        // 第一步:查询数据
         List<SensitiveWordDO> sensitiveWords = sensitiveWordMapper.selectList();
-        log.info("[initLocalCacheIfUpdate][缓存敏感词,数量为:{}]", sensitiveWords.size());
+        log.info("[initLocalCache][缓存敏感词,数量为:{}]", sensitiveWords.size());
 
-        // 第二步:构建缓存
+        // 第二步:构建缓存
         // 写入 sensitiveWordTagsCache 缓存
         Set<String> tags = new HashSet<>();
         sensitiveWords.forEach(word -> tags.addAll(word.getTags()));
         sensitiveWordTagsCache = tags;
         // 写入 defaultSensitiveWordTrie、tagSensitiveWordTries 缓存
         initSensitiveWordTrie(sensitiveWords);
-
-        // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-        this.maxUpdateTime = CollectionUtils.getMaxValue(sensitiveWords, SensitiveWordDO::getUpdateTime);
     }
 
     private void initSensitiveWordTrie(List<SensitiveWordDO> wordDOs) {

+ 3 - 42
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java

@@ -11,17 +11,14 @@ import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
 import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
 
@@ -34,17 +31,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNE
 @Slf4j
 public class SmsChannelServiceImpl implements SmsChannelService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
-    /**
-     * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    private volatile LocalDateTime maxUpdateTime;
-
     @Resource
     private SmsClientFactory smsClientFactory;
 
@@ -60,38 +46,13 @@ public class SmsChannelServiceImpl implements SmsChannelService {
     @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) {
-        // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
-        // 如果没有增量的数据变化,则不进行本地缓存的刷新
-        if (maxUpdateTime != null
-                && smsChannelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-            log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
-            return;
-        }
+        // 第一步:查询数据
         List<SmsChannelDO> channels = smsChannelMapper.selectList();
-        log.info("[initLocalCacheIfUpdate][缓存短信渠道,数量为:{}]", channels.size());
+        log.info("[initLocalCache][缓存短信渠道,数量为:{}]", channels.size());
 
-        // 第二步:构建缓存创建或更新短信 Client
+        // 第二步:构建缓存:创建或更新短信 Client
         List<SmsChannelProperties> propertiesList = SmsChannelConvert.INSTANCE.convertList02(channels);
         propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties));
-
-        // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
-        this.maxUpdateTime = getMaxValue(channels, SmsChannelDO::getUpdateTime);
     }
 
     @Override

+ 10 - 48
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.system.service.sms;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ReUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -20,15 +19,17 @@ import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper;
 import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
 import com.google.common.annotations.VisibleForTesting;
+import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.regex.Pattern;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -44,12 +45,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 @Slf4j
 public class SmsTemplateServiceImpl implements SmsTemplateService {
 
-    /**
-     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
-     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
-     */
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
     /**
      * 正则表达式,匹配 {} 中的变量
      */
@@ -73,51 +68,18 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter // 为了方便测试,这里提供 getter 方法
     private volatile Map<String, SmsTemplateDO> smsTemplateCache;
-    /**
-     * 缓存短信模板的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    private volatile LocalDateTime maxUpdateTime;
 
     @Override
     @PostConstruct
     public void initLocalCache() {
-        // 获取短信模板列表,如果有更新
-        List<SmsTemplateDO> smsTemplateList = this.loadSmsTemplateIfUpdate(maxUpdateTime);
-        if (CollUtil.isEmpty(smsTemplateList)) {
-            return;
-        }
+        // 第一步:查询数据
+        List<SmsTemplateDO> smsTemplateList = smsTemplateMapper.selectList();
+        log.info("[initLocalCache][缓存短信模版,数量为:{}]", smsTemplateList.size());
 
-        // 写入缓存
+        // 第二步:构建缓存
         smsTemplateCache = CollectionUtils.convertMap(smsTemplateList, SmsTemplateDO::getCode);
-        maxUpdateTime = CollectionUtils.getMaxValue(smsTemplateList, SmsTemplateDO::getUpdateTime);
-        log.info("[initLocalCache][初始化 SmsTemplate 数量为 {}]", smsTemplateList.size());
-    }
-
-    /**
-     * 如果短信模板发生变化,从数据库中获取最新的全量短信模板。
-     * 如果未发生变化,则返回空
-     *
-     * @param maxUpdateTime 当前短信模板的最大更新时间
-     * @return 短信模板列表
-     */
-    private List<SmsTemplateDO> loadSmsTemplateIfUpdate(LocalDateTime maxUpdateTime) {
-        // 第一步,判断是否要更新。
-        if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
-            log.info("[loadSmsTemplateIfUpdate][首次加载全量短信模板]");
-        } else { // 判断数据库中是否有更新的短信模板
-            if (smsTemplateMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                return null;
-            }
-            log.info("[loadSmsTemplateIfUpdate][增量加载全量短信模板]");
-        }
-        // 第二步,如果有更新,则从数据库加载所有短信模板
-        return smsTemplateMapper.selectList();
-    }
-
-    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
-    public void schedulePeriodicRefresh() {
-        initLocalCache();
     }
 
     @Override

+ 1 - 4
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java

@@ -5,8 +5,6 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
@@ -16,7 +14,7 @@ import cn.iocoder.yudao.module.system.service.member.MemberService;
 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
-import com.anji.captcha.service.CaptchaService;
+import com.xingyuv.captcha.service.CaptchaService;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
@@ -25,7 +23,6 @@ import javax.annotation.Resource;
 import javax.validation.Validator;
 
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
-import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

+ 7 - 13
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java

@@ -1,7 +1,10 @@
 package cn.iocoder.yudao.module.system.service.dept;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO;
@@ -9,9 +12,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
 import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
 import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
-import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import com.google.common.collect.Multimap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -19,17 +19,15 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Consumer;
 
-import static cn.hutool.core.bean.BeanUtil.getFieldValue;
 import static cn.hutool.core.util.RandomUtil.randomEle;
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -56,8 +54,7 @@ public class DeptServiceTest extends BaseDbUnitTest {
     }
 
     @Test
-    @SuppressWarnings("unchecked")
-    void testInitLocalCache() {
+    public void testInitLocalCache() {
         // mock 数据
         DeptDO deptDO1 = randomDeptDO();
         deptMapper.insert(deptDO1);
@@ -67,18 +64,15 @@ public class DeptServiceTest extends BaseDbUnitTest {
         // 调用
         deptService.initLocalCache();
         // 断言 deptCache 缓存
-        Map<Long, DeptDO> deptCache = (Map<Long, DeptDO>) getFieldValue(deptService, "deptCache");
+        Map<Long, DeptDO> deptCache = deptService.getDeptCache();
         assertEquals(2, deptCache.size());
         assertPojoEquals(deptDO1, deptCache.get(deptDO1.getId()));
         assertPojoEquals(deptDO2, deptCache.get(deptDO2.getId()));
         // 断言 parentDeptCache 缓存
-        Multimap<Long, DeptDO> parentDeptCache = (Multimap<Long, DeptDO>) getFieldValue(deptService, "parentDeptCache");
+        Multimap<Long, DeptDO> parentDeptCache = deptService.getParentDeptCache();
         assertEquals(2, parentDeptCache.size());
         assertPojoEquals(deptDO1, parentDeptCache.get(deptDO1.getParentId()));
         assertPojoEquals(deptDO2, parentDeptCache.get(deptDO2.getParentId()));
-        // 断言 maxUpdateTime 缓存
-        LocalDateTime maxUpdateTime = (LocalDateTime) getFieldValue(deptService, "maxUpdateTime");
-        assertEquals(ObjectUtils.max(deptDO1.getUpdateTime(), deptDO2.getUpdateTime()), maxUpdateTime);
     }
 
     @Test

+ 0 - 3
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java

@@ -19,7 +19,6 @@ import java.util.Collections;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
@@ -59,8 +58,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
         assertEquals(2, clientCache.size());
         assertPojoEquals(clientDO1, clientCache.get(clientDO1.getClientId()));
         assertPojoEquals(clientDO2, clientCache.get(clientDO2.getClientId()));
-        // 断言 maxUpdateTime 缓存
-        assertEquals(max(clientDO1.getUpdateTime(), clientDO2.getUpdateTime()), oauth2ClientService.getMaxUpdateTime());
     }
 
     @Test

+ 7 - 17
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.permission;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
@@ -20,7 +19,6 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
@@ -51,32 +49,24 @@ public class MenuServiceTest extends BaseDbUnitTest {
     private TenantService tenantService;
 
     @Test
-    public void testInitLocalCache_success() throws Exception {
-        MenuDO menuDO1 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
+    public void testInitLocalCache_success() {
+        MenuDO menuDO1 = randomPojo(MenuDO.class);
         menuMapper.insert(menuDO1);
-        MenuDO menuDO2 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
+        MenuDO menuDO2 = randomPojo(MenuDO.class);
         menuMapper.insert(menuDO2);
 
         // 调用
         menuService.initLocalCache();
-
-        // 获取代理对象
-        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService);
-
-        Map<Long, MenuDO> menuCache =
-                (Map<Long, MenuDO>) BeanUtil.getFieldValue(target, "menuCache");
+        // 校验 menuCache 缓存
+        Map<Long, MenuDO> menuCache = menuService.getMenuCache();
         Assert.isTrue(menuCache.size() == 2);
         assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId()));
         assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId()));
-
-        Multimap<String, MenuDO> permissionMenuCache =
-                (Multimap<String, MenuDO>) BeanUtil.getFieldValue(target, "permissionMenuCache");
+        // 校验 permissionMenuCache 缓存
+        Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache();
         Assert.isTrue(permissionMenuCache.size() == 2);
         assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission()));
         assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission()));
-
-        LocalDateTime maxUpdateTime = (LocalDateTime) BeanUtil.getFieldValue(target, "maxUpdateTime");
-        assertEquals(ObjectUtils.max(menuDO1.getUpdateTime(), menuDO2.getUpdateTime()), maxUpdateTime);
     }
 
     @Test

+ 10 - 22
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java

@@ -3,18 +3,15 @@ package cn.iocoder.yudao.module.system.service.permission;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
-import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
-import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
@@ -27,8 +24,10 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@@ -42,8 +41,7 @@ import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@Import({PermissionServiceImpl.class,
-        RoleMenuBatchInsertMapper.class, UserRoleBatchInsertMapper.class})
+@Import({PermissionServiceImpl.class})
 public class PermissionServiceTest extends BaseDbUnitTest {
 
     @Resource
@@ -52,11 +50,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
     @Resource
     private RoleMenuMapper roleMenuMapper;
     @Resource
-    private RoleMenuBatchInsertMapper roleMenuBatchInsertMapper;
-    @Resource
     private UserRoleMapper userRoleMapper;
-    @Resource
-    private UserRoleBatchInsertMapper userRoleBatchInsertMapper;
 
     @MockBean
     private RoleService roleService;
@@ -71,7 +65,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
     private PermissionProducer permissionProducer;
 
     @Test
-    public void testInitLocalCacheIfUpdateForRoleMenu() {
+    public void testInitLocalCacheForRoleMenu() {
         // mock 数据
         RoleMenuDO roleMenuDO01 = randomPojo(RoleMenuDO.class, o -> o.setRoleId(1L).setMenuId(10L));
         roleMenuMapper.insert(roleMenuDO01);
@@ -79,7 +73,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
         roleMenuMapper.insert(roleMenuDO02);
 
         // 调用
-        permissionService.initLocalCacheIfUpdateForRoleMenu(null);
+        permissionService.initLocalCacheForRoleMenu();
         // 断言 roleMenuCache 缓存
         assertEquals(1, permissionService.getRoleMenuCache().keySet().size());
         assertEquals(asList(10L, 20L), permissionService.getRoleMenuCache().get(1L));
@@ -87,13 +81,10 @@ public class PermissionServiceTest extends BaseDbUnitTest {
         assertEquals(2, permissionService.getMenuRoleCache().size());
         assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(10L));
         assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(20L));
-        // 断言 maxUpdateTime 缓存
-        LocalDateTime maxUpdateTime = permissionService.getRoleMenuMaxUpdateTime();
-        assertEquals(ObjectUtils.max(roleMenuDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime);
     }
 
     @Test
-    public void testInitLocalCacheIfUpdateForUserRole() {
+    public void testInitLocalCacheForUserRole() {
         // mock 数据
         UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
         userRoleMapper.insert(userRoleDO01);
@@ -101,13 +92,10 @@ public class PermissionServiceTest extends BaseDbUnitTest {
         userRoleMapper.insert(roleMenuDO02);
 
         // 调用
-        permissionService.initLocalCacheIfUpdateForUserRole(null);
+        permissionService.initLocalCacheForUserRole();
         // 断言 roleMenuCache 缓存
         assertEquals(1, permissionService.getUserRoleCache().size());
         assertEquals(asSet(10L, 20L), permissionService.getUserRoleCache().get(1L));
-        // 断言 maxUpdateTime 缓存
-        LocalDateTime maxUpdateTime = permissionService.getUserRoleMaxUpdateTime();
-        assertEquals(ObjectUtils.max(userRoleDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime);
     }
 
     @Test

+ 0 - 3
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java

@@ -23,7 +23,6 @@ import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
@@ -59,8 +58,6 @@ public class RoleServiceTest extends BaseDbUnitTest {
         Map<Long, RoleDO> roleCache = roleService.getRoleCache();
         assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId()));
         assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId()));
-        // 断言 maxUpdateTime 缓存
-        assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), roleService.getMaxUpdateTime());
     }
 
     @Test

+ 0 - 2
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java

@@ -60,8 +60,6 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
 
         // 调用
         sensitiveWordService.initLocalCache();
-        // 断言 maxUpdateTime 缓存
-        assertEquals(max(wordDO1.getUpdateTime(), wordDO2.getUpdateTime()), sensitiveWordService.getMaxUpdateTime());
         // 断言 sensitiveWordTagsCache 缓存
         assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTags());
         // 断言 tagSensitiveWordTries 缓存

+ 8 - 13
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java

@@ -1,18 +1,17 @@
 package cn.iocoder.yudao.module.system.service.sms;
 
-import cn.hutool.core.bean.BeanUtil;
-import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelUpdateReqVO;
-import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
-import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
-import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelUpdateReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
+import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
+import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
@@ -22,12 +21,11 @@ import java.time.LocalDateTime;
 import java.util.function.Consumer;
 
 import static cn.hutool.core.util.RandomUtil.randomEle;
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.*;
@@ -58,9 +56,6 @@ public class SmsChannelServiceTest extends BaseDbUnitTest {
 
         // 调用
         smsChannelService.initLocalCache();
-        // 校验 maxUpdateTime 属性
-        LocalDateTime maxUpdateTime = (LocalDateTime) BeanUtil.getFieldValue(smsChannelService, "maxUpdateTime");
-        assertEquals(max(smsChannelDO01.getUpdateTime(), smsChannelDO02.getUpdateTime()), maxUpdateTime);
         // 校验调用
         verify(smsClientFactory, times(1)).createOrUpdateSmsClient(
                 argThat(properties -> isPojoEquals(smsChannelDO01, properties)));

+ 1 - 5
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java

@@ -61,7 +61,6 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
     private SmsProducer smsProducer;
 
     @Test
-    @SuppressWarnings("unchecked")
     void testInitLocalCache() {
         // mock 数据
         SmsTemplateDO smsTemplate01 = randomSmsTemplateDO();
@@ -72,13 +71,10 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
         // 调用
         smsTemplateService.initLocalCache();
         // 断言 deptCache 缓存
-        Map<String, SmsTemplateDO> smsTemplateCache = (Map<String, SmsTemplateDO>) getFieldValue(smsTemplateService, "smsTemplateCache");
+        Map<String, SmsTemplateDO> smsTemplateCache = smsTemplateService.getSmsTemplateCache();
         assertEquals(2, smsTemplateCache.size());
         assertPojoEquals(smsTemplate01, smsTemplateCache.get(smsTemplate01.getCode()));
         assertPojoEquals(smsTemplate02, smsTemplateCache.get(smsTemplate02.getCode()));
-        // 断言 maxUpdateTime 缓存
-        LocalDateTime maxUpdateTime = (LocalDateTime) getFieldValue(smsTemplateService, "maxUpdateTime");
-        assertEquals(max(smsTemplate01.getUpdateTime(), smsTemplate02.getUpdateTime()), maxUpdateTime);
     }
 
     @Test