Commit c744e115e3c20af79c2f98b0d2080c7210f7cfa0

Authored by YunaiV
1 parent 0763c720

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

Showing 37 changed files with 111 additions and 657 deletions
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> {
81 81 }
82 82  
83 83 /**
84   - * 逐条插入,适合少量数据插入,或者对性能要求不高的场景
85   - * <p>
86   - * 如果大量,请使用 {@link com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch(Collection)} 方法
87   - * 使用示例,可见 RoleMenuBatchInsertMapper、UserRoleBatchInsertMapper 类
  84 + * 批量插入,适合大量数据插入
88 85 *
89 86 * @param entities 实体们
90 87 */
91 88 default void insertBatch(Collection<T> entities) {
92   - entities.forEach(this::insert);
  89 + Db.saveBatch(entities);
93 90 }
94 91  
95 92 /**
96 93 * 批量插入,适合大量数据插入
97 94 *
98 95 * @param entities 实体们
99   - * @param size 插入数量 Db.saveBatch 默认为1000
  96 + * @param size 插入数量 Db.saveBatch 默认为 1000
100 97 */
101 98 default void insertBatch(Collection<T> entities, int size) {
102 99 Db.saveBatch(entities, size);
... ...
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;
6 6 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
7 7 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9   -import org.apache.ibatis.annotations.Select;
10 9  
11   -import java.time.LocalDateTime;
12   -
13   -/**
14   - * 文件配置 Mapper
15   - *
16   - * @author 芋道源码
17   - */
18 10 @Mapper
19 11 public interface FileConfigMapper extends BaseMapperX<FileConfigDO> {
20 12  
... ... @@ -26,7 +18,4 @@ public interface FileConfigMapper extends BaseMapperX&lt;FileConfigDO&gt; {
26 18 .orderByDesc(FileConfigDO::getId));
27 19 }
28 20  
29   - @Select("SELECT COUNT(*) FROM infra_file_config WHERE update_time > #{maxUpdateTime}")
30   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
31   -
32 21 }
... ...
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&lt;Fi
23 23 @Override
24 24 public void onMessage(FileConfigRefreshMessage message) {
25 25 log.info("[onMessage][收到 FileConfig 刷新消息]");
26   - fileConfigService.initFileClients();
  26 + fileConfigService.initLocalCache();
27 27 }
28 28  
29 29 }
... ...
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 {
21 21 /**
22 22 * 初始化文件客户端
23 23 */
24   - void initFileClients();
  24 + void initLocalCache();
25 25  
26 26 /**
27 27 * 创建文件配置
... ...
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;
3 3 import cn.hutool.core.io.resource.ResourceUtil;
4 4 import cn.hutool.core.util.IdUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 7 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
9 8 import cn.iocoder.yudao.framework.file.core.client.FileClient;
... ... @@ -19,7 +18,6 @@ import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
19 18 import cn.iocoder.yudao.module.infra.mq.producer.file.FileConfigProducer;
20 19 import lombok.Getter;
21 20 import lombok.extern.slf4j.Slf4j;
22   -import org.springframework.scheduling.annotation.Scheduled;
23 21 import org.springframework.stereotype.Service;
24 22 import org.springframework.transaction.annotation.Transactional;
25 23 import org.springframework.transaction.support.TransactionSynchronization;
... ... @@ -29,7 +27,6 @@ import org.springframework.validation.annotation.Validated;
29 27 import javax.annotation.PostConstruct;
30 28 import javax.annotation.Resource;
31 29 import javax.validation.Validator;
32   -import java.time.LocalDateTime;
33 30 import java.util.Collection;
34 31 import java.util.List;
35 32 import java.util.Map;
... ... @@ -48,18 +45,6 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_CONFIG
48 45 @Slf4j
49 46 public class FileConfigServiceImpl implements FileConfigService {
50 47  
51   - /**
52   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
53   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
54   - */
55   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
56   -
57   - /**
58   - * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
59   - */
60   - @Getter
61   - private volatile LocalDateTime maxUpdateTime;
62   -
63 48 @Resource
64 49 private FileClientFactory fileClientFactory;
65 50 /**
... ... @@ -79,34 +64,12 @@ public class FileConfigServiceImpl implements FileConfigService {
79 64  
80 65 @Override
81 66 @PostConstruct
82   - public void initFileClients() {
83   - initLocalCacheIfUpdate(null);
84   - }
85   -
86   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
87   - public void schedulePeriodicRefresh() {
88   - initLocalCacheIfUpdate(this.maxUpdateTime);
89   - }
90   -
91   - /**
92   - * 刷新本地缓存
93   - *
94   - * @param maxUpdateTime 最大更新时间
95   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
96   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
97   - */
98   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
99   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
100   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
101   - if (maxUpdateTime != null
102   - && fileConfigMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
103   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
104   - return;
105   - }
  67 + public void initLocalCache() {
  68 + // 第一步:查询数据
106 69 List<FileConfigDO> configs = fileConfigMapper.selectList();
107   - log.info("[initLocalCacheIfUpdate][缓存文件配置,数量为:{}]", configs.size());
  70 + log.info("[initLocalCache][缓存文件配置,数量为:{}]", configs.size());
108 71  
109   - // 第二步:构建缓存。创建或更新文件 Client
  72 + // 第二步:构建缓存:创建或更新文件 Client
110 73 configs.forEach(config -> {
111 74 fileClientFactory.createOrUpdateFileClient(config.getId(), config.getStorage(), config.getConfig());
112 75 // 如果是 master,进行设置
... ... @@ -114,9 +77,6 @@ public class FileConfigServiceImpl implements FileConfigService {
114 77 masterFileClient = fileClientFactory.getFileClient(config.getId());
115 78 }
116 79 });
117   -
118   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
119   - this.maxUpdateTime = CollectionUtils.getMaxValue(configs, FileConfigDO::getUpdateTime);
120 80 }
121 81  
122 82 @Override
... ...
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;
30 30 import static cn.hutool.core.util.RandomUtil.randomEle;
31 31 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
32 32 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
33   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
34 33 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
35 34 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
36 35 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
... ... @@ -74,16 +73,13 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
74 73 when(fileClientFactory.getFileClient(eq(1L))).thenReturn(masterFileClient);
75 74  
76 75 // 调用
77   - fileConfigService.initFileClients();
  76 + fileConfigService.initLocalCache();
78 77 // 断言 fileClientFactory 调用
79 78 verify(fileClientFactory).createOrUpdateFileClient(eq(1L),
80 79 eq(configDO1.getStorage()), eq(configDO1.getConfig()));
81 80 verify(fileClientFactory).createOrUpdateFileClient(eq(2L),
82 81 eq(configDO2.getStorage()), eq(configDO2.getConfig()));
83 82 assertSame(masterFileClient, fileConfigService.getMasterFileClient());
84   - // 断言 maxUpdateTime 缓存
85   - assertEquals(max(configDO1.getUpdateTime(), configDO2.getUpdateTime()),
86   - fileConfigService.getMaxUpdateTime());
87 83 }
88 84  
89 85 @Test
... ...
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
8 8 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
9 9 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
10 10 import org.apache.ibatis.annotations.Mapper;
11   -import org.apache.ibatis.annotations.Select;
12 11  
13   -import java.time.LocalDateTime;
14 12 import java.util.Collection;
15 13 import java.util.List;
16 14  
... ... @@ -21,9 +19,6 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; {
21 19 return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
22 20 }
23 21  
24   - @Select("SELECT COUNT(*) FROM pay_channel WHERE update_time > #{maxUpdateTime}")
25   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
26   -
27 22 default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
28 23 return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
29 24 .eqIfPresent("code", reqVO.getCode())
... ... @@ -67,14 +62,14 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; {
67 62 * 根据条件获取渠道
68 63 *
69 64 * @param merchantId 商户编号
70   - * @param appid 应用编号 // TODO @aquan:appid =》appId
  65 + * @param appI 应用编号
71 66 * @param code 渠道编码
72 67 * @return 数量
73 68 */
74   - default PayChannelDO selectOne(Long merchantId, Long appid, String code) {
  69 + default PayChannelDO selectOne(Long merchantId, Long appI, String code) {
75 70 return this.selectOne((new QueryWrapper<PayChannelDO>().lambda()
76 71 .eq(PayChannelDO::getMerchantId, merchantId)
77   - .eq(PayChannelDO::getAppId, appid)
  72 + .eq(PayChannelDO::getAppId, appI)
78 73 .eq(PayChannelDO::getCode, code)
79 74 ));
80 75 }
... ...
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;
5 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 6 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
7 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9 8 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
10 9 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
11 10 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
... ... @@ -19,7 +18,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
19 18 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayChannelMapper;
20 19 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
21 20 import lombok.extern.slf4j.Slf4j;
22   -import org.springframework.scheduling.annotation.Scheduled;
23 21 import org.springframework.stereotype.Service;
24 22 import org.springframework.validation.annotation.Validated;
25 23  
... ... @@ -45,12 +43,6 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_E
45 43 public class PayChannelServiceImpl implements PayChannelService {
46 44  
47 45 /**
48   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
49   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
50   - */
51   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
52   -
53   - /**
54 46 * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
55 47 */
56 48 private volatile LocalDateTime maxUpdateTime;
... ... @@ -70,40 +62,15 @@ public class PayChannelServiceImpl implements PayChannelService {
70 62 @Override
71 63 @PostConstruct
72 64 public void initLocalCache() {
73   - initLocalCacheIfUpdate(null);
74   - }
75   -
76   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
77   - public void schedulePeriodicRefresh() {
78   - initLocalCacheIfUpdate(this.maxUpdateTime);
79   - }
80   -
81   - /**
82   - * 刷新本地缓存
83   - *
84   - * @param maxUpdateTime 最大更新时间
85   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
86   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
87   - */
88   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
89 65 // 注意:忽略自动多租户,因为要全局初始化缓存
90 66 TenantUtils.executeIgnore(() -> {
91   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
92   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
93   - if (maxUpdateTime != null
94   - && channelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
95   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
96   - return;
97   - }
  67 + // 第一步:查询数据
98 68 List<PayChannelDO> channels = channelMapper.selectList();
99   - log.info("[initLocalCacheIfUpdate][缓存支付渠道,数量为:{}]", channels.size());
  69 + log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size());
100 70  
101   - // 第二步:构建缓存。创建或更新支付 Client
  71 + // 第二步:构建缓存:创建或更新支付 Client
102 72 channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
103 73 payChannel.getCode(), payChannel.getConfig()));
104   -
105   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
106   - this.maxUpdateTime = CollectionUtils.getMaxValue(channels, PayChannelDO::getUpdateTime);
107 74 });
108 75 }
109 76  
... ...
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
6 6 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
7 7 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 8 import org.apache.ibatis.annotations.Mapper;
9   -import org.apache.ibatis.annotations.Select;
10 9  
11   -import java.time.LocalDateTime;
12 10 import java.util.List;
13 11  
14 12 @Mapper
... ... @@ -30,7 +28,4 @@ public interface DeptMapper extends BaseMapperX&lt;DeptDO&gt; {
30 28 return selectCount(DeptDO::getParentId, parentId);
31 29 }
32 30  
33   - @Select("SELECT COUNT(*) FROM system_dept WHERE update_time > #{maxUpdateTime}")
34   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
35   -
36 31 }
... ...
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;
6 6 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2ClientPageReqVO;
7 7 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9   -import org.apache.ibatis.annotations.Select;
10   -
11   -import java.time.LocalDateTime;
12 9  
13 10  
14 11 /**
... ... @@ -30,7 +27,4 @@ public interface OAuth2ClientMapper extends BaseMapperX&lt;OAuth2ClientDO&gt; {
30 27 return selectOne(OAuth2ClientDO::getClientId, clientId);
31 28 }
32 29  
33   - @Select("SELECT COUNT(*) FROM system_oauth2_client WHERE update_time > #{maxUpdateTime}")
34   - int selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
35   -
36 30 }
... ...
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
6 6 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
7 7 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 8 import org.apache.ibatis.annotations.Mapper;
9   -import org.apache.ibatis.annotations.Select;
10 9  
11   -import java.time.LocalDateTime;
12 10 import java.util.List;
13 11  
14 12 @Mapper
... ... @@ -28,7 +26,4 @@ public interface MenuMapper extends BaseMapperX&lt;MenuDO&gt; {
28 26 .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
29 27 }
30 28  
31   - @Select("SELECT COUNT(*) FROM system_menu WHERE update_time > #{maxUpdateTime}")
32   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
33   -
34 29 }
... ...
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
8 8 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
9 9 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
10 10 import org.apache.ibatis.annotations.Mapper;
11   -import org.apache.ibatis.annotations.Select;
12 11 import org.springframework.lang.Nullable;
13 12  
14   -import java.time.LocalDateTime;
15 13 import java.util.Collection;
16 14 import java.util.List;
17 15  
... ... @@ -47,7 +45,4 @@ public interface RoleMapper extends BaseMapperX&lt;RoleDO&gt; {
47 45 return selectList(RoleDO::getStatus, statuses);
48 46 }
49 47  
50   - @Select("SELECT COUNT(*) FROM system_role WHERE update_time > #{maxUpdateTime}")
51   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
52   -
53 48 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuBatchInsertMapper.java deleted
1   -package cn.iocoder.yudao.module.system.dal.mysql.permission;
2   -
3   -import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
4   -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
5   -import org.springframework.stereotype.Repository;
6   -
7   -/**
8   - * 实体 {@link RoleMenuDO} 的批量插入 Mapper
9   - *
10   - * @author 芋道源码
11   - */
12   -@Repository
13   -public class RoleMenuBatchInsertMapper extends ServiceImpl<RoleMenuMapper, RoleMenuDO> {
14   -}
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;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
5   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 6 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 7 import org.apache.ibatis.annotations.Mapper;
8   -import org.apache.ibatis.annotations.Select;
9 8 import org.springframework.stereotype.Repository;
10 9  
11   -import java.time.LocalDateTime;
12 10 import java.util.Collection;
13 11 import java.util.List;
14 12  
... ... @@ -20,23 +18,21 @@ public interface RoleMenuMapper extends BaseMapperX&lt;RoleMenuDO&gt; {
20 18 }
21 19  
22 20 default List<RoleMenuDO> selectListByRoleId(Long roleId) {
23   - return selectList(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
  21 + return selectList(RoleMenuDO::getRoleId, roleId);
24 22 }
25 23  
26 24 default void deleteListByRoleIdAndMenuIds(Long roleId, Collection<Long> menuIds) {
27   - delete(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId)
28   - .in("menu_id", menuIds));
  25 + delete(new LambdaQueryWrapper<RoleMenuDO>()
  26 + .eq(RoleMenuDO::getRoleId, roleId)
  27 + .in(RoleMenuDO::getMenuId, menuIds));
29 28 }
30 29  
31 30 default void deleteListByMenuId(Long menuId) {
32   - delete(new QueryWrapper<RoleMenuDO>().eq("menu_id", menuId));
  31 + delete(new LambdaQueryWrapper<RoleMenuDO>().eq(RoleMenuDO::getMenuId, menuId));
33 32 }
34 33  
35 34 default void deleteListByRoleId(Long roleId) {
36   - delete(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
  35 + delete(new LambdaQueryWrapper<RoleMenuDO>().eq(RoleMenuDO::getRoleId, roleId));
37 36 }
38 37  
39   - @Select("SELECT COUNT(*) FROM system_role_menu WHERE update_time > #{maxUpdateTime}")
40   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
41   -
42 38 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleBatchInsertMapper.java deleted
1   -package cn.iocoder.yudao.module.system.dal.mysql.permission;
2   -
3   -import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
4   -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
5   -import org.springframework.stereotype.Repository;
6   -
7   -/**
8   - * 实体 {@link UserRoleDO} 的批量插入 Mapper
9   - *
10   - * @author 芋道源码
11   - */
12   -@Repository
13   -public class UserRoleBatchInsertMapper extends ServiceImpl<UserRoleMapper, UserRoleDO> {
14   -}
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;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
5   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 6 import org.apache.ibatis.annotations.Mapper;
7   -import org.apache.ibatis.annotations.Select;
8 7  
9   -import java.time.LocalDateTime;
10 8 import java.util.Collection;
11 9 import java.util.List;
12 10  
... ... @@ -14,32 +12,25 @@ import java.util.List;
14 12 public interface UserRoleMapper extends BaseMapperX<UserRoleDO> {
15 13  
16 14 default List<UserRoleDO> selectListByUserId(Long userId) {
17   - return selectList(new QueryWrapper<UserRoleDO>().eq("user_id", userId));
18   - }
19   -
20   - default List<UserRoleDO> selectListByRoleId(Long roleId) {
21   - return selectList(new QueryWrapper<UserRoleDO>().eq("role_id", roleId));
  15 + return selectList(UserRoleDO::getUserId, userId);
22 16 }
23 17  
24 18 default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {
25   - delete(new QueryWrapper<UserRoleDO>().eq("user_id", userId)
26   - .in("role_id", roleIds));
  19 + delete(new LambdaQueryWrapper<UserRoleDO>()
  20 + .eq(UserRoleDO::getUserId, userId)
  21 + .in(UserRoleDO::getRoleId, roleIds));
27 22 }
28 23  
29 24 default void deleteListByUserId(Long userId) {
30   - delete(new QueryWrapper<UserRoleDO>().eq("user_id", userId));
  25 + delete(new LambdaQueryWrapper<UserRoleDO>().eq(UserRoleDO::getUserId, userId));
31 26 }
32 27  
33 28 default void deleteListByRoleId(Long roleId) {
34   - delete(new QueryWrapper<UserRoleDO>().eq("role_id", roleId));
  29 + delete(new LambdaQueryWrapper<UserRoleDO>().eq(UserRoleDO::getRoleId, roleId));
35 30 }
36 31  
37   -
38 32 default List<UserRoleDO> selectListByRoleIds(Collection<Long> roleIds) {
39 33 return selectList(UserRoleDO::getRoleId, roleIds);
40 34 }
41 35  
42   - @Select("SELECT COUNT(*) FROM system_user_role WHERE update_time > #{maxUpdateTime}")
43   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
44   -
45 36 }
... ...
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
7 7 import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
8 8 import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10   -import org.apache.ibatis.annotations.Select;
11 10  
12   -import java.time.LocalDateTime;
13 11 import java.util.List;
14 12  
15 13 /**
... ... @@ -42,7 +40,4 @@ public interface SensitiveWordMapper extends BaseMapperX&lt;SensitiveWordDO&gt; {
42 40 return selectOne(SensitiveWordDO::getName, name);
43 41 }
44 42  
45   - @Select("SELECT COUNT(*) FROM system_sensitive_word WHERE update_time > #{maxUpdateTime}")
46   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
47   -
48 43 }
... ...
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;
6 6 import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
7 7 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9   -import org.apache.ibatis.annotations.Select;
10   -
11   -import java.time.LocalDateTime;
12 9  
13 10 @Mapper
14 11 public interface SmsChannelMapper extends BaseMapperX<SmsChannelDO> {
... ... @@ -21,7 +18,4 @@ public interface SmsChannelMapper extends BaseMapperX&lt;SmsChannelDO&gt; {
21 18 .orderByDesc(SmsChannelDO::getId));
22 19 }
23 20  
24   - @Select("SELECT COUNT(*) FROM system_sms_channel WHERE update_time > #{maxUpdateTime}")
25   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
26   -
27 21 }
... ...
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
7 7 import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
8 8 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10   -import org.apache.ibatis.annotations.Select;
11 10  
12   -import java.time.LocalDateTime;
13 11 import java.util.List;
14 12  
15 13 @Mapper
16 14 public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
17 15  
18   - @Select("SELECT COUNT(*) FROM system_sms_template WHERE update_time > #{maxUpdateTime}")
19   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
20   -
21 16 default SmsTemplateDO selectByCode(String code) {
22 17 return selectOne(SmsTemplateDO::getCode, code);
23 18 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java
1 1 package cn.iocoder.yudao.module.system.dal.mysql.tenant;
2 2  
3   -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
4   -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
5   -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
6 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
8 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
  7 +import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10   -import org.apache.ibatis.annotations.Select;
11 10  
12   -import java.time.LocalDateTime;
13 11 import java.util.List;
14 12  
15 13 /**
... ... @@ -52,7 +50,4 @@ public interface TenantMapper extends BaseMapperX&lt;TenantDO&gt; {
52 50 return selectList(TenantDO::getPackageId, packageId);
53 51 }
54 52  
55   - @Select("SELECT COUNT(*) FROM system_tenant WHERE update_time > #{maxUpdateTime}")
56   - Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
57   -
58 53 }
... ...
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;
17 17 import com.google.common.collect.ImmutableMap;
18 18 import com.google.common.collect.ImmutableMultimap;
19 19 import com.google.common.collect.Multimap;
  20 +import lombok.Getter;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.springframework.scheduling.annotation.Scheduled;
22 23 import org.springframework.stereotype.Service;
... ... @@ -41,18 +42,12 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
41 42 public class DeptServiceImpl implements DeptService {
42 43  
43 44 /**
44   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
45   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
46   - */
47   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
48   -
49   - /**
50 45 * 部门缓存
51 46 * key:部门编号 {@link DeptDO#getId()}
52 47 *
53 48 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
54 49 */
55   - @SuppressWarnings("FieldCanBeLocal")
  50 + @Getter
56 51 private volatile Map<Long, DeptDO> deptCache;
57 52 /**
58 53 * 父部门缓存
... ... @@ -61,11 +56,8 @@ public class DeptServiceImpl implements DeptService {
61 56 *
62 57 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
63 58 */
  59 + @Getter
64 60 private volatile Multimap<Long, DeptDO> parentDeptCache;
65   - /**
66   - * 缓存部门的最大更新时间,用于后续的增量轮询,判断是否有更新
67   - */
68   - private volatile LocalDateTime maxUpdateTime;
69 61  
70 62 @Resource
71 63 private DeptMapper deptMapper;
... ... @@ -79,48 +71,21 @@ public class DeptServiceImpl implements DeptService {
79 71 @Override
80 72 @PostConstruct
81 73 public synchronized void initLocalCache() {
82   - initLocalCacheIfUpdate(null);
83   - }
84   -
85   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
86   - public void schedulePeriodicRefresh() {
87   - initLocalCacheIfUpdate(this.maxUpdateTime);
88   - }
89   -
90   - /**
91   - * 刷新本地缓存
92   - *
93   - * @param maxUpdateTime 最大更新时间
94   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
95   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
96   - */
97   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
98 74 // 注意:忽略自动多租户,因为要全局初始化缓存
99 75 TenantUtils.executeIgnore(() -> {
100   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
101   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
102   - if (maxUpdateTime != null
103   - && deptMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
104   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
105   - return;
106   - }
  76 + // 第一步:查询数据
107 77 List<DeptDO> depts = deptMapper.selectList();
108   - log.info("[initLocalCacheIfUpdate][缓存部门,数量为:{}]", depts.size());
  78 + log.info("[initLocalCache][缓存部门,数量为:{}]", depts.size());
109 79  
110   - // 第二步:构建缓存。创建或更新支付 Client
111   - // 构建缓存
  80 + // 第二步:构建缓存
112 81 ImmutableMap.Builder<Long, DeptDO> builder = ImmutableMap.builder();
113 82 ImmutableMultimap.Builder<Long, DeptDO> parentBuilder = ImmutableMultimap.builder();
114 83 depts.forEach(sysRoleDO -> {
115 84 builder.put(sysRoleDO.getId(), sysRoleDO);
116 85 parentBuilder.put(sysRoleDO.getParentId(), sysRoleDO);
117 86 });
118   - // 设置缓存
119 87 deptCache = builder.build();
120 88 parentDeptCache = parentBuilder.build();
121   -
122   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
123   - this.maxUpdateTime = CollectionUtils.getMaxValue(depts, DeptDO::getUpdateTime);
124 89 });
125 90 }
126 91  
... ...
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;
17 17 import lombok.Getter;
18 18 import lombok.Setter;
19 19 import lombok.extern.slf4j.Slf4j;
20   -import org.springframework.scheduling.annotation.Scheduled;
21 20 import org.springframework.stereotype.Service;
22 21 import org.springframework.validation.annotation.Validated;
23 22  
24 23 import javax.annotation.PostConstruct;
25 24 import javax.annotation.Resource;
26   -import java.time.LocalDateTime;
27 25 import java.util.Collection;
28 26 import java.util.List;
29 27 import java.util.Map;
30 28  
31 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
32 30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
33   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
34 31 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
35 32  
36 33 /**
... ... @@ -44,12 +41,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
44 41 public class OAuth2ClientServiceImpl implements OAuth2ClientService {
45 42  
46 43 /**
47   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
48   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
49   - */
50   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
51   -
52   - /**
53 44 * 客户端缓存
54 45 * key:客户端编号 {@link OAuth2ClientDO#getClientId()} ()}
55 46 *
... ... @@ -58,11 +49,6 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
58 49 @Getter // 解决单测
59 50 @Setter // 解决单测
60 51 private volatile Map<String, OAuth2ClientDO> clientCache;
61   - /**
62   - * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
63   - */
64   - @Getter
65   - private volatile LocalDateTime maxUpdateTime;
66 52  
67 53 @Resource
68 54 private OAuth2ClientMapper oauth2ClientMapper;
... ... @@ -76,37 +62,12 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
76 62 @Override
77 63 @PostConstruct
78 64 public void initLocalCache() {
79   - initLocalCacheIfUpdate(null);
80   - }
81   -
82   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
83   - public void schedulePeriodicRefresh() {
84   - initLocalCacheIfUpdate(this.maxUpdateTime);
85   - }
86   -
87   - /**
88   - * 刷新本地缓存
89   - *
90   - * @param maxUpdateTime 最大更新时间
91   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
92   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
93   - */
94   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
95   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
96   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
97   - if (maxUpdateTime != null
98   - && oauth2ClientMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
99   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
100   - return;
101   - }
  65 + // 第一步:查询数据
102 66 List<OAuth2ClientDO> clients = oauth2ClientMapper.selectList();
103   - log.info("[initLocalCacheIfUpdate][缓存 OAuth2 客户端,数量为:{}]", clients.size());
  67 + log.info("[initLocalCache][缓存 OAuth2 客户端,数量为:{}]", clients.size());
104 68  
105 69 // 第二步:构建缓存。
106 70 clientCache = convertMap(clients, OAuth2ClientDO::getClientId);
107   -
108   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
109   - this.maxUpdateTime = getMaxValue(clients, OAuth2ClientDO::getUpdateTime);
110 71 }
111 72  
112 73 @Override
... ...
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;
18 18 import com.google.common.collect.ImmutableMap;
19 19 import com.google.common.collect.ImmutableMultimap;
20 20 import com.google.common.collect.Multimap;
  21 +import lombok.Getter;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.context.annotation.Lazy;
