Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
计算机应用开发
后
后端
J
Java
后台管理
Ruoyi Vue Pro
提交
66ebb71b
R
Ruoyi Vue Pro
项目概览
计算机应用开发
/
后端
/
Java
/
后台管理
/
Ruoyi Vue Pro
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Ruoyi Vue Pro
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
66ebb71b
编写于
2月 26, 2022
作者:
公众号-芋道源码
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Redis 最低版本 5.0.0 检测,解决搭建环境过程中无法理解 XREADGROUP 指令的报错
上级
c64bb81c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
158 addition
and
19 deletion
+158
-19
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DocumentEnum.java
...cn/iocoder/yudao/framework/common/enums/DocumentEnum.java
+20
-0
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java
...r/yudao/framework/mq/config/YudaoMQAutoConfiguration.java
+22
-0
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java
...e/system/service/tenant/TenantPackageServiceImplTest.java
+84
-15
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java
...o/module/system/service/tenant/TenantServiceImplTest.java
+31
-4
更新日志.md
更新日志.md
+1
-0
未找到文件。
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DocumentEnum.java
0 → 100644
浏览文件 @
66ebb71b
package
cn.iocoder.yudao.framework.common.enums
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 文档地址
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public
enum
DocumentEnum
{
REDIS_INSTALL
(
"https://gitee.com/zhijiantianya/ruoyi-vue-pro/issues/I4VCSJ"
,
"Redis 安装文档"
);
private
final
String
url
;
private
final
String
memo
;
}
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java
浏览文件 @
66ebb71b
package
cn.iocoder.yudao.framework.mq.config
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.system.SystemUtil
;
import
cn.iocoder.yudao.framework.common.enums.DocumentEnum
;
import
cn.iocoder.yudao.framework.mq.core.RedisMQTemplate
;
import
cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor
;
import
cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener
;
...
...
@@ -10,10 +13,12 @@ import lombok.extern.slf4j.Slf4j;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisServerCommands
;
import
org.springframework.data.redis.connection.stream.Consumer
;
import
org.springframework.data.redis.connection.stream.ObjectRecord
;
import
org.springframework.data.redis.connection.stream.ReadOffset
;
import
org.springframework.data.redis.connection.stream.StreamOffset
;
import
org.springframework.data.redis.core.RedisCallback
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.data.redis.listener.ChannelTopic
;
...
...
@@ -22,6 +27,7 @@ import org.springframework.data.redis.stream.DefaultStreamMessageListenerContain
import
org.springframework.data.redis.stream.StreamMessageListenerContainer
;
import
java.util.List
;
import
java.util.Properties
;
/**
* 消息队列配置类
...
...
@@ -73,6 +79,7 @@ public class YudaoMQAutoConfiguration {
public
StreamMessageListenerContainer
<
String
,
ObjectRecord
<
String
,
String
>>
redisStreamMessageListenerContainer
(
RedisMQTemplate
redisMQTemplate
,
List
<
AbstractStreamMessageListener
<?>>
listeners
)
{
RedisTemplate
<
String
,
?>
redisTemplate
=
redisMQTemplate
.
getRedisTemplate
();
checkRedisVersion
(
redisTemplate
);
// 第一步,创建 StreamMessageListenerContainer 容器
// 创建 options 配置
StreamMessageListenerContainer
.
StreamMessageListenerContainerOptions
<
String
,
ObjectRecord
<
String
,
String
>>
containerOptions
=
...
...
@@ -118,4 +125,19 @@ public class YudaoMQAutoConfiguration {
return
String
.
format
(
"%s@%d"
,
SystemUtil
.
getHostInfo
().
getAddress
(),
SystemUtil
.
getCurrentPID
());
}
/**
* 校验 Redis 版本号,是否满足最低的版本号要求!
*/
private
static
void
checkRedisVersion
(
RedisTemplate
<
String
,
?>
redisTemplate
)
{
// 获得 Redis 版本
Properties
info
=
redisTemplate
.
execute
((
RedisCallback
<
Properties
>)
RedisServerCommands:
:
info
);
String
version
=
MapUtil
.
getStr
(
info
,
"redis_version"
);
// 校验最低版本必须大于等于 5.0.0
int
majorVersion
=
Integer
.
parseInt
(
StrUtil
.
subBefore
(
version
,
'.'
,
false
));
if
(
majorVersion
<
7
)
{
throw
new
IllegalStateException
(
StrUtil
.
format
(
"您当前的 Redis 版本为 {},小于最低要求的 5.0.0 版本!"
+
"请参考 {} 文档进行安装。"
,
version
,
DocumentEnum
.
REDIS_INSTALL
.
getUrl
()));
}
}
}
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java
浏览文件 @
66ebb71b
package
cn.iocoder.yudao.module.system.service.tenant
;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageUpdateReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper
;
import
cn.iocoder.yudao.module.system.test.BaseDbUnitTest
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.mock.mockito.MockBean
;
import
org.springframework.context.annotation.Import
;
import
javax.annotation.Resource
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildTime
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
object
.
ObjectUtils
.
cloneIgnoreId
;
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
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
test
.
core
.
util
.
RandomUtils
.
randomPojo
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.
TENANT_PACKAGE_NOT_EXISTS
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.*;
import
static
java
.
util
.
Arrays
.
asList
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.*;
import
static
org
.
mockito
.
ArgumentMatchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
* {@link TenantPackageServiceImpl} 的单元测试类
...
...
@@ -34,6 +42,9 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest {
@Resource
private
TenantPackageMapper
tenantPackageMapper
;
@MockBean
private
TenantService
tenantService
;
@Test
public
void
testCreateTenantPackage_success
()
{
// 准备参数
...
...
@@ -57,12 +68,21 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest {
TenantPackageUpdateReqVO
reqVO
=
randomPojo
(
TenantPackageUpdateReqVO
.
class
,
o
->
{
o
.
setId
(
dbTenantPackage
.
getId
());
// 设置更新的 ID
});
// mock 方法
Long
tenantId01
=
randomLongId
();
Long
tenantId02
=
randomLongId
();
when
(
tenantService
.
getTenantListByPackageId
(
eq
(
reqVO
.
getId
()))).
thenReturn
(
asList
(
randomPojo
(
TenantDO
.
class
,
o
->
o
.
setId
(
tenantId01
)),
randomPojo
(
TenantDO
.
class
,
o
->
o
.
setId
(
tenantId02
))));
// 调用
tenantPackageService
.
updateTenantPackage
(
reqVO
);
// 校验是否更新正确
TenantPackageDO
tenantPackage
=
tenantPackageMapper
.
selectById
(
reqVO
.
getId
());
// 获取最新的
assertPojoEquals
(
reqVO
,
tenantPackage
);
// 校验调用租户的菜单
verify
(
tenantService
).
updateTenantRoleMenu
(
eq
(
tenantId01
),
eq
(
reqVO
.
getMenuIds
()));
verify
(
tenantService
).
updateTenantRoleMenu
(
eq
(
tenantId02
),
eq
(
reqVO
.
getMenuIds
()));
}
@Test
...
...
@@ -81,6 +101,8 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest {
tenantPackageMapper
.
insert
(
dbTenantPackage
);
// @Sql: 先插入出一条存在的数据
// 准备参数
Long
id
=
dbTenantPackage
.
getId
();
// mock 租户未使用该套餐
when
(
tenantService
.
getTenantCountByPackageId
(
eq
(
id
))).
thenReturn
(
0
);
// 调用
tenantPackageService
.
deleteTenantPackage
(
id
);
...
...
@@ -97,31 +119,45 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest {
assertServiceException
(()
->
tenantPackageService
.
deleteTenantPackage
(
id
),
TENANT_PACKAGE_NOT_EXISTS
);
}
@Test
// TODO 请修改 null 为需要的值
@Test
public
void
testDeleteTenantPackage_used
()
{
// mock 数据
TenantPackageDO
dbTenantPackage
=
randomPojo
(
TenantPackageDO
.
class
);
tenantPackageMapper
.
insert
(
dbTenantPackage
);
// @Sql: 先插入出一条存在的数据
// 准备参数
Long
id
=
dbTenantPackage
.
getId
();
// mock 租户在使用该套餐
when
(
tenantService
.
getTenantCountByPackageId
(
eq
(
id
))).
thenReturn
(
1
);
// 调用, 并断言异常
assertServiceException
(()
->
tenantPackageService
.
deleteTenantPackage
(
id
),
TENANT_PACKAGE_USED
);
}
@Test
public
void
testGetTenantPackagePage
()
{
// mock 数据
TenantPackageDO
dbTenantPackage
=
randomPojo
(
TenantPackageDO
.
class
,
o
->
{
// 等会查询到
o
.
setName
(
null
);
o
.
setStatus
(
null
);
o
.
setRemark
(
null
);
o
.
setCreateTime
(
null
);
o
.
setName
(
"芋道源码"
);
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
()
);
o
.
setRemark
(
"源码解析"
);
o
.
setCreateTime
(
buildTime
(
2022
,
10
,
10
)
);
});
tenantPackageMapper
.
insert
(
dbTenantPackage
);
// 测试 name 不匹配
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setName
(
null
)));
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setName
(
"源码"
)));
// 测试 status 不匹配
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setStatus
(
null
)));
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
DISABLE
.
getStatus
()
)));
// 测试 remark 不匹配
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setRemark
(
null
)));
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setRemark
(
"解析"
)));
// 测试 createTime 不匹配
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setCreateTime
(
null
)));
tenantPackageMapper
.
insert
(
cloneIgnoreId
(
dbTenantPackage
,
o
->
o
.
setCreateTime
(
buildTime
(
2022
,
11
,
11
)
)));
// 准备参数
TenantPackagePageReqVO
reqVO
=
new
TenantPackagePageReqVO
();
reqVO
.
setName
(
null
);
reqVO
.
setStatus
(
null
);
reqVO
.
setRemark
(
null
);
reqVO
.
setBeginCreateTime
(
null
);
reqVO
.
setEndCreateTime
(
null
);
reqVO
.
setName
(
"芋道"
);
reqVO
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
()
);
reqVO
.
setRemark
(
"源码"
);
reqVO
.
setBeginCreateTime
(
buildTime
(
2022
,
10
,
9
)
);
reqVO
.
setEndCreateTime
(
buildTime
(
2022
,
10
,
11
)
);
// 调用
PageResult
<
TenantPackageDO
>
pageResult
=
tenantPackageService
.
getTenantPackagePage
(
reqVO
);
...
...
@@ -131,4 +167,37 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest {
assertPojoEquals
(
dbTenantPackage
,
pageResult
.
getList
().
get
(
0
));
}
@Test
public
void
testValidTenantPackage_success
()
{
// mock 数据
TenantPackageDO
dbTenantPackage
=
randomPojo
(
TenantPackageDO
.
class
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
ENABLE
.
getStatus
()));
tenantPackageMapper
.
insert
(
dbTenantPackage
);
// @Sql: 先插入出一条存在的数据
// 调用
TenantPackageDO
result
=
tenantPackageService
.
validTenantPackage
(
dbTenantPackage
.
getId
());
// 断言
assertPojoEquals
(
dbTenantPackage
,
result
);
}
@Test
public
void
testValidTenantPackage_notExists
()
{
// 准备参数
Long
id
=
randomLongId
();
// 调用, 并断言异常
assertServiceException
(()
->
tenantPackageService
.
validTenantPackage
(
id
),
TENANT_PACKAGE_NOT_EXISTS
);
}
@Test
public
void
testValidTenantPackage_disable
()
{
// mock 数据
TenantPackageDO
dbTenantPackage
=
randomPojo
(
TenantPackageDO
.
class
,
o
->
o
.
setStatus
(
CommonStatusEnum
.
DISABLE
.
getStatus
()));
tenantPackageMapper
.
insert
(
dbTenantPackage
);
// @Sql: 先插入出一条存在的数据
// 调用, 并断言异常
assertServiceException
(()
->
tenantPackageService
.
validTenantPackage
(
dbTenantPackage
.
getId
()),
TENANT_PACKAGE_DISABLE
,
dbTenantPackage
.
getName
());
}
}
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceTest.java
→
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantService
Impl
Test.java
浏览文件 @
66ebb71b
package
cn.iocoder.yudao.module.system.service.tenant
;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.tenant.config.TenantProperties
;
import
cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO
;
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.controller.admin.tenant.vo.tenant.TenantUpdateReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper
;
import
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.module.system.mq.producer.tenant.TenantProducer
;
import
cn.iocoder.yudao.module.system.service.permission.MenuService
;
import
cn.iocoder.yudao.module.system.service.permission.PermissionService
;
import
cn.iocoder.yudao.module.system.service.permission.RoleService
;
import
cn.iocoder.yudao.module.system.service.user.AdminUserService
;
import
cn.iocoder.yudao.module.system.test.BaseDbUnitTest
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.mock.mockito.MockBean
;
import
org.springframework.context.annotation.Import
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.
TENANT_NOT_EXISTS
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
buildTime
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
object
.
ObjectUtils
.
cloneIgnoreId
;
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
.
TENANT_NOT_EXISTS
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.*;
/**
* {@link TenantServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
@Import
(
TenantServiceImpl
.
class
)
public
class
TenantServiceTest
extends
BaseDbUnitTest
{
public
class
TenantService
Impl
Test
extends
BaseDbUnitTest
{
@Resource
private
TenantServiceImpl
tenantService
;
...
...
@@ -32,6 +44,21 @@ public class TenantServiceTest extends BaseDbUnitTest {
@Resource
private
TenantMapper
tenantMapper
;
@MockBean
private
TenantProperties
tenantProperties
;
@MockBean
private
TenantPackageService
tenantPackageService
;
@MockBean
private
AdminUserService
userService
;
@MockBean
private
RoleService
roleService
;
@MockBean
private
MenuService
menuService
;
@MockBean
private
PermissionService
permissionService
;
@MockBean
private
TenantProducer
tenantProducer
;
@Test
public
void
testCreateTenant_success
()
{
// 准备参数
...
...
更新日志.md
浏览文件 @
66ebb71b
...
...
@@ -32,6 +32,7 @@ TODO
*
【新增】新增
`@TenantIgnore`
注解,标记指定方法,忽略多租户的自动过滤,适合实现跨租户的逻辑
[
commit
](
https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/4d53944771c66b563da1e3d68d3ba43405af8a06
)
*
【新增】租户套餐的管理,可配置每个租户的可使用的功能权限
[
commit
](
https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/6b6d676a6baa2dad16ae9bf03d5002209064c8cc
)
*
【优化】新建租户时,自动创建对应的管理员账号、角色等基础信息
[
commit
](
https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/2598c033a95d4b61d5f5ab3da5f1414f25c510d6
)
*
【优化】Redis 最低版本 5.0.0 检测,解决搭建环境过程中无法理解 XREADGROUP 指令的报错
[
commit
](
)
### 🐞 Bug Fixes
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录