Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
d2d2b5cd
提交
d2d2b5cd
authored
1月 25, 2023
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
简化本地缓存的实现,萌新更容易看懂!
上级
b43813ab
隐藏空白字符变更
内嵌
并排
正在显示
35 个修改的文件
包含
201 行增加
和
715 行删除
+201
-715
BaseMapperX.java
...oder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
+8
-6
FileConfigMapper.java
...r/yudao/module/infra/dal/mysql/file/FileConfigMapper.java
+0
-11
FileConfigRefreshConsumer.java
...ule/infra/mq/consumer/file/FileConfigRefreshConsumer.java
+1
-1
FileConfigService.java
...er/yudao/module/infra/service/file/FileConfigService.java
+1
-1
FileConfigServiceImpl.java
...udao/module/infra/service/file/FileConfigServiceImpl.java
+4
-44
FileConfigServiceImplTest.java
.../module/infra/service/file/FileConfigServiceImplTest.java
+32
-36
DeptMapper.java
...ocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java
+0
-6
OAuth2ClientMapper.java
...ao/module/system/dal/mysql/oauth2/OAuth2ClientMapper.java
+0
-6
MenuMapper.java
.../yudao/module/system/dal/mysql/permission/MenuMapper.java
+0
-5
RoleMapper.java
.../yudao/module/system/dal/mysql/permission/RoleMapper.java
+0
-5
RoleMenuBatchInsertMapper.java
...ystem/dal/mysql/permission/RoleMenuBatchInsertMapper.java
+0
-14
RoleMenuMapper.java
...ao/module/system/dal/mysql/permission/RoleMenuMapper.java
+7
-11
UserRoleBatchInsertMapper.java
...ystem/dal/mysql/permission/UserRoleBatchInsertMapper.java
+0
-14
UserRoleMapper.java
...ao/module/system/dal/mysql/permission/UserRoleMapper.java
+7
-16
SensitiveWordMapper.java
...e/system/dal/mysql/sensitiveword/SensitiveWordMapper.java
+0
-5
SmsChannelMapper.java
...r/yudao/module/system/dal/mysql/sms/SmsChannelMapper.java
+0
-6
SmsTemplateMapper.java
.../yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java
+0
-5
TenantMapper.java
...er/yudao/module/system/dal/mysql/tenant/TenantMapper.java
+3
-8
DeptServiceImpl.java
...der/yudao/module/system/service/dept/DeptServiceImpl.java
+6
-41
OAuth2ClientServiceImpl.java
...module/system/service/oauth2/OAuth2ClientServiceImpl.java
+2
-41
MenuServiceImpl.java
...dao/module/system/service/permission/MenuServiceImpl.java
+10
-44
PermissionServiceImpl.java
...dule/system/service/permission/PermissionServiceImpl.java
+11
-68
RoleServiceImpl.java
...dao/module/system/service/permission/RoleServiceImpl.java
+5
-49
SensitiveWordServiceImpl.java
...ystem/service/sensitiveword/SensitiveWordServiceImpl.java
+3
-42
SmsChannelServiceImpl.java
...udao/module/system/service/sms/SmsChannelServiceImpl.java
+4
-45
SmsTemplateServiceImpl.java
...dao/module/system/service/sms/SmsTemplateServiceImpl.java
+10
-48
AdminAuthServiceImplTest.java
.../module/system/service/auth/AdminAuthServiceImplTest.java
+1
-2
DeptServiceTest.java
...der/yudao/module/system/service/dept/DeptServiceTest.java
+8
-14
OAuth2ClientServiceImplTest.java
...le/system/service/oauth2/OAuth2ClientServiceImplTest.java
+25
-28
MenuServiceTest.java
...dao/module/system/service/permission/MenuServiceTest.java
+7
-17
PermissionServiceTest.java
...dule/system/service/permission/PermissionServiceTest.java
+10
-22
RoleServiceTest.java
...dao/module/system/service/permission/RoleServiceTest.java
+9
-14
SensitiveWordServiceImplTest.java
...m/service/sensitiveword/SensitiveWordServiceImplTest.java
+7
-10
SmsChannelServiceTest.java
...udao/module/system/service/sms/SmsChannelServiceTest.java
+12
-17
SmsTemplateServiceTest.java
...dao/module/system/service/sms/SmsTemplateServiceTest.java
+8
-13
没有找到文件。
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
浏览文件 @
d2d2b5cd
...
...
@@ -76,23 +76,24 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
return
selectList
(
new
LambdaQueryWrapper
<
T
>().
in
(
field
,
values
));
}
default
List
<
T
>
selectList
(
SFunction
<
T
,
?>
leField
,
SFunction
<
T
,
?>
geField
,
Object
value
)
{
return
selectList
(
new
LambdaQueryWrapper
<
T
>().
le
(
leField
,
value
).
ge
(
geField
,
value
));
}
/**
* 逐条插入,适合少量数据插入,或者对性能要求不高的场景
*
* 如果大量,请使用 {@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
);
...
...
@@ -105,4 +106,5 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
default
void
updateBatch
(
Collection
<
T
>
entities
,
int
size
)
{
Db
.
updateBatchById
(
entities
,
size
);
}
}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileConfigMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
);
}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/consumer/file/FileConfigRefreshConsumer.java
浏览文件 @
d2d2b5cd
...
...
@@ -23,7 +23,7 @@ public class FileConfigRefreshConsumer {
@EventListener
public
void
execute
(
FileConfigRefreshMessage
message
)
{
log
.
info
(
"[execute][收到 FileConfig 刷新消息]"
);
fileConfigService
.
init
FileClients
();
fileConfigService
.
init
LocalCache
();
}
}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java
浏览文件 @
d2d2b5cd
...
...
@@ -21,7 +21,7 @@ public interface FileConfigService {
/**
* 初始化文件客户端
*/
void
init
FileClients
();
void
init
LocalCache
();
/**
* 创建文件配置
...
...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
(
"[initLocalCache
IfUpdate
][缓存文件配置,数量为:{}]"
,
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
...
...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -28,9 +28,8 @@ import java.time.LocalDateTime;
import
java.util.Map
;
import
static
cn
.
hutool
.
core
.
util
.
RandomUtil
.
randomEle
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildLocalDate
Time
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
LocalDateTimeUtils
.
build
Time
;
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
;
...
...
@@ -42,10 +41,10 @@ import static org.mockito.ArgumentMatchers.eq;
import
static
org
.
mockito
.
Mockito
.*;
/**
* {@link FileConfigServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
* {@link FileConfigServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
@Import
(
FileConfigServiceImpl
.
class
)
public
class
FileConfigServiceImplTest
extends
BaseDbUnitTest
{
...
...
@@ -74,16 +73,13 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
when
(
fileClientFactory
.
getFileClient
(
eq
(
1L
))).
thenReturn
(
masterFileClient
);
// 调用
fileConfigService
.
init
FileClients
();
fileConfigService
.
init
LocalCache
();
// 断言 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
...
...
@@ -175,8 +171,8 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
// 调用
fileConfigService
.
deleteFileConfig
(
id
);
// 校验数据不存在了
assertNull
(
fileConfigMapper
.
selectById
(
id
));
// 校验数据不存在了
assertNull
(
fileConfigMapper
.
selectById
(
id
));
// verify 调用
verify
(
fileConfigProducer
).
sendFileConfigRefreshMessage
();
}
...
...
@@ -204,30 +200,30 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
@Test
public
void
testGetFileConfigPage
()
{
// mock 数据
FileConfigDO
dbFileConfig
=
randomFileConfigDO
().
setName
(
"芋道源码"
)
.
setStorage
(
FileStorageEnum
.
LOCAL
.
getStorage
());
dbFileConfig
.
setCreateTime
(
LocalDateTimeUtil
.
parse
(
"2020-01-23"
,
DatePattern
.
NORM_DATE_PATTERN
));
// 等会查询到
fileConfigMapper
.
insert
(
dbFileConfig
);
// 测试 name 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setName
(
"源码"
)));
// 测试 storage 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setStorage
(
FileStorageEnum
.
DB
.
getStorage
())));
// 测试 createTime 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setCreateTime
(
LocalDateTimeUtil
.
parse
(
"2020-11-23"
,
DatePattern
.
NORM_DATE_PATTERN
))));
// 准备参数
FileConfigPageReqVO
reqVO
=
new
FileConfigPageReqVO
();
reqVO
.
setName
(
"芋道"
);
reqVO
.
setStorage
(
FileStorageEnum
.
LOCAL
.
getStorage
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
buildLocalDate
Time
(
2020
,
1
,
1
),
buildLocalDate
Time
(
2020
,
1
,
24
)}));
// 调用
PageResult
<
FileConfigDO
>
pageResult
=
fileConfigService
.
getFileConfigPage
(
reqVO
);
// 断言
assertEquals
(
1
,
pageResult
.
getTotal
());
assertEquals
(
1
,
pageResult
.
getList
().
size
());
assertPojoEquals
(
dbFileConfig
,
pageResult
.
getList
().
get
(
0
));
// mock 数据
FileConfigDO
dbFileConfig
=
randomFileConfigDO
().
setName
(
"芋道源码"
)
.
setStorage
(
FileStorageEnum
.
LOCAL
.
getStorage
());
dbFileConfig
.
setCreateTime
(
LocalDateTimeUtil
.
parse
(
"2020-01-23"
,
DatePattern
.
NORM_DATE_PATTERN
));
// 等会查询到
fileConfigMapper
.
insert
(
dbFileConfig
);
// 测试 name 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setName
(
"源码"
)));
// 测试 storage 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setStorage
(
FileStorageEnum
.
DB
.
getStorage
())));
// 测试 createTime 不匹配
fileConfigMapper
.
insert
(
cloneIgnoreId
(
dbFileConfig
,
o
->
o
.
setCreateTime
(
LocalDateTimeUtil
.
parse
(
"2020-11-23"
,
DatePattern
.
NORM_DATE_PATTERN
))));
// 准备参数
FileConfigPageReqVO
reqVO
=
new
FileConfigPageReqVO
();
reqVO
.
setName
(
"芋道"
);
reqVO
.
setStorage
(
FileStorageEnum
.
LOCAL
.
getStorage
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2020
,
1
,
1
),
build
Time
(
2020
,
1
,
24
)}));
// 调用
PageResult
<
FileConfigDO
>
pageResult
=
fileConfigService
.
getFileConfigPage
(
reqVO
);
// 断言
assertEquals
(
1
,
pageResult
.
getTotal
());
assertEquals
(
1
,
pageResult
.
getList
().
size
());
assertPojoEquals
(
dbFileConfig
,
pageResult
.
getList
().
get
(
0
));
}
@Test
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -6,10 +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.time.LocalDateTime
;
import
java.util.List
;
@Mapper
...
...
@@ -31,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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2ClientMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -6,10 +6,7 @@ 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
;
import
java.time.LocalDateTime
;
/**
* OAuth2 客户端 Mapper
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -8,11 +8,9 @@ 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.util.Collection
;
import
java.time.LocalDateTime
;
import
java.util.List
;
@Mapper
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuBatchInsertMapper.java
deleted
100644 → 0
浏览文件 @
b43813ab
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
>
{
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -2,14 +2,12 @@ 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.
Lambda
QueryWrapper
;
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.util.Collection
;
import
java.time.LocalDateTime
;
import
java.util.List
;
@Mapper
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleBatchInsertMapper.java
deleted
100644 → 0
浏览文件 @
b43813ab
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
>
{
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -2,44 +2,35 @@ 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.
Lambda
QueryWrapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Select
;
import
java.util.Collection
;
import
java.time.LocalDateTime
;
import
java.util.List
;
@Mapper
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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sensitiveword/SensitiveWordMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsChannelMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
);
}
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java
浏览文件 @
d2d2b5cd
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
);
}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
(
"[initLocalCache
IfUpdate
][缓存部门,数量为:{}]"
,
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
);
});
}
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
(
"[initLocalCache
IfUpdate
][缓存 OAuth2 客户端,数量为:{}]"
,
clients
.
size
());
log
.
info
(
"[initLocalCache][缓存 OAuth2 客户端,数量为:{}]"
,
clients
.
size
());
// 第二步:构建缓存。
clientCache
=
convertMap
(
clients
,
OAuth2ClientDO:
:
getClientId
);
// 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
this
.
maxUpdateTime
=
getMaxValue
(
clients
,
OAuth2ClientDO:
:
getUpdateTime
);
}
@Override
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
(
"[initLocalCache
IfUpdate
][缓存菜单,数量为:{}]"
,
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
...
...
@@ -219,7 +185,7 @@ public class MenuServiceImpl implements MenuService {
}
// 创建新数组,避免缓存被修改
return
menuCache
.
values
().
stream
().
filter
(
menu
->
menuTypes
.
contains
(
menu
.
getType
())
&&
menusStatuses
.
contains
(
menu
.
getStatus
()))
&&
menusStatuses
.
contains
(
menu
.
getStatus
()))
.
collect
(
Collectors
.
toList
());
}
...
...
@@ -231,8 +197,8 @@ public class MenuServiceImpl implements MenuService {
return
Collections
.
emptyList
();
}
return
menuCache
.
values
().
stream
().
filter
(
menu
->
menuIds
.
contains
(
menu
.
getId
())
&&
menuTypes
.
contains
(
menu
.
getType
())
&&
menusStatuses
.
contains
(
menu
.
getStatus
()))
&&
menuTypes
.
contains
(
menu
.
getType
())
&&
menusStatuses
.
contains
(
menu
.
getStatus
()))
.
collect
(
Collectors
.
toList
());
}
...
...
@@ -272,7 +238,7 @@ public class MenuServiceImpl implements MenuService {
}
// 父菜单必须是目录或者菜单类型
if
(!
MenuTypeEnum
.
DIR
.
getType
().
equals
(
menu
.
getType
())
&&
!
MenuTypeEnum
.
MENU
.
getType
().
equals
(
menu
.
getType
()))
{
&&
!
MenuTypeEnum
.
MENU
.
getType
().
equals
(
menu
.
getType
()))
{
throw
ServiceExceptionUtil
.
exception
(
MENU_PARENT_NOT_DIR_OR_MENU
);
}
}
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
initLocalCache
IfUpdateForRoleMenu
(
LocalDateTime
maxUpdateTime
)
{
void
initLocalCache
ForRoleMenu
(
)
{
// 注意:忽略自动多租户,因为要全局初始化缓存
TenantUtils
.
executeIgnore
(()
->
{
// 第一步:基于 maxUpdateTime 判断缓存是否刷新。
// 如果没有增量的数据变化,则不进行本地缓存的刷新
if
(
maxUpdateTime
!=
null
&&
roleMenuMapper
.
selectCountByUpdateTimeGt
(
maxUpdateTime
)
==
0
)
{
log
.
info
(
"[initLocalCacheIfUpdateForRoleMenu][数据未发生变化({}),本地缓存不刷新]"
,
maxUpdateTime
);
return
;
}
// 第一步:查询数据
List
<
RoleMenuDO
>
roleMenus
=
roleMenuMapper
.
selectList
();
log
.
info
(
"[initLocalCache
IfUpdate
ForRoleMenu][缓存角色与菜单,数量为:{}]"
,
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
initLocalCache
IfUpdateForUserRole
(
LocalDateTime
maxUpdateTime
)
{
void
initLocalCache
ForUserRole
(
)
{
// 注意:忽略自动多租户,因为要全局初始化缓存
TenantUtils
.
executeIgnore
(()
->
{
// 第一步:基于 maxUpdateTime 判断缓存是否刷新。
// 如果没有增量的数据变化,则不进行本地缓存的刷新
if
(
maxUpdateTime
!=
null
&&
userRoleMapper
.
selectCountByUpdateTimeGt
(
maxUpdateTime
)
==
0
)
{
log
.
info
(
"[initLocalCacheIfUpdateForUserRole][数据未发生变化({}),本地缓存不刷新]"
,
maxUpdateTime
);
return
;
}
// 第一步:加载数据
List
<
UserRoleDO
>
userRoles
=
userRoleMapper
.
selectList
();
log
.
info
(
"[initLocalCache
IfUpdate
ForUserRole][缓存用户与角色,数量为:{}]"
,
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
))
{
roleMenu
BatchInsertMapper
.
save
Batch
(
CollectionUtils
.
convertList
(
createMenuIds
,
menuId
->
{
roleMenu
Mapper
.
insert
Batch
(
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
))
{
userRole
BatchInsertMapper
.
save
Batch
(
CollectionUtils
.
convertList
(
createRoleIds
,
roleId
->
{
userRole
Mapper
.
insert
Batch
(
CollectionUtils
.
convertList
(
createRoleIds
,
roleId
->
{
UserRoleDO
entity
=
new
UserRoleDO
();
entity
.
setUserId
(
userId
);
entity
.
setRoleId
(
roleId
);
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjectUtil;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.collection.CollectionUtils
;
import
cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore
;
import
cn.iocoder.yudao.framework.tenant.core.util.TenantUtils
;
import
cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO
;
...
...
@@ -22,9 +21,7 @@ import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer;
import
com.google.common.annotations.VisibleForTesting
;
import
lombok.Getter
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.annotation.Lazy
;
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
;
...
...
@@ -33,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
;
...
...
@@ -49,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()}
...
...
@@ -63,11 +53,6 @@ public class RoleServiceImpl implements RoleService {
*/
@Getter
private
volatile
Map
<
Long
,
RoleDO
>
roleCache
;
/**
* 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
*/
@Getter
private
volatile
LocalDateTime
maxUpdateTime
;
@Resource
private
PermissionService
permissionService
;
...
...
@@ -78,49 +63,20 @@ public class RoleServiceImpl implements RoleService {
@Resource
private
RoleProducer
roleProducer
;
@Resource
@Lazy
// 注入自己,所以延迟加载
private
RoleService
self
;
/**
* 初始化 {@link #roleCache} 缓存
*/
@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
(
"[initLocalCache
IfUpdate
][缓存角色,数量为:{}]"
,
roleList
.
size
());
log
.
info
(
"[initLocalCache][缓存角色,数量为:{}]"
,
roleList
.
size
());
// 第二步:构建缓存
。
// 第二步:构建缓存
roleCache
=
CollectionUtils
.
convertMap
(
roleList
,
RoleDO:
:
getId
);
// 第三步:设置最新的 maxUpdateTime,用于下次的增量判断。
this
.
maxUpdateTime
=
CollectionUtils
.
getMaxValue
(
roleList
,
RoleDO:
:
getUpdateTime
);
});
}
...
...
@@ -215,8 +171,8 @@ public class RoleServiceImpl implements RoleService {
@Override
public
List
<
RoleDO
>
getRoles
(
@Nullable
Collection
<
Integer
>
statuses
)
{
if
(
CollUtil
.
isEmpty
(
statuses
))
{
return
roleMapper
.
selectList
();
}
return
roleMapper
.
selectList
();
}
return
roleMapper
.
selectListByStatus
(
statuses
);
}
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
(
"[initLocalCache
IfUpdate
][缓存敏感词,数量为:{}]"
,
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
)
{
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java
浏览文件 @
d2d2b5cd
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.collection.CollectionUtils
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO
;
...
...
@@ -13,22 +11,19 @@ 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.util.Collection
;
import
java.time.LocalDateTime
;
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
;
/**
* 短信渠道
Service
实现类
* 短信渠道
Service
实现类
*
* @author zzf
*/
...
...
@@ -36,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
;
...
...
@@ -62,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
(
"[initLocalCache
IfUpdate
][缓存短信渠道,数量为:{}]"
,
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
...
...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java
浏览文件 @
d2d2b5cd
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
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -25,8 +25,7 @@ import javax.validation.Validator;
import
static
cn
.
iocoder
.
yudao
.
framework
.
test
.
core
.
util
.
AssertUtils
.
assertPojoEquals
;
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
.
AUTH_LOGIN_BAD_CREDENTIALS
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.
AUTH_LOGIN_USER_DISABLED
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.*;
import
static
org
.
mockito
.
ArgumentMatchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.*;
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java
浏览文件 @
d2d2b5cd
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
;
...
...
@@ -54,10 +52,9 @@ public class DeptServiceTest extends BaseDbUnitTest {
// 清理租户上下文
TenantContextHolder
.
clear
();
}
@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
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
.*;
...
...
@@ -28,10 +27,10 @@ import static org.junit.jupiter.api.Assertions.*;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
* {@link OAuth2ClientServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
* {@link OAuth2ClientServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
@Import
(
OAuth2ClientServiceImpl
.
class
)
public
class
OAuth2ClientServiceImplTest
extends
BaseDbUnitTest
{
...
...
@@ -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
...
...
@@ -158,27 +155,27 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
@Test
public
void
testGetOAuth2ClientPage
()
{
// mock 数据
OAuth2ClientDO
dbOAuth2Client
=
randomPojo
(
OAuth2ClientDO
.
class
,
o
->
{
// 等会查询到
o
.
setName
(
"潜龙"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
});
oauth2ClientMapper
.
insert
(
dbOAuth2Client
);
// 测试 name 不匹配
oauth2ClientMapper
.
insert
(
cloneIgnoreId
(
dbOAuth2Client
,
o
->
o
.
setName
(
"凤凰"
)));
// 测试 status 不匹配
oauth2ClientMapper
.
insert
(
cloneIgnoreId
(
dbOAuth2Client
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
DISABLE
.
getStatus
())));
// 准备参数
OAuth2ClientPageReqVO
reqVO
=
new
OAuth2ClientPageReqVO
();
reqVO
.
setName
(
"龙"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
// 调用
PageResult
<
OAuth2ClientDO
>
pageResult
=
oauth2ClientService
.
getOAuth2ClientPage
(
reqVO
);
// 断言
assertEquals
(
1
,
pageResult
.
getTotal
());
assertEquals
(
1
,
pageResult
.
getList
().
size
());
assertPojoEquals
(
dbOAuth2Client
,
pageResult
.
getList
().
get
(
0
));
// mock 数据
OAuth2ClientDO
dbOAuth2Client
=
randomPojo
(
OAuth2ClientDO
.
class
,
o
->
{
// 等会查询到
o
.
setName
(
"潜龙"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
});
oauth2ClientMapper
.
insert
(
dbOAuth2Client
);
// 测试 name 不匹配
oauth2ClientMapper
.
insert
(
cloneIgnoreId
(
dbOAuth2Client
,
o
->
o
.
setName
(
"凤凰"
)));
// 测试 status 不匹配
oauth2ClientMapper
.
insert
(
cloneIgnoreId
(
dbOAuth2Client
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
DISABLE
.
getStatus
())));
// 准备参数
OAuth2ClientPageReqVO
reqVO
=
new
OAuth2ClientPageReqVO
();
reqVO
.
setName
(
"龙"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
// 调用
PageResult
<
OAuth2ClientDO
>
pageResult
=
oauth2ClientService
.
getOAuth2ClientPage
(
reqVO
);
// 断言
assertEquals
(
1
,
pageResult
.
getTotal
());
assertEquals
(
1
,
pageResult
.
getList
().
size
());
assertPojoEquals
(
dbOAuth2Client
,
pageResult
.
getList
().
get
(
0
));
}
@Test
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -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
testInitLocalCache
IfUpdate
ForRoleMenu
()
{
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
.
initLocalCache
IfUpdateForRoleMenu
(
null
);
permissionService
.
initLocalCache
ForRoleMenu
(
);
// 断言 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
testInitLocalCache
IfUpdate
ForUserRole
()
{
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
.
initLocalCache
IfUpdateForUserRole
(
null
);
permissionService
.
initLocalCache
ForUserRole
(
);
// 断言 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
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.permission;
import
cn.hutool.core.util.RandomUtil
;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest
;
import
cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO
;
...
...
@@ -21,11 +20,9 @@ import org.springframework.context.annotation.Import;
import
javax.annotation.Resource
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildLocalDate
Time
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
LocalDateTimeUtils
.
build
Time
;
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
.*;
...
...
@@ -61,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
...
...
@@ -129,7 +124,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
Long
roleId
=
roleDO
.
getId
();
//调用
Set
<
Long
>
deptIdSet
=
Arrays
.
asList
(
1L
,
2L
,
3L
,
4L
,
5L
).
stream
().
collect
(
Collectors
.
toSet
(
));
Set
<
Long
>
deptIdSet
=
new
HashSet
<>(
Arrays
.
asList
(
1L
,
2L
,
3L
,
4L
,
5L
));
roleService
.
updateRoleDataScope
(
roleId
,
DataScopeEnum
.
DEPT_CUSTOM
.
getScope
(),
deptIdSet
);
//断言
...
...
@@ -137,7 +132,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
assertEquals
(
DataScopeEnum
.
DEPT_CUSTOM
.
getScope
(),
newRoleDO
.
getDataScope
());
Set
<
Long
>
newDeptIdSet
=
newRoleDO
.
getDataScopeDeptIds
();
assert
True
(
deptIdSet
.
size
()
==
newDeptIdSet
.
size
());
assert
Equals
(
deptIdSet
.
size
(),
newDeptIdSet
.
size
());
deptIdSet
.
stream
().
forEach
(
d
->
assertTrue
(
newDeptIdSet
.
contains
(
d
)));
verify
(
roleProducer
).
sendRoleRefreshMessage
();
...
...
@@ -166,7 +161,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
o
.
setName
(
"土豆"
);
o
.
setCode
(
"tudou"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
8
));
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
8
));
});
roleMapper
.
insert
(
dbRole
);
// 测试 name 不匹配
...
...
@@ -174,13 +169,13 @@ public class RoleServiceTest extends BaseDbUnitTest {
// 测试 code 不匹配
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCode
(
"hong"
)));
// 测试 createTime 不匹配
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
16
))));
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
16
))));
// 准备参数
RoleExportReqVO
reqVO
=
new
RoleExportReqVO
();
reqVO
.
setName
(
"土豆"
);
reqVO
.
setCode
(
"tu"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2022
,
2
,
1
),
buildLocalDate
Time
(
2022
,
2
,
12
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2022
,
2
,
1
),
build
Time
(
2022
,
2
,
12
)}));
// 调用
List
<
RoleDO
>
list
=
roleService
.
getRoleList
(
reqVO
);
...
...
@@ -196,7 +191,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
o
.
setName
(
"土豆"
);
o
.
setCode
(
"tudou"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
8
));
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
8
));
});
roleMapper
.
insert
(
dbRole
);
// 测试 name 不匹配
...
...
@@ -204,13 +199,13 @@ public class RoleServiceTest extends BaseDbUnitTest {
// 测试 code 不匹配
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCode
(
"hong"
)));
// 测试 createTime 不匹配
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
16
))));
roleMapper
.
insert
(
cloneIgnoreId
(
dbRole
,
o
->
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
16
))));
// 准备参数
RolePageReqVO
reqVO
=
new
RolePageReqVO
();
reqVO
.
setName
(
"土豆"
);
reqVO
.
setCode
(
"tu"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2022
,
2
,
1
),
buildLocalDate
Time
(
2022
,
2
,
12
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2022
,
2
,
1
),
build
Time
(
2022
,
2
,
12
)}));
// 调用
PageResult
<
RoleDO
>
pageResult
=
roleService
.
getRolePage
(
reqVO
);
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.sensitiveword;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.collection.SetUtils
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest
;
import
cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExportReqVO
;
...
...
@@ -21,7 +20,7 @@ import java.time.LocalDateTime;
import
java.util.Arrays
;
import
java.util.List
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildLocalDate
Time
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
LocalDateTimeUtils
.
build
Time
;
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
;
...
...
@@ -61,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 缓存
...
...
@@ -145,7 +142,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
o
.
setName
(
"笨蛋"
);
o
.
setTags
(
Arrays
.
asList
(
"论坛"
,
"蔬菜"
));
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
8
));
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
8
));
});
sensitiveWordMapper
.
insert
(
dbSensitiveWord
);
// 测试 name 不匹配
...
...
@@ -153,13 +150,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
// 测试 tags 不匹配
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setTags
(
Arrays
.
asList
(
"短信"
,
"日用品"
))));
// 测试 createTime 不匹配
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
16
))));
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
16
))));
// 准备参数
SensitiveWordPageReqVO
reqVO
=
new
SensitiveWordPageReqVO
();
reqVO
.
setName
(
"笨"
);
reqVO
.
setTag
(
"论坛"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2022
,
2
,
1
),
buildLocalDate
Time
(
2022
,
2
,
12
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2022
,
2
,
1
),
build
Time
(
2022
,
2
,
12
)}));
// 调用
PageResult
<
SensitiveWordDO
>
pageResult
=
sensitiveWordService
.
getSensitiveWordPage
(
reqVO
);
...
...
@@ -176,7 +173,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
o
.
setName
(
"笨蛋"
);
o
.
setTags
(
Arrays
.
asList
(
"论坛"
,
"蔬菜"
));
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
8
));
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
8
));
});
sensitiveWordMapper
.
insert
(
dbSensitiveWord
);
// 测试 name 不匹配
...
...
@@ -184,13 +181,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
// 测试 tags 不匹配
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setTags
(
Arrays
.
asList
(
"短信"
,
"日用品"
))));
// 测试 createTime 不匹配
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setCreateTime
(
DateUtils
.
buildLocalDate
Time
(
2022
,
2
,
16
))));
sensitiveWordMapper
.
insert
(
cloneIgnoreId
(
dbSensitiveWord
,
o
->
o
.
setCreateTime
(
build
Time
(
2022
,
2
,
16
))));
// 准备参数
SensitiveWordExportReqVO
reqVO
=
new
SensitiveWordExportReqVO
();
reqVO
.
setName
(
"笨"
);
reqVO
.
setTag
(
"论坛"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2022
,
2
,
1
),
buildLocalDate
Time
(
2022
,
2
,
12
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2022
,
2
,
1
),
build
Time
(
2022
,
2
,
12
)}));
// 调用
List
<
SensitiveWordDO
>
list
=
sensitiveWordService
.
getSensitiveWordList
(
reqVO
);
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java
浏览文件 @
d2d2b5cd
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
.
DateUtils
.
buildLocalDateTime
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
object
.
ObjectUtils
.
max
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
LocalDateTimeUtils
.
buildTime
;
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
)));
...
...
@@ -159,7 +154,7 @@ public class SmsChannelServiceTest extends BaseDbUnitTest {
SmsChannelDO
dbSmsChannel
=
randomPojo
(
SmsChannelDO
.
class
,
o
->
{
// 等会查询到
o
.
setSignature
(
"芋道源码"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
o
.
setCreateTime
(
build
LocalDate
Time
(
2020
,
12
,
12
));
o
.
setCreateTime
(
buildTime
(
2020
,
12
,
12
));
});
smsChannelMapper
.
insert
(
dbSmsChannel
);
// 测试 signature 不匹配
...
...
@@ -167,12 +162,12 @@ public class SmsChannelServiceTest extends BaseDbUnitTest {
// 测试 status 不匹配
smsChannelMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsChannel
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
DISABLE
.
getStatus
())));
// 测试 createTime 不匹配
smsChannelMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsChannel
,
o
->
o
.
setCreateTime
(
build
LocalDate
Time
(
2020
,
11
,
11
))));
smsChannelMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsChannel
,
o
->
o
.
setCreateTime
(
buildTime
(
2020
,
11
,
11
))));
// 准备参数
SmsChannelPageReqVO
reqVO
=
new
SmsChannelPageReqVO
();
reqVO
.
setSignature
(
"芋道"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
());
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2020
,
12
,
1
),
buildLocalDate
Time
(
2020
,
12
,
24
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2020
,
12
,
1
),
build
Time
(
2020
,
12
,
24
)}));
// 调用
PageResult
<
SmsChannelDO
>
pageResult
=
smsChannelService
.
getSmsChannelPage
(
reqVO
);
...
...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java
浏览文件 @
d2d2b5cd
...
...
@@ -34,7 +34,7 @@ import static cn.hutool.core.bean.BeanUtil.getFieldValue;
import
static
cn
.
hutool
.
core
.
util
.
RandomUtil
.
randomEle
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
object
.
ObjectUtils
.
max
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.*;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildLocalDate
Time
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
LocalDateTimeUtils
.
build
Time
;
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
.*;
...
...
@@ -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
...
...
@@ -205,7 +201,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
o
.
setContent
(
"芋道源码"
);
o
.
setApiTemplateId
(
"yunai"
);
o
.
setChannelId
(
1L
);
o
.
setCreateTime
(
build
LocalDate
Time
(
2021
,
11
,
11
));
o
.
setCreateTime
(
buildTime
(
2021
,
11
,
11
));
});
smsTemplateMapper
.
insert
(
dbSmsTemplate
);
// 测试 type 不匹配
...
...
@@ -221,7 +217,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
// 测试 channelId 不匹配
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setChannelId
(
2L
)));
// 测试 createTime 不匹配
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setCreateTime
(
build
LocalDate
Time
(
2021
,
12
,
12
))));
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setCreateTime
(
buildTime
(
2021
,
12
,
12
))));
// 准备参数
SmsTemplatePageReqVO
reqVO
=
new
SmsTemplatePageReqVO
();
reqVO
.
setType
(
SmsTemplateTypeEnum
.
PROMOTION
.
getType
());
...
...
@@ -230,7 +226,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
reqVO
.
setContent
(
"芋道"
);
reqVO
.
setApiTemplateId
(
"yu"
);
reqVO
.
setChannelId
(
1L
);
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
LocalDateTime
(
2021
,
11
,
1
),
buildLocalDate
Time
(
2021
,
12
,
1
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
build
Time
(
2021
,
11
,
1
),
build
Time
(
2021
,
12
,
1
)}));
// 调用
PageResult
<
SmsTemplateDO
>
pageResult
=
smsTemplateService
.
getSmsTemplatePage
(
reqVO
);
...
...
@@ -250,7 +246,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
o
.
setContent
(
"芋道源码"
);
o
.
setApiTemplateId
(
"yunai"
);
o
.
setChannelId
(
1L
);
o
.
setCreateTime
(
build
LocalDate
Time
(
2021
,
11
,
11
));
o
.
setCreateTime
(
buildTime
(
2021
,
11
,
11
));
});
smsTemplateMapper
.
insert
(
dbSmsTemplate
);
// 测试 type 不匹配
...
...
@@ -266,7 +262,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
// 测试 channelId 不匹配
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setChannelId
(
2L
)));
// 测试 createTime 不匹配
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setCreateTime
(
build
LocalDate
Time
(
2021
,
12
,
12
))));
smsTemplateMapper
.
insert
(
ObjectUtils
.
cloneIgnoreId
(
dbSmsTemplate
,
o
->
o
.
setCreateTime
(
buildTime
(
2021
,
12
,
12
))));
// 准备参数
SmsTemplateExportReqVO
reqVO
=
new
SmsTemplateExportReqVO
();
reqVO
.
setType
(
SmsTemplateTypeEnum
.
PROMOTION
.
getType
());
...
...
@@ -275,8 +271,7 @@ public class SmsTemplateServiceTest extends BaseDbUnitTest {
reqVO
.
setContent
(
"芋道"
);
reqVO
.
setApiTemplateId
(
"yu"
);
reqVO
.
setChannelId
(
1L
);
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
buildLocalDateTime
(
2021
,
11
,
1
),
buildLocalDateTime
(
2021
,
12
,
1
)}));
reqVO
.
setCreateTime
((
new
LocalDateTime
[]{
buildTime
(
2021
,
11
,
1
),
buildTime
(
2021
,
12
,
1
)}));
// 调用
List
<
SmsTemplateDO
>
list
=
smsTemplateService
.
getSmsTemplateList
(
reqVO
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论