23   -import org.springframework.scheduling.annotation.Scheduled;
24 24 import org.springframework.stereotype.Service;
25 25 import org.springframework.transaction.annotation.Transactional;
26 26 import org.springframework.transaction.support.TransactionSynchronization;
... ... @@ -28,7 +28,6 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
28 28  
29 29 import javax.annotation.PostConstruct;
30 30 import javax.annotation.Resource;
31   -import java.time.LocalDateTime;
32 31 import java.util.*;
33 32 import java.util.stream.Collectors;
34 33  
... ... @@ -44,17 +43,12 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
44 43 public class MenuServiceImpl implements MenuService {
45 44  
46 45 /**
47   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
48   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
49   - */
50   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
51   -
52   - /**
53 46 * 菜单缓存
54 47 * key:菜单编号
55 48 *
56 49 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
57 50 */
  51 + @Getter
58 52 private volatile Map<Long, MenuDO> menuCache;
59 53 /**
60 54 * 权限与菜单缓存
... ... @@ -63,11 +57,8 @@ public class MenuServiceImpl implements MenuService {
63 57 *
64 58 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
65 59 */
  60 + @Getter
66 61 private volatile Multimap<String, MenuDO> permissionMenuCache;
67   - /**
68   - * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
69   - */
70   - private volatile LocalDateTime maxUpdateTime;
71 62  
72 63 @Resource
73 64 private MenuMapper menuMapper;
... ... @@ -86,33 +77,11 @@ public class MenuServiceImpl implements MenuService {
86 77 @Override
87 78 @PostConstruct
88 79 public synchronized void initLocalCache() {
89   - initLocalCacheIfUpdate(null);
90   - }
91   -
92   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
93   - public void schedulePeriodicRefresh() {
94   - initLocalCacheIfUpdate(this.maxUpdateTime);
95   - }
96   -
97   - /**
98   - * 刷新本地缓存
99   - *
100   - * @param maxUpdateTime 最大更新时间
101   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
102   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
103   - */
104   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
105   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
106   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
107   - if (maxUpdateTime != null
108   - && menuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
109   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
110   - return;
111   - }
  80 + // 第一步:查询数据
112 81 List<MenuDO> menuList = menuMapper.selectList();
113   - log.info("[initLocalCacheIfUpdate][缓存菜单,数量为:{}]", menuList.size());
  82 + log.info("[initLocalCache][缓存菜单,数量为:{}]", menuList.size());
114 83  
115   - // 第二步:构建缓存。
  84 + // 第二步:构建缓存
116 85 ImmutableMap.Builder<Long, MenuDO> menuCacheBuilder = ImmutableMap.builder();
117 86 ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
118 87 menuList.forEach(menuDO -> {
... ... @@ -123,9 +92,6 @@ public class MenuServiceImpl implements MenuService {
123 92 });
124 93 menuCache = menuCacheBuilder.build();
125 94 permissionMenuCache = permMenuCacheBuilder.build();
126   -
127   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
128   - this.maxUpdateTime = CollectionUtils.getMaxValue(menuList, MenuDO::getUpdateTime);
129 95 }
130 96  
131 97 @Override
... ...
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;
16 16 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
17 17 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
18 18 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
19   -import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
20 19 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
21   -import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
22 20 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
23 21 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
24 22 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
... ... @@ -32,7 +30,6 @@ import com.google.common.collect.Sets;
32 30 import lombok.Getter;
33 31 import lombok.Setter;
34 32 import lombok.extern.slf4j.Slf4j;
35   -import org.springframework.scheduling.annotation.Scheduled;
36 33 import org.springframework.stereotype.Service;
37 34 import org.springframework.transaction.annotation.Transactional;
38 35 import org.springframework.transaction.support.TransactionSynchronization;
... ... @@ -40,12 +37,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
40 37  
41 38 import javax.annotation.PostConstruct;
42 39 import javax.annotation.Resource;
43   -import java.time.LocalDateTime;
44 40 import java.util.*;
45 41 import java.util.function.Supplier;
46 42  
47 43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
48   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
49 44 import static java.util.Collections.singleton;
50 45  
51 46 /**
... ... @@ -58,12 +53,6 @@ import static java.util.Collections.singleton;
58 53 public class PermissionServiceImpl implements PermissionService {
59 54  
60 55 /**
61   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
62   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
63   - */
64   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
65   -
66   - /**
67 56 * 角色编号与菜单编号的缓存映射
68 57 * key:角色编号
69 58 * value:菜单编号的数组
... ... @@ -83,11 +72,6 @@ public class PermissionServiceImpl implements PermissionService {
83 72 @Getter
84 73 @Setter // 单元测试需要
85 74 private volatile Multimap<Long, Long> menuRoleCache;
86   - /**
87   - * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新
88   - */
89   - @Getter
90   - private volatile LocalDateTime roleMenuMaxUpdateTime;
91 75  
92 76 /**
93 77 * 用户编号与角色编号的缓存映射
... ... @@ -99,20 +83,11 @@ public class PermissionServiceImpl implements PermissionService {
99 83 @Getter
100 84 @Setter // 单元测试需要
101 85 private volatile Map<Long, Set<Long>> userRoleCache;
102   - /**
103   - * 缓存 UserRole 的最大更新时间,用于后续的增量轮询,判断是否有更新
104   - */
105   - @Getter
106   - private volatile LocalDateTime userRoleMaxUpdateTime;
107 86  
108 87 @Resource
109 88 private RoleMenuMapper roleMenuMapper;
110 89 @Resource
111   - private RoleMenuBatchInsertMapper roleMenuBatchInsertMapper;
112   - @Resource
113 90 private UserRoleMapper userRoleMapper;
114   - @Resource
115   - private UserRoleBatchInsertMapper userRoleBatchInsertMapper;
116 91  
117 92 @Resource
118 93 private RoleService roleService;
... ... @@ -129,38 +104,22 @@ public class PermissionServiceImpl implements PermissionService {
129 104 @Override
130 105 @PostConstruct
131 106 public void initLocalCache() {
132   - initLocalCacheIfUpdateForRoleMenu(null);
133   - initLocalCacheIfUpdateForUserRole(null);
134   - }
135   -
136   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
137   - public void schedulePeriodicRefresh() {
138   - initLocalCacheIfUpdateForRoleMenu(this.roleMenuMaxUpdateTime);
139   - initLocalCacheIfUpdateForUserRole(this.userRoleMaxUpdateTime);
  107 + initLocalCacheForRoleMenu();
  108 + initLocalCacheForUserRole();
140 109 }
141 110  
142 111 /**
143 112 * 刷新 RoleMenu 本地缓存
144   - *
145   - * @param maxUpdateTime 最大更新时间
146   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
147   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
148 113 */
149 114 @VisibleForTesting
150   - void initLocalCacheIfUpdateForRoleMenu(LocalDateTime maxUpdateTime) {
  115 + void initLocalCacheForRoleMenu() {
151 116 // 注意:忽略自动多租户,因为要全局初始化缓存
152 117 TenantUtils.executeIgnore(() -> {
153   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
154   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
155   - if (maxUpdateTime != null
156   - && roleMenuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
157   - log.info("[initLocalCacheIfUpdateForRoleMenu][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
158   - return;
159   - }
  118 + // 第一步:查询数据
160 119 List<RoleMenuDO> roleMenus = roleMenuMapper.selectList();
161   - log.info("[initLocalCacheIfUpdateForRoleMenu][缓存角色与菜单,数量为:{}]", roleMenus.size());
  120 + log.info("[initLocalCacheForRoleMenu][缓存角色与菜单,数量为:{}]", roleMenus.size());
162 121  
163   - // 第二步:构建缓存。
  122 + // 第二步:构建缓存
164 123 ImmutableMultimap.Builder<Long, Long> roleMenuCacheBuilder = ImmutableMultimap.builder();
165 124 ImmutableMultimap.Builder<Long, Long> menuRoleCacheBuilder = ImmutableMultimap.builder();
166 125 roleMenus.forEach(roleMenuDO -> {
... ... @@ -169,40 +128,24 @@ public class PermissionServiceImpl implements PermissionService {
169 128 });
170 129 roleMenuCache = roleMenuCacheBuilder.build();
171 130 menuRoleCache = menuRoleCacheBuilder.build();
172   -
173   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
174   - this.roleMenuMaxUpdateTime = getMaxValue(roleMenus, RoleMenuDO::getUpdateTime);
175 131 });
176 132 }
177 133  
178 134 /**
179 135 * 刷新 UserRole 本地缓存
180   - *
181   - * @param maxUpdateTime 最大更新时间
182   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
183   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
184 136 */
185 137 @VisibleForTesting
186   - void initLocalCacheIfUpdateForUserRole(LocalDateTime maxUpdateTime) {
  138 + void initLocalCacheForUserRole() {
187 139 // 注意:忽略自动多租户,因为要全局初始化缓存
188 140 TenantUtils.executeIgnore(() -> {
189   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
190   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
191   - if (maxUpdateTime != null
192   - && userRoleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
193   - log.info("[initLocalCacheIfUpdateForUserRole][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
194   - return;
195   - }
  141 + // 第一步:加载数据
196 142 List<UserRoleDO> userRoles = userRoleMapper.selectList();
197   - log.info("[initLocalCacheIfUpdateForUserRole][缓存用户与角色,数量为:{}]", userRoles.size());
  143 + log.info("[initLocalCacheForUserRole][缓存用户与角色,数量为:{}]", userRoles.size());
198 144  
199 145 // 第二步:构建缓存。
200 146 ImmutableMultimap.Builder<Long, Long> userRoleCacheBuilder = ImmutableMultimap.builder();
201 147 userRoles.forEach(userRoleDO -> userRoleCacheBuilder.put(userRoleDO.getUserId(), userRoleDO.getRoleId()));
202 148 userRoleCache = CollectionUtils.convertMultiMap2(userRoles, UserRoleDO::getUserId, UserRoleDO::getRoleId);
203   -
204   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
205   - this.userRoleMaxUpdateTime = getMaxValue(userRoles, UserRoleDO::getUpdateTime);
206 149 });
207 150 }
208 151  
... ... @@ -264,7 +207,7 @@ public class PermissionServiceImpl implements PermissionService {
264 207 Collection<Long> deleteMenuIds = CollUtil.subtract(dbMenuIds, menuIds);
265 208 // 执行新增和删除。对于已经授权的菜单,不用做任何处理
266 209 if (!CollectionUtil.isEmpty(createMenuIds)) {
267   - roleMenuBatchInsertMapper.saveBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
  210 + roleMenuMapper.insertBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
268 211 RoleMenuDO entity = new RoleMenuDO();
269 212 entity.setRoleId(roleId);
270 213 entity.setMenuId(menuId);
... ... @@ -308,7 +251,7 @@ public class PermissionServiceImpl implements PermissionService {
308 251 Collection<Long> deleteMenuIds = CollUtil.subtract(dbRoleIds, roleIds);
309 252 // 执行新增和删除。对于已经授权的角色,不用做任何处理
310 253 if (!CollectionUtil.isEmpty(createRoleIds)) {
311   - userRoleBatchInsertMapper.saveBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
  254 + userRoleMapper.insertBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
312 255 UserRoleDO entity = new UserRoleDO();
313 256 entity.setUserId(userId);
314 257 entity.setRoleId(roleId);
... ...
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;
22 22 import lombok.Getter;
23 23 import lombok.extern.slf4j.Slf4j;
24 24 import org.springframework.lang.Nullable;
25   -import org.springframework.scheduling.annotation.Scheduled;
26 25 import org.springframework.stereotype.Service;
27 26 import org.springframework.transaction.annotation.Transactional;
28 27 import org.springframework.transaction.support.TransactionSynchronization;
... ... @@ -31,7 +30,6 @@ import org.springframework.util.StringUtils;
31 30  
32 31 import javax.annotation.PostConstruct;
33 32 import javax.annotation.Resource;
34   -import java.time.LocalDateTime;
35 33 import java.util.*;
36 34 import java.util.stream.Collectors;
37 35  
... ... @@ -48,12 +46,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
48 46 public class RoleServiceImpl implements RoleService {
49 47  
50 48 /**
51   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
52   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
53   - */
54   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
55   -
56   - /**
57 49 * 角色缓存
58 50 * key:角色编号 {@link RoleDO#getId()}
59 51 *
... ... @@ -61,11 +53,6 @@ public class RoleServiceImpl implements RoleService {
61 53 */
62 54 @Getter
63 55 private volatile Map<Long, RoleDO> roleCache;
64   - /**
65   - * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
66   - */
67   - @Getter
68   - private volatile LocalDateTime maxUpdateTime;
69 56  
70 57 @Resource
71 58 private PermissionService permissionService;
... ... @@ -82,39 +69,14 @@ public class RoleServiceImpl implements RoleService {
82 69 @Override
83 70 @PostConstruct
84 71 public void initLocalCache() {
85   - initLocalCacheIfUpdate(null);
86   - }
87   -
88   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
89   - public void schedulePeriodicRefresh() {
90   - initLocalCacheIfUpdate(this.maxUpdateTime);
91   - }
92   -
93   - /**
94   - * 刷新本地缓存
95   - *
96   - * @param maxUpdateTime 最大更新时间
97   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
98   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
99   - */
100   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
101 72 // 注意:忽略自动多租户,因为要全局初始化缓存
102 73 TenantUtils.executeIgnore(() -> {
103   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
104   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
105   - if (maxUpdateTime != null
106   - && roleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
107   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
108   - return;
109   - }
  74 + // 第一步:查询数据
110 75 List<RoleDO> roleList = roleMapper.selectList();
111   - log.info("[initLocalCacheIfUpdate][缓存角色,数量为:{}]", roleList.size());
  76 + log.info("[initLocalCache][缓存角色,数量为:{}]", roleList.size());
112 77  
113   - // 第二步:构建缓存。
  78 + // 第二步:构建缓存
114 79 roleCache = CollectionUtils.convertMap(roleList, RoleDO::getId);
115   -
116   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
117   - this.maxUpdateTime = CollectionUtils.getMaxValue(roleList, RoleDO::getUpdateTime);
118 80 });
119 81 }
120 82  
... ...
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;
17 17 import com.google.common.collect.Multimap;
18 18 import lombok.Getter;
19 19 import lombok.extern.slf4j.Slf4j;
20   -import org.springframework.scheduling.annotation.Scheduled;
21 20 import org.springframework.stereotype.Service;
22 21 import org.springframework.validation.annotation.Validated;
23 22  
24 23 import javax.annotation.PostConstruct;
25 24 import javax.annotation.Resource;
26   -import java.time.LocalDateTime;
27 25 import java.util.*;
28 26  
29 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -41,12 +39,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_
41 39 public class SensitiveWordServiceImpl implements SensitiveWordService {
42 40  
43 41 /**
44   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
45   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
46   - */
47   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
48   -
49   - /**
50 42 * 敏感词标签缓存
51 43 * key:敏感词编号 {@link SensitiveWordDO#getId()}
52 44 * <p>
... ... @@ -55,12 +47,6 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
55 47 @Getter
56 48 private volatile Set<String> sensitiveWordTagsCache = Collections.emptySet();
57 49  
58   - /**
59   - * 缓存敏感词的最大更新时间,用于后续的增量轮询,判断是否有更新
60   - */
61   - @Getter
62   - private volatile LocalDateTime maxUpdateTime;
63   -
64 50 @Resource
65 51 private SensitiveWordMapper sensitiveWordMapper;
66 52  
... ... @@ -84,42 +70,17 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
84 70 @Override
85 71 @PostConstruct
86 72 public void initLocalCache() {
87   - initLocalCacheIfUpdate(null);
88   - }
89   -
90   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
91   - public void schedulePeriodicRefresh() {
92   - initLocalCacheIfUpdate(this.maxUpdateTime);
93   - }
94   -
95   - /**
96   - * 刷新本地缓存
97   - *
98   - * @param maxUpdateTime 最大更新时间
99   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
100   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
101   - */
102   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
103   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
104   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
105   - if (maxUpdateTime != null
106   - && sensitiveWordMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
107   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
108   - return;
109   - }
  73 + // 第一步:查询数据
110 74 List<SensitiveWordDO> sensitiveWords = sensitiveWordMapper.selectList();
111   - log.info("[initLocalCacheIfUpdate][缓存敏感词,数量为:{}]", sensitiveWords.size());
  75 + log.info("[initLocalCache][缓存敏感词,数量为:{}]", sensitiveWords.size());
112 76  
113   - // 第二步:构建缓存。
  77 + // 第二步:构建缓存
114 78 // 写入 sensitiveWordTagsCache 缓存
115 79 Set<String> tags = new HashSet<>();
116 80 sensitiveWords.forEach(word -> tags.addAll(word.getTags()));
117 81 sensitiveWordTagsCache = tags;
118 82 // 写入 defaultSensitiveWordTrie、tagSensitiveWordTries 缓存
119 83 initSensitiveWordTrie(sensitiveWords);
120   -
121   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
122   - this.maxUpdateTime = CollectionUtils.getMaxValue(sensitiveWords, SensitiveWordDO::getUpdateTime);
123 84 }
124 85  
125 86 private void initSensitiveWordTrie(List<SensitiveWordDO> wordDOs) {
... ...
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;
11 11 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
12 12 import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
13 13 import lombok.extern.slf4j.Slf4j;
14   -import org.springframework.scheduling.annotation.Scheduled;
15 14 import org.springframework.stereotype.Service;
16 15  
17 16 import javax.annotation.PostConstruct;
18 17 import javax.annotation.Resource;
19   -import java.time.LocalDateTime;
20 18 import java.util.Collection;
21 19 import java.util.List;
22 20  
23 21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
24   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
25 22 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
26 23 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
27 24  
... ... @@ -34,17 +31,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNE
34 31 @Slf4j
35 32 public class SmsChannelServiceImpl implements SmsChannelService {
36 33  
37   - /**
38   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
39   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
40   - */
41   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
42   -
43   - /**
44   - * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
45   - */
46   - private volatile LocalDateTime maxUpdateTime;
47   -
48 34 @Resource
49 35 private SmsClientFactory smsClientFactory;
50 36  
... ... @@ -60,38 +46,13 @@ public class SmsChannelServiceImpl implements SmsChannelService {
60 46 @Override
61 47 @PostConstruct
62 48 public void initLocalCache() {
63   - initLocalCacheIfUpdate(null);
64   - }
65   -
66   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
67   - public void schedulePeriodicRefresh() {
68   - initLocalCacheIfUpdate(this.maxUpdateTime);
69   - }
70   -
71   - /**
72   - * 刷新本地缓存
73   - *
74   - * @param maxUpdateTime 最大更新时间
75   - * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
76   - * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
77   - */
78   - private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
79   - // 第一步:基于 maxUpdateTime 判断缓存是否刷新。
80   - // 如果没有增量的数据变化,则不进行本地缓存的刷新
81   - if (maxUpdateTime != null
82   - && smsChannelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
83   - log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
84   - return;
85   - }
  49 + // 第一步:查询数据
86 50 List<SmsChannelDO> channels = smsChannelMapper.selectList();
87   - log.info("[initLocalCacheIfUpdate][缓存短信渠道,数量为:{}]", channels.size());
  51 + log.info("[initLocalCache][缓存短信渠道,数量为:{}]", channels.size());
88 52  
89   - // 第二步:构建缓存。创建或更新短信 Client
  53 + // 第二步:构建缓存:创建或更新短信 Client
90 54 List<SmsChannelProperties> propertiesList = SmsChannelConvert.INSTANCE.convertList02(channels);
91 55 propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties));
92   -
93   - // 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
94   - this.maxUpdateTime = getMaxValue(channels, SmsChannelDO::getUpdateTime);
95 56 }
96 57  
97 58 @Override
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java
1 1 package cn.iocoder.yudao.module.system.service.sms;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.hutool.core.util.ReUtil;
5 4 import cn.hutool.core.util.StrUtil;
6 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
... ... @@ -20,15 +19,17 @@ import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
20 19 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper;
21 20 import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
22 21 import com.google.common.annotations.VisibleForTesting;
  22 +import lombok.Getter;
23 23 import lombok.extern.slf4j.Slf4j;
24   -import org.springframework.scheduling.annotation.Scheduled;
25 24 import org.springframework.stereotype.Service;
26 25 import org.springframework.util.Assert;
27 26  
28 27 import javax.annotation.PostConstruct;
29 28 import javax.annotation.Resource;
30   -import java.time.LocalDateTime;
31   -import java.util.*;
  29 +import java.util.Collection;
  30 +import java.util.List;
  31 +import java.util.Map;
  32 +import java.util.Objects;
32 33 import java.util.regex.Pattern;
33 34  
34 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -45,12 +46,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
45 46 public class SmsTemplateServiceImpl implements SmsTemplateService {
46 47  
47 48 /**
48   - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
49   - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
50   - */
51   - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
52   -
53   - /**
54 49 * 正则表达式,匹配 {} 中的变量
55 50 */
56 51 private static final Pattern PATTERN_PARAMS = Pattern.compile("\\{(.*?)}");
... ... @@ -73,51 +68,18 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
73 68 *
74 69 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
75 70 */
  71 + @Getter // 为了方便测试,这里提供 getter 方法
76 72 private volatile Map<String, SmsTemplateDO> smsTemplateCache;
77   - /**
78   - * 缓存短信模板的最大更新时间,用于后续的增量轮询,判断是否有更新
79   - */
80   - private volatile LocalDateTime maxUpdateTime;
81 73  
82 74 @Override
83 75 @PostConstruct
84 76 public void initLocalCache() {
85   - // 获取短信模板列表,如果有更新
86   - List<SmsTemplateDO> smsTemplateList = this.loadSmsTemplateIfUpdate(maxUpdateTime);
87   - if (CollUtil.isEmpty(smsTemplateList)) {
88   - return;
89   - }
  77 + // 第一步:查询数据
  78 + List<SmsTemplateDO> smsTemplateList = smsTemplateMapper.selectList();
  79 + log.info("[initLocalCache][缓存短信模版,数量为:{}]", smsTemplateList.size());
90 80  
91   - // 写入缓存
  81 + // 第二步:构建缓存
92 82 smsTemplateCache = CollectionUtils.convertMap(smsTemplateList, SmsTemplateDO::getCode);
93   - maxUpdateTime = CollectionUtils.getMaxValue(smsTemplateList, SmsTemplateDO::getUpdateTime);
94   - log.info("[initLocalCache][初始化 SmsTemplate 数量为 {}]", smsTemplateList.size());
95   - }
96   -
97   - /**
98   - * 如果短信模板发生变化,从数据库中获取最新的全量短信模板。
99   - * 如果未发生变化,则返回空
100   - *
101   - * @param maxUpdateTime 当前短信模板的最大更新时间
102   - * @return 短信模板列表
103   - */
104   - private List<SmsTemplateDO> loadSmsTemplateIfUpdate(LocalDateTime maxUpdateTime) {
105   - // 第一步,判断是否要更新。
106   - if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
107   - log.info("[loadSmsTemplateIfUpdate][首次加载全量短信模板]");
108   - } else { // 判断数据库中是否有更新的短信模板
109   - if (smsTemplateMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
110   - return null;
111   - }
112   - log.info("[loadSmsTemplateIfUpdate][增量加载全量短信模板]");
113   - }
114   - // 第二步,如果有更新,则从数据库加载所有短信模板
115   - return smsTemplateMapper.selectList();
116   - }
117   -
118   - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
119   - public void schedulePeriodicRefresh() {
120   - initLocalCache();
121 83 }
122 84  
123 85 @Override
... ...
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;
5 5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
6 6 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
7 7 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
8   -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO;
9   -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO;
10 8 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
11 9 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
12 10 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
... ... @@ -16,7 +14,7 @@ import cn.iocoder.yudao.module.system.service.member.MemberService;
16 14 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
17 15 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
18 16 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
19   -import com.anji.captcha.service.CaptchaService;
  17 +import com.xingyuv.captcha.service.CaptchaService;
20 18 import org.junit.jupiter.api.Test;
21 19 import org.springframework.boot.test.mock.mockito.MockBean;
22 20 import org.springframework.context.annotation.Import;
... ... @@ -25,7 +23,6 @@ import javax.annotation.Resource;
25 23 import javax.validation.Validator;
26 24  
27 25 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
28   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 26 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
30 27 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
31 28 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java
1 1 package cn.iocoder.yudao.module.system.service.dept;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
  5 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
4 6 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
  7 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 8 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO;
6 9 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
7 10 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;
9 12 import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
10 13 import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
11 14 import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
12   -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
13   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
14   -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
15 15 import com.google.common.collect.Multimap;
16 16 import org.junit.jupiter.api.BeforeEach;
17 17 import org.junit.jupiter.api.Test;
... ... @@ -19,17 +19,15 @@ import org.springframework.boot.test.mock.mockito.MockBean;
19 19 import org.springframework.context.annotation.Import;
20 20  
21 21 import javax.annotation.Resource;
22   -import java.time.LocalDateTime;
23 22 import java.util.List;
24 23 import java.util.Map;
25 24 import java.util.function.Consumer;
26 25  
27   -import static cn.hutool.core.bean.BeanUtil.getFieldValue;
28 26 import static cn.hutool.core.util.RandomUtil.randomEle;
29   -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
30 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
31 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
32 29 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  30 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
33 31 import static org.junit.jupiter.api.Assertions.*;
34 32 import static org.mockito.Mockito.times;
35 33 import static org.mockito.Mockito.verify;
... ... @@ -56,8 +54,7 @@ public class DeptServiceTest extends BaseDbUnitTest {
56 54 }
57 55  
58 56 @Test
59   - @SuppressWarnings("unchecked")
60   - void testInitLocalCache() {
  57 + public void testInitLocalCache() {
61 58 // mock 数据
62 59 DeptDO deptDO1 = randomDeptDO();
63 60 deptMapper.insert(deptDO1);
... ... @@ -67,18 +64,15 @@ public class DeptServiceTest extends BaseDbUnitTest {
67 64 // 调用
68 65 deptService.initLocalCache();
69 66 // 断言 deptCache 缓存
70   - Map<Long, DeptDO> deptCache = (Map<Long, DeptDO>) getFieldValue(deptService, "deptCache");
  67 + Map<Long, DeptDO> deptCache = deptService.getDeptCache();
71 68 assertEquals(2, deptCache.size());
72 69 assertPojoEquals(deptDO1, deptCache.get(deptDO1.getId()));
73 70 assertPojoEquals(deptDO2, deptCache.get(deptDO2.getId()));
74 71 // 断言 parentDeptCache 缓存
75   - Multimap<Long, DeptDO> parentDeptCache = (Multimap<Long, DeptDO>) getFieldValue(deptService, "parentDeptCache");
  72 + Multimap<Long, DeptDO> parentDeptCache = deptService.getParentDeptCache();
76 73 assertEquals(2, parentDeptCache.size());
77 74 assertPojoEquals(deptDO1, parentDeptCache.get(deptDO1.getParentId()));
78 75 assertPojoEquals(deptDO2, parentDeptCache.get(deptDO2.getParentId()));
79   - // 断言 maxUpdateTime 缓存
80   - LocalDateTime maxUpdateTime = (LocalDateTime) getFieldValue(deptService, "maxUpdateTime");
81   - assertEquals(ObjectUtils.max(deptDO1.getUpdateTime(), deptDO2.getUpdateTime()), maxUpdateTime);
82 76 }
83 77  
84 78 @Test
... ...
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;
19 19 import java.util.Map;
20 20  
21 21 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
22   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
23 22 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
24 23 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
25 24 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
... ... @@ -59,8 +58,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
59 58 assertEquals(2, clientCache.size());
60 59 assertPojoEquals(clientDO1, clientCache.get(clientDO1.getClientId()));
61 60 assertPojoEquals(clientDO2, clientCache.get(clientDO2.getClientId()));
62   - // 断言 maxUpdateTime 缓存
63   - assertEquals(max(clientDO1.getUpdateTime(), clientDO2.getUpdateTime()), oauth2ClientService.getMaxUpdateTime());
64 61 }
65 62  
66 63 @Test
... ...
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;
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.lang.Assert;
5 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7 6 import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
8 7 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 8 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
... ... @@ -20,7 +19,6 @@ import org.springframework.boot.test.mock.mockito.MockBean;
20 19 import org.springframework.context.annotation.Import;
21 20  
22 21 import javax.annotation.Resource;
23   -import java.time.LocalDateTime;
24 22 import java.util.*;
25 23  
26 24 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
... ... @@ -51,32 +49,24 @@ public class MenuServiceTest extends BaseDbUnitTest {
51 49 private TenantService tenantService;
52 50  
53 51 @Test
54   - public void testInitLocalCache_success() throws Exception {
55   - MenuDO menuDO1 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
  52 + public void testInitLocalCache_success() {
  53 + MenuDO menuDO1 = randomPojo(MenuDO.class);
56 54 menuMapper.insert(menuDO1);
57   - MenuDO menuDO2 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
  55 + MenuDO menuDO2 = randomPojo(MenuDO.class);
58 56 menuMapper.insert(menuDO2);
59 57  
60 58 // 调用
61 59 menuService.initLocalCache();
62   -
63   - // 获取代理对象
64   - MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService);
65   -
66   - Map<Long, MenuDO> menuCache =
67   - (Map<Long, MenuDO>) BeanUtil.getFieldValue(target, "menuCache");
  60 + // 校验 menuCache 缓存
  61 + Map<Long, MenuDO> menuCache = menuService.getMenuCache();
68 62 Assert.isTrue(menuCache.size() == 2);
69 63 assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId()));
70 64 assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId()));
71   -
72   - Multimap<String, MenuDO> permissionMenuCache =
73   - (Multimap<String, MenuDO>) BeanUtil.getFieldValue(target, "permissionMenuCache");
  65 + // 校验 permissionMenuCache 缓存
  66 + Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache();
74 67 Assert.isTrue(permissionMenuCache.size() == 2);
75 68 assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission()));
76 69 assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission()));
77   -
78   - LocalDateTime maxUpdateTime = (LocalDateTime) BeanUtil.getFieldValue(target, "maxUpdateTime");
79   - assertEquals(ObjectUtils.max(menuDO1.getUpdateTime(), menuDO2.getUpdateTime()), maxUpdateTime);
80 70 }
81 71  
82 72 @Test
... ...
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;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.map.MapUtil;
5 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7   -import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
8 6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  7 +import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
9 8 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
10 9 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
11 10 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
12 11 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
13 12 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
14 13 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
15   -import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
16 14 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
17   -import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
18 15 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
19 16 import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
20 17 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
... ... @@ -27,8 +24,10 @@ import org.springframework.boot.test.mock.mockito.MockBean;
27 24 import org.springframework.context.annotation.Import;
28 25  
29 26 import javax.annotation.Resource;
30   -import java.time.LocalDateTime;
31   -import java.util.*;
  27 +import java.util.Collection;
  28 +import java.util.List;
  29 +import java.util.Map;
  30 +import java.util.Set;
32 31  
33 32 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
34 33 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
... ... @@ -42,8 +41,7 @@ import static org.mockito.ArgumentMatchers.same;
42 41 import static org.mockito.Mockito.verify;
43 42 import static org.mockito.Mockito.when;
44 43  
45   -@Import({PermissionServiceImpl.class,
46   - RoleMenuBatchInsertMapper.class, UserRoleBatchInsertMapper.class})
  44 +@Import({PermissionServiceImpl.class})
47 45 public class PermissionServiceTest extends BaseDbUnitTest {
48 46  
49 47 @Resource
... ... @@ -52,11 +50,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
52 50 @Resource
53 51 private RoleMenuMapper roleMenuMapper;
54 52 @Resource
55   - private RoleMenuBatchInsertMapper roleMenuBatchInsertMapper;
56   - @Resource
57 53 private UserRoleMapper userRoleMapper;
58   - @Resource
59   - private UserRoleBatchInsertMapper userRoleBatchInsertMapper;
60 54  
61 55 @MockBean
62 56 private RoleService roleService;
... ... @@ -71,7 +65,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
71 65 private PermissionProducer permissionProducer;
72 66  
73 67 @Test
74   - public void testInitLocalCacheIfUpdateForRoleMenu() {
  68 + public void testInitLocalCacheForRoleMenu() {
75 69 // mock 数据
76 70 RoleMenuDO roleMenuDO01 = randomPojo(RoleMenuDO.class, o -> o.setRoleId(1L).setMenuId(10L));
77 71 roleMenuMapper.insert(roleMenuDO01);
... ... @@ -79,7 +73,7 @@ public class PermissionServiceTest extends BaseDbUnitTest {
79 73 roleMenuMapper.insert(roleMenuDO02);
80 74  
81 75 // 调用
82   - permissionService.initLocalCacheIfUpdateForRoleMenu(null);
  76 + permissionService.initLocalCacheForRoleMenu();
83 77 // 断言 roleMenuCache 缓存
84 78 assertEquals(1, permissionService.getRoleMenuCache().keySet().size());
85 79 assertEquals(asList(10L, 20L), permissionService.getRoleMenuCache().get(1L));
... ... @@ -87,13 +81,10 @@ public class PermissionServiceTest extends BaseDbUnitTest {
87 81 assertEquals(2, permissionService.getMenuRoleCache().size());
88 82 assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(10L));
89 83 assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(20L));
90   - // 断言 maxUpdateTime 缓存
91   - LocalDateTime maxUpdateTime = permissionService.getRoleMenuMaxUpdateTime();
92   - assertEquals(ObjectUtils.max(roleMenuDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime);
93 84 }
94 85  
95 86 @Test
96   - public void testInitLocalCacheIfUpdateForUserRole() {
  87 + public void testInitLocalCacheForUserRole() {
97 88 // mock 数据
98 89 UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
99 90 userRoleMapper.insert(userRoleDO01);
... ... @@ -101,13 +92,10 @@ public class PermissionServiceTest extends BaseDbUnitTest {
101 92 userRoleMapper.insert(roleMenuDO02);
102 93  
103 94 // 调用
104   - permissionService.initLocalCacheIfUpdateForUserRole(null);
  95 + permissionService.initLocalCacheForUserRole();
105 96 // 断言 roleMenuCache 缓存
106 97 assertEquals(1, permissionService.getUserRoleCache().size());
107 98 assertEquals(asSet(10L, 20L), permissionService.getUserRoleCache().get(1L));
108   - // 断言 maxUpdateTime 缓存
109   - LocalDateTime maxUpdateTime = permissionService.getUserRoleMaxUpdateTime();
110   - assertEquals(ObjectUtils.max(userRoleDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime);
111 99 }
112 100  
113 101 @Test
... ...
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.*;
23 23  
24 24 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
25 25 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
26   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
27 26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
28 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 28 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
... ... @@ -59,8 +58,6 @@ public class RoleServiceTest extends BaseDbUnitTest {
59 58 Map<Long, RoleDO> roleCache = roleService.getRoleCache();
60 59 assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId()));
61 60 assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId()));
62   - // 断言 maxUpdateTime 缓存
63   - assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), roleService.getMaxUpdateTime());
64 61 }
65 62  
66 63 @Test
... ...
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 {
60 60  
61 61 // 调用
62 62 sensitiveWordService.initLocalCache();
63   - // 断言 maxUpdateTime 缓存
64   - assertEquals(max(wordDO1.getUpdateTime(), wordDO2.getUpdateTime()), sensitiveWordService.getMaxUpdateTime());
65 63 // 断言 sensitiveWordTagsCache 缓存
66 64 assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTags());
67 65 // 断言 tagSensitiveWordTries 缓存
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java
1 1 package cn.iocoder.yudao.module.system.service.sms;
2 2  
3   -import cn.hutool.core.bean.BeanUtil;
4   -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO;
5   -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
6   -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelUpdateReqVO;
7   -import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
8   -import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
9   -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
10 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
11 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12 5 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
13 6 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
14 7 import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory;
15 8 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  9 +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO;
  10 +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
  11 +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelUpdateReqVO;
  12 +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
  13 +import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
  14 +import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
16 15 import org.junit.jupiter.api.Test;
17 16 import org.springframework.boot.test.mock.mockito.MockBean;
18 17 import org.springframework.context.annotation.Import;
... ... @@ -22,12 +21,11 @@ import java.time.LocalDateTime;
22 21 import java.util.function.Consumer;
23 22  
24 23 import static cn.hutool.core.util.RandomUtil.randomEle;
25   -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
26   -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
27 24 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
28   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
29 25 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
30 26 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  27 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
  28 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
31 29 import static org.junit.jupiter.api.Assertions.*;
32 30 import static org.mockito.ArgumentMatchers.eq;
33 31 import static org.mockito.Mockito.*;
... ... @@ -58,9 +56,6 @@ public class SmsChannelServiceTest extends BaseDbUnitTest {
58 56  
59 57 // 调用
60 58 smsChannelService.initLocalCache();
61   - // 校验 maxUpdateTime 属性
62   - LocalDateTime maxUpdateTime = (LocalDateTime) BeanUtil.getFieldValue(smsChannelService, "maxUpdateTime");
63   - assertEquals(max(smsChannelDO01.getUpdateTime(), smsChannelDO02.getUpdateTime()), maxUpdateTime);
64 59 // 校验调用
65 60 verify(smsClientFactory, times(1)).createOrUpdateSmsClient(
66 61 argThat(properties -> isPojoEquals(smsChannelDO01, properties)));
... ...
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 {
61 61 private SmsProducer smsProducer;
62 62  
63 63 @Test
64   - @SuppressWarnings("unchecked")
65 64 void testInitLocalCache() {
66 65 // mock 数据
67 66 SmsTemplateDO smsTemplate01 = randomSmsTemplateDO();
... ... @@ -72,13 +71,10 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
72 71 // 调用
73 72 smsTemplateService.initLocalCache();
74 73 // 断言 deptCache 缓存
75   - Map<String, SmsTemplateDO> smsTemplateCache = (Map<String, SmsTemplateDO>) getFieldValue(smsTemplateService, "smsTemplateCache");
  74 + Map<String, SmsTemplateDO> smsTemplateCache = smsTemplateService.getSmsTemplateCache();
76 75 assertEquals(2, smsTemplateCache.size());
77 76 assertPojoEquals(smsTemplate01, smsTemplateCache.get(smsTemplate01.getCode()));
78 77 assertPojoEquals(smsTemplate02, smsTemplateCache.get(smsTemplate02.getCode()));
79   - // 断言 maxUpdateTime 缓存
80   - LocalDateTime maxUpdateTime = (LocalDateTime) getFieldValue(smsTemplateService, "maxUpdateTime");
81   - assertEquals(max(smsTemplate01.getUpdateTime(), smsTemplate02.getUpdateTime()), maxUpdateTime);
82 78 }
83 79  
84 80 @Test
... ...