From b5f708114be076b1cba1fcfa2df78e21200abe8e Mon Sep 17 00:00:00 2001
From: niudehua <657563945@qq.com>
Date: Sat, 6 Mar 2021 22:47:00 +0800
Subject: [PATCH 01/17] =?UTF-8?q?knife4j=20=E7=89=88=E6=9C=AC=20=E6=94=B9?=
=?UTF-8?q?=E4=B8=BA=202.x=20=E8=A7=A3=E5=86=B3=20swagger=20=E5=86=B2?=
=?UTF-8?q?=E7=AA=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../swagger/config/SwaggerAutoConfiguration.java | 14 ++++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/pom.xml b/pom.xml
index bab83344ee..5ee4b2191d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
2.4.2
- 3.0.2
+ 2.0.8
5.1.46
1.2.4
diff --git a/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
index b550511aff..d544c4a2a2 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
@@ -10,15 +10,17 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.service.*;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
-import springfox.documentation.service.ApiKey;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -30,7 +32,7 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka
* @author 芋道源码
*/
@Configuration
-@EnableSwagger2
+@EnableSwagger2WebMvc
@EnableKnife4j
@ConditionalOnClass({Docket.class, ApiInfoBuilder.class})
@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true)
From cafb72b5829f5dbbda8dc18a71da622ff8fbcc97 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Sun, 7 Mar 2021 11:45:16 +0800
Subject: [PATCH 02/17] =?UTF-8?q?README=20=E5=A2=9E=E5=8A=A0=E5=8D=95?=
=?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E7=9A=84=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 4597c708f0..0bc06b7ed4 100644
--- a/README.md
+++ b/README.md
@@ -43,11 +43,12 @@
1. 幂等组件:基于 Redis 实现幂等组件,解决重复请求问题
1. 服务保障:基于 Resilience4j 实现服务的稳定性,包括限流、熔断等功能
1. 日志服务:轻量级日志中心,查看远程服务器的日志
+1. 单元测试:基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等
### 研发工具
1. 表单构建:拖动表单元素生成相应的 HTML 代码
-1. 代码生成:前后端代码的生成(Java、Vue、SQL),支持 CRUD 下载
+1. 代码生成:前后端代码的生成(Java、Vue、SQL、单元测试),支持 CRUD 下载
1. 系统接口:基于 Swagger 自动生成相关的 RESTful API 接口文档
1. 数据库文档:基于 Screw 自动生成数据库文档
@@ -83,7 +84,9 @@
| [Spring Boot Admin](https://github.com/skywalking) | Spring Boot 监控平台 | 8.6.0 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.11.4 | |
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
-| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码| 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
+| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
+| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.0 | - |
+| [Mockito](https://junit.org/junit5/) | Java Mock 框架 | 3.6.28 | - |
**前端**
@@ -125,7 +128,7 @@
|
- |
+ - |
From 4a23698876bfe47e75502a6ac4dae7e23f902b9b Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Sun, 7 Mar 2021 20:21:03 +0800
Subject: [PATCH 03/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=20WebConfiguration=20?=
=?UTF-8?q?=E6=B3=A8=E9=87=8A=EF=BC=8C=E5=B8=AE=E5=8A=A9=E9=98=85=E8=AF=BB?=
=?UTF-8?q?=E7=9A=84=E4=BA=BA=E7=90=86=E8=A7=A3=20/api=20=E5=89=8D?=
=?UTF-8?q?=E7=BC=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
.../《芋道 Spring Boot 安全框架 Spring Security 入门》.md | 1 -
.../《芋道 Spring Boot 服务容错 Resilience4j 入门》.md | 1 +
.../dashboard/framework/web/config/WebConfiguration.java | 3 ++-
4 files changed, 4 insertions(+), 3 deletions(-)
delete mode 100644 src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 安全框架 Spring Security 入门》.md
create mode 100644 src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 服务容错 Resilience4j 入门》.md
diff --git a/README.md b/README.md
index 0bc06b7ed4..6af0a5447f 100644
--- a/README.md
+++ b/README.md
@@ -86,7 +86,7 @@
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.0 | - |
-| [Mockito](https://junit.org/junit5/) | Java Mock 框架 | 3.6.28 | - |
+| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.6.28 | - |
**前端**
diff --git a/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 安全框架 Spring Security 入门》.md b/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 安全框架 Spring Security 入门》.md
deleted file mode 100644
index 3fa673793a..0000000000
--- a/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 安全框架 Spring Security 入门》.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 服务容错 Resilience4j 入门》.md b/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 服务容错 Resilience4j 入门》.md
new file mode 100644
index 0000000000..8d6d0335b1
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/resilience4j/《芋道 Spring Boot 服务容错 Resilience4j 入门》.md
@@ -0,0 +1 @@
+
diff --git a/src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
index 9fbe6237ce..b87c490086 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
@@ -27,9 +27,10 @@ public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
+ // 设置 API 前缀,仅仅匹配 controller 包下的
configurer.addPathPrefix(webProperties.getApiPrefix(), clazz ->
clazz.isAnnotationPresent(RestController.class)
- && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage()));
+ && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage())); // 仅仅匹配 controller 包
}
// ========== Filter 相关 ==========
From 5351917b67177f3cfc338f137e3702d0166b55e6 Mon Sep 17 00:00:00 2001
From: niudehua <657563945@qq.com>
Date: Sun, 7 Mar 2021 21:06:39 +0800
Subject: [PATCH 04/17] =?UTF-8?q?=E5=BC=95=E5=85=A5=20swagger-annotations?=
=?UTF-8?q?=201.5.22=20=E6=8E=92=E9=99=A4knife4j3.0.2=20=E4=B8=AD=20swagge?=
=?UTF-8?q?r-annotations=20=E8=A7=A3=E5=86=B3=E4=BE=9D=E8=B5=96=E5=86=B2?=
=?UTF-8?q?=E7=AA=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 14 ++++++++++++--
.../swagger/config/SwaggerAutoConfiguration.java | 4 ++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index 5ee4b2191d..a601b907d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
- 4.0.0
+ 4.0.0
cn.iocoder
dashboard
@@ -24,7 +24,8 @@
2.4.2
- 2.0.8
+ 3.0.2
+ 1.5.22
5.1.46
1.2.4
@@ -104,8 +105,17 @@
guava
com.google.guava
+
+ swagger-annotations
+ io.swagger
+
+
+ io.swagger
+ swagger-annotations
+ ${swagger-annotations.version}
+
diff --git a/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
index d544c4a2a2..21511c37c4 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/swagger/config/SwaggerAutoConfiguration.java
@@ -19,7 +19,7 @@ import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
import java.util.List;
@@ -32,7 +32,7 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka
* @author 芋道源码
*/
@Configuration
-@EnableSwagger2WebMvc
+@EnableSwagger2
@EnableKnife4j
@ConditionalOnClass({Docket.class, ApiInfoBuilder.class})
@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true)
From 113e34b2791ec9b54f5c2cd915890057454d92ed Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Sun, 7 Mar 2021 22:36:08 +0800
Subject: [PATCH 05/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=20dict=20data=20?=
=?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../dal/mysql/dict/SysDictDataMapper.java | 4 +-
.../dict/impl/SysDictDataServiceImpl.java | 22 +--
.../dashboard/util/collection/ArrayUtils.java | 6 +-
.../service/dict/SysDictDataServiceTest.java | 140 +++++++++++++++++-
4 files changed, 150 insertions(+), 22 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
index a9a4a1d55a..f135a6f8cd 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
@@ -15,9 +15,9 @@ import java.util.List;
@Mapper
public interface SysDictDataMapper extends BaseMapperX {
- default SysDictDataDO selectByDictTypeAndLabel(String dictType, String label) {
+ default SysDictDataDO selectByDictTypeAndLabel(String dictType, String value) {
return selectOne(new QueryWrapper().eq("dict_type", dictType)
- .eq("label", label));
+ .eq("value", value));
}
default int selectCountByDictType(String dictType) {
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
index e8ebb82dc4..029e10d27c 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
@@ -2,7 +2,6 @@ package cn.iocoder.dashboard.modules.system.service.dict.impl;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
-import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.SysDictDataCreateReqVO;
@@ -10,9 +9,9 @@ import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.SysDictDataEx
import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.SysDictDataPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.SysDictDataUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dict.SysDictDataMapper;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dict.SysDictDataMapper;
import cn.iocoder.dashboard.modules.system.mq.producer.dict.SysDictDataProducer;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
@@ -28,6 +27,7 @@ import java.util.Comparator;
import java.util.Date;
import java.util.List;
+import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
/**
@@ -156,7 +156,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
@Override
public Long createDictData(SysDictDataCreateReqVO reqVO) {
// 校验正确性
- this.checkCreateOrUpdate(null, reqVO.getLabel(), reqVO.getDictType());
+ this.checkCreateOrUpdate(null, reqVO.getValue(), reqVO.getDictType());
// 插入字典类型
SysDictDataDO dictData = SysDictDataConvert.INSTANCE.convert(reqVO);
dictDataMapper.insert(dictData);
@@ -168,7 +168,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
@Override
public void updateDictData(SysDictDataUpdateReqVO reqVO) {
// 校验正确性
- this.checkCreateOrUpdate(reqVO.getId(), reqVO.getLabel(), reqVO.getDictType());
+ this.checkCreateOrUpdate(reqVO.getId(), reqVO.getValue(), reqVO.getDictType());
// 更新字典类型
SysDictDataDO updateObj = SysDictDataConvert.INSTANCE.convert(reqVO);
dictDataMapper.updateById(updateObj);
@@ -191,13 +191,13 @@ public class SysDictDataServiceImpl implements SysDictDataService {
return dictDataMapper.selectCountByDictType(dictType);
}
- private void checkCreateOrUpdate(Long id, String label, String dictType) {
+ private void checkCreateOrUpdate(Long id, String value, String dictType) {
// 校验自己存在
checkDictDataExists(id);
// 校验字典类型有效
checkDictTypeValid(dictType);
// 校验字典数据的值的唯一性
- checkDictDataValueUnique(id, dictType, label);
+ checkDictDataValueUnique(id, dictType, value);
}
private void checkDictDataValueUnique(Long id, String dictType, String label) {
@@ -207,10 +207,10 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
// 如果 id 为空,说明不用比较是否为相同 id 的字典数据
if (id == null) {
- throw ServiceExceptionUtil.exception(DICT_DATA_VALUE_DUPLICATE);
+ throw exception(DICT_DATA_VALUE_DUPLICATE);
}
if (!dictData.getId().equals(id)) {
- throw ServiceExceptionUtil.exception(DICT_DATA_VALUE_DUPLICATE);
+ throw exception(DICT_DATA_VALUE_DUPLICATE);
}
}
@@ -220,17 +220,17 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
SysDictDataDO dictData = dictDataMapper.selectById(id);
if (dictData == null) {
- throw ServiceExceptionUtil.exception(DICT_DATA_NOT_EXISTS);
+ throw exception(DICT_DATA_NOT_EXISTS);
}
}
private void checkDictTypeValid(String type) {
SysDictTypeDO dictType = dictTypeService.getDictType(type);
if (dictType == null) {
- throw ServiceExceptionUtil.exception(DICT_TYPE_NOT_EXISTS);
+ throw exception(DICT_TYPE_NOT_EXISTS);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(dictType.getStatus())) {
- throw ServiceExceptionUtil.exception(DICT_TYPE_NOT_ENABLE);
+ throw exception(DICT_TYPE_NOT_ENABLE);
}
}
diff --git a/src/main/java/cn/iocoder/dashboard/util/collection/ArrayUtils.java b/src/main/java/cn/iocoder/dashboard/util/collection/ArrayUtils.java
index 7dc9fb6543..e404427323 100644
--- a/src/main/java/cn/iocoder/dashboard/util/collection/ArrayUtils.java
+++ b/src/main/java/cn/iocoder/dashboard/util/collection/ArrayUtils.java
@@ -2,6 +2,8 @@ package cn.iocoder.dashboard.util.collection;
import cn.hutool.core.util.ArrayUtil;
+import java.util.function.Consumer;
+
/**
* Array 工具类
*
@@ -18,11 +20,11 @@ public class ArrayUtils {
* @return 结果数组
*/
@SafeVarargs
- public static T[] append(T object, T... newElements) {
+ public static Consumer[] append(Consumer object, Consumer... newElements) {
if (object == null) {
return newElements;
}
- T[] result = ArrayUtil.newArray(object.getClass(), 1 + newElements.length);
+ Consumer[] result = ArrayUtil.newArray(Consumer.class, 1 + newElements.length);
result[0] = object;
System.arraycopy(newElements, 0, result, 1, newElements.length);
return result;
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
index 318a4afca9..8d976c31f6 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
@@ -12,14 +12,16 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dict.SysDictDataMapper;
import cn.iocoder.dashboard.modules.system.mq.producer.dict.SysDictDataProducer;
import cn.iocoder.dashboard.modules.system.service.dict.impl.SysDictDataServiceImpl;
+import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import java.util.List;
+import java.util.function.Consumer;
-import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.DICT_DATA_NOT_EXISTS;
+import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
import static cn.iocoder.dashboard.util.RandomUtils.*;
@@ -107,8 +109,7 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
o -> o.setStatus(randomCommonStatus()));
// mock 方法
- when(dictTypeService.getDictType(eq(reqVO.getDictType())))
- .thenReturn(randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())));
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
// 调用
Long dictDataId = dictDataService.createDictData(reqVO);
@@ -121,21 +122,66 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
}
+ @Test
+ public void testCreateDictData_dictTypeNotExists() {
+ // 准备参数
+ SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
+ o -> o.setStatus(randomCommonStatus()));
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_TYPE_NOT_EXISTS);
+ }
+
+ @Test
+ public void testCreateDictData_dictTypeNotEnable() {
+ // 准备参数
+ SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
+ o -> o.setStatus(randomCommonStatus()));
+ // mock 方法,数据类型被禁用
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(
+ randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_TYPE_NOT_ENABLE);
+ }
+
+ @Test
+ public void testCreateDictData_dictDataValueDuplicate() {
+ // 准备参数
+ SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
+ o -> o.setStatus(randomCommonStatus()));
+ // mock 方法,字典类型
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
+ // mock dictData 重复 value 重复
+ dictDataMapper.insert(randomDictDataDO(o -> {
+ o.setDictType(reqVO.getDictType());
+ o.setValue(reqVO.getValue()); // 使用 reqVO 的 value,实现重复
+ }));
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_DATA_VALUE_DUPLICATE);
+ }
+
@Test
public void testUpdateDictData_success() {
// mock 数据
- SysDictDataDO dbDictData = randomPojo(SysDictDataDO.class);
+ SysDictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
// 准备参数
SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
o.setId(dbDictData.getId()); // 设置更新的 ID
+ o.setStatus(randomCommonStatus());
});
+ // mock 方法,字典类型
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
// 调用
dictDataService.updateDictData(reqVO);
// 校验是否更新正确
SysDictDataDO dictData = dictDataMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, dictData);
+ // 校验调用
+ verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
}
@Test
@@ -147,18 +193,75 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_DATA_NOT_EXISTS);
}
+ @Test
+ public void testUpdateDictData_dictTypeNotExists() {
+ // mock 数据
+ SysDictDataDO dbDictData = randomDictDataDO();
+ dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
+ // 准备参数
+ SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
+ o.setId(dbDictData.getId()); // 设置更新的 ID
+ o.setStatus(randomCommonStatus());
+ });
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_TYPE_NOT_EXISTS);
+ }
+
+ @Test
+ public void testUpdateDictData_dictTypeNotEnable() {
+ // mock 数据
+ SysDictDataDO dbDictData = randomDictDataDO();
+ dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
+ // 准备参数
+ SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
+ o.setId(dbDictData.getId()); // 设置更新的 ID
+ o.setStatus(randomCommonStatus());
+ });
+ // mock 方法,数据类型被禁用
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(
+ randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_TYPE_NOT_ENABLE);
+ }
+
+ @Test
+ public void testUpdateDictData_dictDataValueDuplicate() {
+ // mock 数据
+ SysDictDataDO dbDictData = randomDictDataDO();
+ dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
+ // 准备参数
+ SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
+ o.setId(dbDictData.getId()); // 设置更新的 ID
+ o.setStatus(randomCommonStatus());
+ });
+ // mock 方法,字典类型
+ when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
+ // mock dictData 重复 value 重复
+ dictDataMapper.insert(randomDictDataDO(o -> {
+ o.setDictType(reqVO.getDictType());
+ o.setValue(reqVO.getValue()); // 使用 reqVO 的 value,实现重复
+ }));
+
+ // 调用, 并断言异常
+ assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_DATA_VALUE_DUPLICATE);
+ }
+
@Test
public void testDeleteDictData_success() {
// mock 数据
- SysDictDataDO dbDictData = randomPojo(SysDictDataDO.class);
+ SysDictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDictData.getId();
// 调用
dictDataService.deleteDictData(id);
- // 校验数据不存在了
- assertNull(dictDataMapper.selectById(id));
+ // 校验数据不存在了
+ assertNull(dictDataMapper.selectById(id));
+ // 校验调用
+ verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
}
@Test
@@ -170,4 +273,27 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
assertServiceException(() -> dictDataService.deleteDictData(id), DICT_DATA_NOT_EXISTS);
}
+ // ========== 随机对象 ==========
+
+ @SafeVarargs
+ private static SysDictDataDO randomDictDataDO(Consumer... consumers) {
+ Consumer consumer = (o) -> {
+ o.setStatus(randomCommonStatus()); // 保证 status 的范围
+ };
+ return randomPojo(SysDictDataDO.class, ArrayUtils.append(consumer, consumers));
+ }
+
+ /**
+ * 生成一个有效的字典类型
+ *
+ * @param type 字典类型
+ * @return SysDictTypeDO 对象
+ */
+ private static SysDictTypeDO randomDictTypeDO(String type) {
+ return randomPojo(SysDictTypeDO.class, o -> {
+ o.setType(type);
+ o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 是开启
+ });
+ }
+
}
From 351d08a2c438c094f4bc577c86c68c017276b332 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Sun, 7 Mar 2021 23:15:27 +0800
Subject: [PATCH 06/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=20dict=20data=20?=
=?UTF-8?q?=E7=9A=84=E6=9C=AC=E5=9C=B0=E7=BC=93=E5=AD=98=E7=9A=84=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../dashboard/util/object/ObjectUtils.java | 10 ++++++
.../service/dict/SysDictDataServiceTest.java | 34 +++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/src/main/java/cn/iocoder/dashboard/util/object/ObjectUtils.java b/src/main/java/cn/iocoder/dashboard/util/object/ObjectUtils.java
index c8b2d2e802..1d652488fa 100644
--- a/src/main/java/cn/iocoder/dashboard/util/object/ObjectUtils.java
+++ b/src/main/java/cn/iocoder/dashboard/util/object/ObjectUtils.java
@@ -19,4 +19,14 @@ public class ObjectUtils {
return result;
}
+ public static > T max(T obj1, T obj2) {
+ if (obj1 == null) {
+ return obj2;
+ }
+ if (obj2 == null) {
+ return obj1;
+ }
+ return obj1.compareTo(obj2) > 0 ? obj1 : obj2;
+ }
+
}
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
index 8d976c31f6..b817072f08 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
@@ -14,13 +14,16 @@ import cn.iocoder.dashboard.modules.system.mq.producer.dict.SysDictDataProducer;
import cn.iocoder.dashboard.modules.system.service.dict.impl.SysDictDataServiceImpl;
import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
+import com.google.common.collect.ImmutableTable;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
+import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
+import static cn.hutool.core.bean.BeanUtil.getFieldValue;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
@@ -193,6 +196,37 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_DATA_NOT_EXISTS);
}
+ /**
+ * 测试加载到新的字典数据的情况
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testInitLocalCache() {
+ // mock 数据
+ SysDictDataDO dictData01 = randomDictDataDO();
+ dictDataMapper.insert(dictData01);
+ SysDictDataDO dictData02 = randomDictDataDO();
+ dictDataMapper.insert(dictData02);
+
+ // 调用
+ dictDataService.initLocalCache();
+ // 断言 labelDictDataCache 缓存
+ ImmutableTable labelDictDataCache =
+ (ImmutableTable) getFieldValue(dictDataService, "labelDictDataCache");
+ assertEquals(2, labelDictDataCache.size());
+ assertPojoEquals(dictData01, labelDictDataCache.get(dictData01.getDictType(), dictData01.getLabel()));
+ assertPojoEquals(dictData02, labelDictDataCache.get(dictData02.getDictType(), dictData02.getLabel()));
+ // 断言 valueDictDataCache 缓存
+ ImmutableTable valueDictDataCache =
+ (ImmutableTable) getFieldValue(dictDataService, "valueDictDataCache");
+ assertEquals(2, valueDictDataCache.size());
+ assertPojoEquals(dictData01, valueDictDataCache.get(dictData01.getDictType(), dictData01.getValue()));
+ assertPojoEquals(dictData02, valueDictDataCache.get(dictData02.getDictType(), dictData02.getValue()));
+ // 断言 maxUpdateTime 缓存
+ Date maxUpdateTime = (Date) getFieldValue(dictDataService, "maxUpdateTime");
+ assertEquals(ObjectUtils.max(dictData01.getUpdateTime(), dictData02.getUpdateTime()), maxUpdateTime);
+ }
+
@Test
public void testUpdateDictData_dictTypeNotExists() {
// mock 数据
From 2249d76d46d7ece06067db2ca2f2a02b65289870 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Mon, 8 Mar 2021 00:21:49 +0800
Subject: [PATCH 07/17] =?UTF-8?q?=E7=AE=80=E5=8C=96=20dict=20data=20?=
=?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=B0=86?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0?=
=?UTF-8?q?=E9=99=A4=E6=B6=89=E5=8F=8A=E7=9A=84=E5=85=AC=E7=94=A8=E6=96=B9?=
=?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=8D=95=E7=8B=AC=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mybatis/core/mapper/BaseMapperX.java | 4 +
.../dal/mysql/dict/SysDictDataMapper.java | 4 +-
.../dict/impl/SysDictDataServiceImpl.java | 12 +-
.../dict/impl/SysDictTypeServiceImpl.java | 10 +-
.../service/dict/SysDictDataServiceTest.java | 240 ++++++++----------
5 files changed, 122 insertions(+), 148 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
index eace96a265..b86fd762ff 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
@@ -28,6 +28,10 @@ public interface BaseMapperX extends BaseMapper {
return selectOne(new QueryWrapper().eq(field, value));
}
+ default Integer selectCount(String field, Object value) {
+ return selectCount(new QueryWrapper().eq(field, value));
+ }
+
default List selectList() {
return selectList(new QueryWrapper<>());
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
index f135a6f8cd..78a4105639 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dict/SysDictDataMapper.java
@@ -15,13 +15,13 @@ import java.util.List;
@Mapper
public interface SysDictDataMapper extends BaseMapperX {
- default SysDictDataDO selectByDictTypeAndLabel(String dictType, String value) {
+ default SysDictDataDO selectByDictTypeAndValue(String dictType, String value) {
return selectOne(new QueryWrapper().eq("dict_type", dictType)
.eq("value", value));
}
default int selectCountByDictType(String dictType) {
- return selectCount(new QueryWrapper().eq("dict_type", dictType));
+ return selectCount("dict_type", dictType);
}
default PageResult selectPage(SysDictDataPageReqVO reqVO) {
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
index 029e10d27c..603a9933ec 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
@@ -15,6 +15,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dict.SysDictDataMapper;
import cn.iocoder.dashboard.modules.system.mq.producer.dict.SysDictDataProducer;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableTable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
@@ -200,8 +201,9 @@ public class SysDictDataServiceImpl implements SysDictDataService {
checkDictDataValueUnique(id, dictType, value);
}
- private void checkDictDataValueUnique(Long id, String dictType, String label) {
- SysDictDataDO dictData = dictDataMapper.selectByDictTypeAndLabel(dictType, label);
+ @VisibleForTesting
+ public void checkDictDataValueUnique(Long id, String dictType, String value) {
+ SysDictDataDO dictData = dictDataMapper.selectByDictTypeAndValue(dictType, value);
if (dictData == null) {
return;
}
@@ -214,7 +216,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
}
- private void checkDictDataExists(Long id) {
+ @VisibleForTesting
+ public void checkDictDataExists(Long id) {
if (id == null) {
return;
}
@@ -224,7 +227,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
}
- private void checkDictTypeValid(String type) {
+ @VisibleForTesting
+ public void checkDictTypeValid(String type) {
SysDictTypeDO dictType = dictTypeService.getDictType(type);
if (dictType == null) {
throw exception(DICT_TYPE_NOT_EXISTS);
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
index 24b6be5e0c..5c75befaad 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
@@ -10,6 +10,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dict.SysDictTypeMapper;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService;
import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
+import com.google.common.annotations.VisibleForTesting;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -97,7 +98,8 @@ public class SysDictTypeServiceImpl implements SysDictTypeService {
checkDictTypeUnique(id, type);
}
- private void checkDictTypeNameUnique(Long id, String type) {
+ @VisibleForTesting
+ public void checkDictTypeNameUnique(Long id, String type) {
SysDictTypeDO dictType = dictTypeMapper.selectByName(type);
if (dictType == null) {
return;
@@ -111,7 +113,8 @@ public class SysDictTypeServiceImpl implements SysDictTypeService {
}
}
- private void checkDictTypeUnique(Long id, String type) {
+ @VisibleForTesting
+ public void checkDictTypeUnique(Long id, String type) {
SysDictTypeDO dictType = dictTypeMapper.selectByType(type);
if (dictType == null) {
return;
@@ -125,7 +128,8 @@ public class SysDictTypeServiceImpl implements SysDictTypeService {
}
}
- private SysDictTypeDO checkDictTypeExists(Long id) {
+ @VisibleForTesting
+ public SysDictTypeDO checkDictTypeExists(Long id) {
if (id == null) {
return null;
}
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
index b817072f08..82a3dafcbd 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
@@ -49,6 +49,37 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
@MockBean
private SysDictDataProducer dictDataProducer;
+ /**
+ * 测试加载到新的字典数据的情况
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testInitLocalCache() {
+ // mock 数据
+ SysDictDataDO dictData01 = randomDictDataDO();
+ dictDataMapper.insert(dictData01);
+ SysDictDataDO dictData02 = randomDictDataDO();
+ dictDataMapper.insert(dictData02);
+
+ // 调用
+ dictDataService.initLocalCache();
+ // 断言 labelDictDataCache 缓存
+ ImmutableTable labelDictDataCache =
+ (ImmutableTable) getFieldValue(dictDataService, "labelDictDataCache");
+ assertEquals(2, labelDictDataCache.size());
+ assertPojoEquals(dictData01, labelDictDataCache.get(dictData01.getDictType(), dictData01.getLabel()));
+ assertPojoEquals(dictData02, labelDictDataCache.get(dictData02.getDictType(), dictData02.getLabel()));
+ // 断言 valueDictDataCache 缓存
+ ImmutableTable valueDictDataCache =
+ (ImmutableTable) getFieldValue(dictDataService, "valueDictDataCache");
+ assertEquals(2, valueDictDataCache.size());
+ assertPojoEquals(dictData01, valueDictDataCache.get(dictData01.getDictType(), dictData01.getValue()));
+ assertPojoEquals(dictData02, valueDictDataCache.get(dictData02.getDictType(), dictData02.getValue()));
+ // 断言 maxUpdateTime 缓存
+ Date maxUpdateTime = (Date) getFieldValue(dictDataService, "maxUpdateTime");
+ assertEquals(ObjectUtils.max(dictData01.getUpdateTime(), dictData02.getUpdateTime()), maxUpdateTime);
+ }
+
@Test
public void testGetDictDataPage() {
// mock 数据
@@ -125,46 +156,6 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
}
- @Test
- public void testCreateDictData_dictTypeNotExists() {
- // 准备参数
- SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
- o -> o.setStatus(randomCommonStatus()));
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_TYPE_NOT_EXISTS);
- }
-
- @Test
- public void testCreateDictData_dictTypeNotEnable() {
- // 准备参数
- SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
- o -> o.setStatus(randomCommonStatus()));
- // mock 方法,数据类型被禁用
- when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(
- randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_TYPE_NOT_ENABLE);
- }
-
- @Test
- public void testCreateDictData_dictDataValueDuplicate() {
- // 准备参数
- SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
- o -> o.setStatus(randomCommonStatus()));
- // mock 方法,字典类型
- when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
- // mock dictData 重复 value 重复
- dictDataMapper.insert(randomDictDataDO(o -> {
- o.setDictType(reqVO.getDictType());
- o.setValue(reqVO.getValue()); // 使用 reqVO 的 value,实现重复
- }));
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.createDictData(reqVO), DICT_DATA_VALUE_DUPLICATE);
- }
-
@Test
public void testUpdateDictData_success() {
// mock 数据
@@ -187,101 +178,6 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
}
- @Test
- public void testUpdateDictData_notExists() {
- // 准备参数
- SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class);
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_DATA_NOT_EXISTS);
- }
-
- /**
- * 测试加载到新的字典数据的情况
- */
- @Test
- @SuppressWarnings("unchecked")
- public void testInitLocalCache() {
- // mock 数据
- SysDictDataDO dictData01 = randomDictDataDO();
- dictDataMapper.insert(dictData01);
- SysDictDataDO dictData02 = randomDictDataDO();
- dictDataMapper.insert(dictData02);
-
- // 调用
- dictDataService.initLocalCache();
- // 断言 labelDictDataCache 缓存
- ImmutableTable labelDictDataCache =
- (ImmutableTable) getFieldValue(dictDataService, "labelDictDataCache");
- assertEquals(2, labelDictDataCache.size());
- assertPojoEquals(dictData01, labelDictDataCache.get(dictData01.getDictType(), dictData01.getLabel()));
- assertPojoEquals(dictData02, labelDictDataCache.get(dictData02.getDictType(), dictData02.getLabel()));
- // 断言 valueDictDataCache 缓存
- ImmutableTable valueDictDataCache =
- (ImmutableTable) getFieldValue(dictDataService, "valueDictDataCache");
- assertEquals(2, valueDictDataCache.size());
- assertPojoEquals(dictData01, valueDictDataCache.get(dictData01.getDictType(), dictData01.getValue()));
- assertPojoEquals(dictData02, valueDictDataCache.get(dictData02.getDictType(), dictData02.getValue()));
- // 断言 maxUpdateTime 缓存
- Date maxUpdateTime = (Date) getFieldValue(dictDataService, "maxUpdateTime");
- assertEquals(ObjectUtils.max(dictData01.getUpdateTime(), dictData02.getUpdateTime()), maxUpdateTime);
- }
-
- @Test
- public void testUpdateDictData_dictTypeNotExists() {
- // mock 数据
- SysDictDataDO dbDictData = randomDictDataDO();
- dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
- // 准备参数
- SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
- o.setId(dbDictData.getId()); // 设置更新的 ID
- o.setStatus(randomCommonStatus());
- });
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_TYPE_NOT_EXISTS);
- }
-
- @Test
- public void testUpdateDictData_dictTypeNotEnable() {
- // mock 数据
- SysDictDataDO dbDictData = randomDictDataDO();
- dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
- // 准备参数
- SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
- o.setId(dbDictData.getId()); // 设置更新的 ID
- o.setStatus(randomCommonStatus());
- });
- // mock 方法,数据类型被禁用
- when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(
- randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_TYPE_NOT_ENABLE);
- }
-
- @Test
- public void testUpdateDictData_dictDataValueDuplicate() {
- // mock 数据
- SysDictDataDO dbDictData = randomDictDataDO();
- dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
- // 准备参数
- SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
- o.setId(dbDictData.getId()); // 设置更新的 ID
- o.setStatus(randomCommonStatus());
- });
- // mock 方法,字典类型
- when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
- // mock dictData 重复 value 重复
- dictDataMapper.insert(randomDictDataDO(o -> {
- o.setDictType(reqVO.getDictType());
- o.setValue(reqVO.getValue()); // 使用 reqVO 的 value,实现重复
- }));
-
- // 调用, 并断言异常
- assertServiceException(() -> dictDataService.updateDictData(reqVO), DICT_DATA_VALUE_DUPLICATE);
- }
-
@Test
public void testDeleteDictData_success() {
// mock 数据
@@ -299,12 +195,78 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
}
@Test
- public void testDeleteDictData_notExists() {
- // 准备参数
- Long id = randomLongId();
+ public void testCheckDictDataExists_success() {
+ // mock 数据
+ SysDictDataDO dbDictData = randomDictDataDO();
+ dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
+
+ // 调用成功
+ dictDataService.checkDictDataExists(dbDictData.getId());
+ }
+
+ @Test
+ public void testCheckDictTypeValid_success() {
+ // mock 方法,数据类型被禁用
+ String type = randomString();
+ when(dictTypeService.getDictType(eq(type))).thenReturn(randomDictTypeDO(type));
+
+ // 调用, 成功
+ dictDataService.checkDictTypeValid(type);
+ }
+
+ @Test
+ public void testCheckDictTypeValid_notExists() {
+ assertServiceException(() -> dictDataService.checkDictTypeValid(randomString()), DICT_TYPE_NOT_EXISTS);
+ }
+
+ @Test
+ public void testCheckDictTypeValid_notEnable() {
+ // mock 方法,数据类型被禁用
+ String dictType = randomString();
+ when(dictTypeService.getDictType(eq(dictType))).thenReturn(
+ randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 调用, 并断言异常
- assertServiceException(() -> dictDataService.deleteDictData(id), DICT_DATA_NOT_EXISTS);
+ assertServiceException(() -> dictDataService.checkDictTypeValid(dictType), DICT_TYPE_NOT_ENABLE);
+ }
+
+ @Test
+ public void testCheckDictDataValueUnique_success() {
+ // 调用,成功
+ dictDataService.checkDictDataValueUnique(randomLongId(), randomString(), randomString());
+ }
+
+ @Test
+ public void testCheckDictDataValueUnique_valueDuplicateForCreate() {
+ // 准备参数
+ String dictType = randomString();
+ String value = randomString();
+ // mock 数据
+ dictDataMapper.insert(randomDictDataDO(o -> {
+ o.setDictType(dictType);
+ o.setValue(value);
+ }));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictDataService.checkDictDataValueUnique(null, dictType, value),
+ DICT_DATA_VALUE_DUPLICATE);
+ }
+
+ @Test
+ public void testCheckDictDataValueUnique_valueDuplicateForUpdate() {
+ // 准备参数
+ Long id = randomLongId();
+ String dictType = randomString();
+ String value = randomString();
+ // mock 数据
+ dictDataMapper.insert(randomDictDataDO(o -> {
+ o.setDictType(dictType);
+ o.setValue(value);
+ }));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictDataService.checkDictDataValueUnique(id, dictType, value),
+ DICT_DATA_VALUE_DUPLICATE);
}
// ========== 随机对象 ==========
From c5ec798c10f1f0b50d6c95068d0af5f1dd273ef5 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Mon, 8 Mar 2021 00:37:18 +0800
Subject: [PATCH 08/17] =?UTF-8?q?=E7=AE=80=E5=8C=96=20dict=20type=20?=
=?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=B0=86?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0?=
=?UTF-8?q?=E9=99=A4=E6=B6=89=E5=8F=8A=E7=9A=84=E5=85=AC=E7=94=A8=E6=96=B9?=
=?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=8D=95=E7=8B=AC=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../dict/impl/SysDictTypeServiceImpl.java | 4 +-
.../service/dict/SysDictDataServiceTest.java | 5 +
.../service/dict/SysDictTypeServiceTest.java | 144 ++++++++++--------
3 files changed, 87 insertions(+), 66 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
index 5c75befaad..c210e8e2b1 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictTypeServiceImpl.java
@@ -99,8 +99,8 @@ public class SysDictTypeServiceImpl implements SysDictTypeService {
}
@VisibleForTesting
- public void checkDictTypeNameUnique(Long id, String type) {
- SysDictTypeDO dictType = dictTypeMapper.selectByName(type);
+ public void checkDictTypeNameUnique(Long id, String name) {
+ SysDictTypeDO dictType = dictTypeMapper.selectByName(name);
if (dictType == null) {
return;
}
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
index 82a3dafcbd..ae029f73b9 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
@@ -204,6 +204,11 @@ public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
dictDataService.checkDictDataExists(dbDictData.getId());
}
+ @Test
+ public void testCheckDictDataExists_notExists() {
+ assertServiceException(() -> dictDataService.checkDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS);
+ }
+
@Test
public void testCheckDictTypeValid_success() {
// mock 方法,数据类型被禁用
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
index e25fe2577c..05441a7075 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
@@ -23,8 +23,8 @@ import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
-import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
-import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
+import static cn.iocoder.dashboard.util.RandomUtils.*;
+import static cn.iocoder.dashboard.util.RandomUtils.randomString;
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
@@ -142,32 +142,6 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
assertPojoEquals(reqVO, dictType);
}
- @Test
- public void testCreateDictType_nameDuplicate() {
- // mock 数据
- SysDictTypeDO dbDictType = randomDictTypeDO();
- dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
- // 准备参数
- SysDictTypeCreateReqVO reqVO = randomPojo(SysDictTypeCreateReqVO.class,
- o -> o.setName(dbDictType.getName())); // 模拟 name 重复
-
- // 调用, 并断言异常
- assertServiceException(() -> dictTypeService.createDictType(reqVO), DICT_TYPE_NAME_DUPLICATE);
- }
-
- @Test
- public void testCreateDictType_typeDuplicate() {
- // mock 数据
- SysDictTypeDO dbDictType = randomDictTypeDO();
- dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
- // 准备参数
- SysDictTypeCreateReqVO reqVO = randomPojo(SysDictTypeCreateReqVO.class,
- o -> o.setType(dbDictType.getType())); // 模拟 type 重复
-
- // 调用, 并断言异常
- assertServiceException(() -> dictTypeService.createDictType(reqVO), DICT_TYPE_TYPE_DUPLICATE);
- }
-
@Test
public void testUpdateDictType_success() {
// mock 数据
@@ -186,33 +160,6 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
assertPojoEquals(reqVO, dictType);
}
- @Test
- public void testUpdateDictType_notExists() {
- // 准备参数
- SysDictTypeUpdateReqVO reqVO = randomPojo(SysDictTypeUpdateReqVO.class);
-
- // 调用, 并断言异常
- assertServiceException(() -> dictTypeService.updateDictType(reqVO), DICT_TYPE_NOT_EXISTS);
- }
-
- @Test
- public void testUpdateDictType_nameDuplicate() {
- // mock 数据,稍后更新它
- SysDictTypeDO dbDictType = randomDictTypeDO();
- dictTypeMapper.insert(dbDictType);
- // mock 数据,ks稍后模拟重复它的名字
- SysDictTypeDO nameDictType = randomDictTypeDO();
- dictTypeMapper.insert(nameDictType);
- // 准备参数
- SysDictTypeUpdateReqVO reqVO = randomPojo(SysDictTypeUpdateReqVO.class, o -> {
- o.setId(dbDictType.getId()); // 设置更新的 ID
- o.setName(nameDictType.getName()); // 模拟 name 重复
- });
-
- // 调用, 并断言异常
- assertServiceException(() -> dictTypeService.updateDictType(reqVO), DICT_TYPE_NAME_DUPLICATE);
- }
-
@Test
public void testDeleteDictType_success() {
// mock 数据
@@ -227,15 +174,6 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
assertNull(dictTypeMapper.selectById(id));
}
- @Test
- public void testDeleteDictType_notExists() {
- // 准备参数
- Long id = randomLongId();
-
- // 调用, 并断言异常
- assertServiceException(() -> dictTypeService.deleteDictType(id), DICT_TYPE_NOT_EXISTS);
- }
-
@Test
public void testDeleteDictType_hasChildren() {
// mock 数据
@@ -250,6 +188,84 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
assertServiceException(() -> dictTypeService.deleteDictType(id), DICT_TYPE_HAS_CHILDREN);
}
+ @Test
+ public void testCheckDictDataExists_success() {
+ // mock 数据
+ SysDictTypeDO dbDictType = randomDictTypeDO();
+ dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
+
+ // 调用成功
+ dictTypeService.checkDictTypeExists(dbDictType.getId());
+ }
+
+ @Test
+ public void testCheckDictDataExists_notExists() {
+ assertServiceException(() -> dictTypeService.checkDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS);
+ }
+
+ @Test
+ public void testCheckDictTypeUnique_success() {
+ // 调用,成功
+ dictTypeService.checkDictTypeUnique(randomLongId(), randomString());
+ }
+
+ @Test
+ public void testCheckDictTypeUnique_valueDuplicateForCreate() {
+ // 准备参数
+ String type = randomString();
+ // mock 数据
+ dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictTypeService.checkDictTypeUnique(null, type),
+ DICT_TYPE_TYPE_DUPLICATE);
+ }
+
+ @Test
+ public void testCheckDictTypeUnique_valueDuplicateForUpdate() {
+ // 准备参数
+ Long id = randomLongId();
+ String type = randomString();
+ // mock 数据
+ dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictTypeService.checkDictTypeUnique(id, type),
+ DICT_TYPE_TYPE_DUPLICATE);
+ }
+
+
+ @Test
+ public void testCheckDictTypNameUnique_success() {
+ // 调用,成功
+ dictTypeService.checkDictTypeNameUnique(randomLongId(), randomString());
+ }
+
+ @Test
+ public void testCheckDictTypeNameUnique_valueDuplicateForCreate() {
+ // 准备参数
+ String name = randomString();
+ // mock 数据
+ dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(null, name),
+ DICT_TYPE_NAME_DUPLICATE);
+ }
+
+ @Test
+ public void testCheckDictTypeNameUnique_valueDuplicateForUpdate() {
+ // 准备参数
+ Long id = randomLongId();
+ String name = randomString();
+ // mock 数据
+ dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
+
+ // 调用,校验异常
+ assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(id, name),
+ DICT_TYPE_NAME_DUPLICATE);
+ }
+
// ========== 随机对象 ==========
@SafeVarargs
From 7b4d7f5e65d89bb872e11e765996be6252595308 Mon Sep 17 00:00:00 2001
From: niudehua <657563945@qq.com>
Date: Mon, 8 Mar 2021 00:39:04 +0800
Subject: [PATCH 09/17] sort String -> Integer
---
.../modules/system/controller/dept/vo/dept/SysDeptBaseVO.java | 2 +-
.../modules/system/controller/dept/vo/post/SysPostBaseVO.java | 2 +-
.../modules/system/controller/dept/vo/post/SysPostExcelVO.java | 2 +-
.../system/controller/permission/vo/menu/SysMenuBaseVO.java | 2 +-
.../system/controller/permission/vo/role/SysRoleBaseVO.java | 2 +-
.../dashboard/modules/system/dal/dataobject/dept/SysDeptDO.java | 2 +-
.../dashboard/modules/system/dal/dataobject/dept/SysPostDO.java | 2 +-
.../modules/system/dal/dataobject/permission/SysMenuDO.java | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/dept/SysDeptBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/dept/SysDeptBaseVO.java
index fd40fd7deb..922c395fdb 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/dept/SysDeptBaseVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/dept/SysDeptBaseVO.java
@@ -26,7 +26,7 @@ public class SysDeptBaseVO {
@ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024")
@NotBlank(message = "显示顺序不能为空")
- private String sort;
+ private Integer sort;
@ApiModelProperty(value = "负责人", example = "芋道")
private String leader;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostBaseVO.java
index 162f713878..9a7943b0fd 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostBaseVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostBaseVO.java
@@ -25,7 +25,7 @@ public class SysPostBaseVO {
@ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024")
@NotBlank(message = "显示顺序不能为空")
- private String sort;
+ private Integer sort;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
private Integer status;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostExcelVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostExcelVO.java
index 05ac0e962d..74afa919e7 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostExcelVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/vo/post/SysPostExcelVO.java
@@ -23,7 +23,7 @@ public class SysPostExcelVO {
private String name;
@ExcelProperty("岗位排序")
- private String sort;
+ private Integer sort;
@ExcelProperty(value = "状态", converter = DictConvert.class)
@DictFormat(SYS_COMMON_STATUS)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/menu/SysMenuBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/menu/SysMenuBaseVO.java
index 818ef8c93a..5882f825ce 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/menu/SysMenuBaseVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/menu/SysMenuBaseVO.java
@@ -29,7 +29,7 @@ public class SysMenuBaseVO {
@ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024")
@NotBlank(message = "显示顺序不能为空")
- private String sort;
+ private Integer sort;
@ApiModelProperty(value = "父菜单 ID", required = true, example = "1024")
@NotNull(message = "父菜单 ID 不能为空")
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/role/SysRoleBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/role/SysRoleBaseVO.java
index 80ee8bfcd3..bf9a1b1414 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/role/SysRoleBaseVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/vo/role/SysRoleBaseVO.java
@@ -25,7 +25,7 @@ public class SysRoleBaseVO {
@ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024")
@NotBlank(message = "显示顺序不能为空")
- private String sort;
+ private Integer sort;
@ApiModelProperty(value = "角色类型", required = true, example = "1", notes = "见 SysRoleTypeEnum 枚举")
private Integer type;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysDeptDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysDeptDO.java
index e2218f461d..e116bd3b0f 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysDeptDO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysDeptDO.java
@@ -35,7 +35,7 @@ public class SysDeptDO extends BaseDO {
/**
* 显示顺序
*/
- private String sort;
+ private Integer sort;
/**
* 负责人
*/
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysPostDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysPostDO.java
index d2eaefd3bd..ba5f3e0ad7 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysPostDO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/dept/SysPostDO.java
@@ -34,7 +34,7 @@ public class SysPostDO extends BaseDO {
/**
* 岗位排序
*/
- private String sort;
+ private Integer sort;
/**
* 状态
*
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/permission/SysMenuDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/permission/SysMenuDO.java
index ee8f302ddd..82956e9f95 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/permission/SysMenuDO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/permission/SysMenuDO.java
@@ -49,7 +49,7 @@ public class SysMenuDO extends BaseDO {
/**
* 显示顺序
*/
- private String sort;
+ private Integer sort;
/**
* 父菜单ID
*/
From 01be94a7a062633884c9947d64b961b1f056e241 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Mon, 8 Mar 2021 00:50:59 +0800
Subject: [PATCH 10/17] =?UTF-8?q?=E7=AE=80=E5=8C=96=20config=20=E7=9A=84?=
=?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=B0=86=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0=E9=99=A4?=
=?UTF-8?q?=E6=B6=89=E5=8F=8A=E7=9A=84=E5=85=AC=E7=94=A8=E6=96=B9=E6=B3=95?=
=?UTF-8?q?=EF=BC=8C=E5=8D=95=E7=8B=AC=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sql/ruoyi-vue-pro.sql | 27 ++++++--
.../config/impl/InfConfigServiceImpl.java | 7 +-
.../service/config/InfConfigServiceTest.java | 68 +++++++++++--------
.../service/dict/SysDictTypeServiceTest.java | 5 +-
4 files changed, 68 insertions(+), 39 deletions(-)
diff --git a/sql/ruoyi-vue-pro.sql b/sql/ruoyi-vue-pro.sql
index 56a3a98bf3..7b2e2c7abc 100644
--- a/sql/ruoyi-vue-pro.sql
+++ b/sql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@
Target Server Version : 50718
File Encoding : 65001
- Date: 07/03/2021 00:43:34
+ Date: 08/03/2021 00:50:29
*/
SET NAMES utf8mb4;
@@ -43,7 +43,7 @@ CREATE TABLE `inf_api_access_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=1822 DEFAULT CHARSET=utf8mb4 COMMENT='API 访问日志表';
+) ENGINE=InnoDB AUTO_INCREMENT=1850 DEFAULT CHARSET=utf8mb4 COMMENT='API 访问日志表';
-- ----------------------------
-- Records of inf_api_access_log
@@ -175,7 +175,7 @@ CREATE TABLE `inf_job_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=4458 DEFAULT CHARSET=utf8mb4 COMMENT='定时任务日志表';
+) ENGINE=InnoDB AUTO_INCREMENT=4477 DEFAULT CHARSET=utf8mb4 COMMENT='定时任务日志表';
-- ----------------------------
-- Records of inf_job_log
@@ -579,7 +579,7 @@ CREATE TABLE `sys_operate_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
+) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
-- ----------------------------
-- Records of sys_operate_log
@@ -955,7 +955,7 @@ INSERT INTO `sys_user_session` VALUES ('7b008d71139f48a4903aeaab0bbbef2e', 1, '1
INSERT INTO `sys_user_session` VALUES ('7cbd0fdfb9304f298abb9ee2f58f7230', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-02-08 20:02:24', '', '2021-02-08 20:02:24', b'0');
INSERT INTO `sys_user_session` VALUES ('830a1687977b44969025177ad3b6d051', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-02-10 01:56:00', '', '2021-02-10 01:56:00', b'0');
INSERT INTO `sys_user_session` VALUES ('8331dbbca7be4348a3d2d02bf559b65e', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-02-05 13:29:04', '', '2021-02-10 19:06:26', b'0');
-INSERT INTO `sys_user_session` VALUES ('897714de63634dba9ac235247f9860c2', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-03-06 06:27:27', '', '2021-03-06 06:27:27', b'0');
+INSERT INTO `sys_user_session` VALUES ('897714de63634dba9ac235247f9860c2', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-03-06 06:27:27', '', '2021-03-07 00:50:21', b'0');
INSERT INTO `sys_user_session` VALUES ('8d7668c1276344ecbffaf7e4420595d7', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-02-08 09:56:09', '', '2021-02-19 19:17:42', b'0');
INSERT INTO `sys_user_session` VALUES ('9a3a5b8dee1841b69d70454ce23a53a3', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-02-26 00:09:49', '', '2021-02-27 01:27:20', b'0');
INSERT INTO `sys_user_session` VALUES ('9cc71dc2d7a24b978db1bfe0e4bae349', 1, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '', '2021-01-26 08:30:01', '', '2021-01-26 08:30:01', b'0');
@@ -1006,7 +1006,7 @@ CREATE TABLE `tool_codegen_column` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=369 DEFAULT CHARSET=utf8mb4 COMMENT='代码生成表字段定义';
+) ENGINE=InnoDB AUTO_INCREMENT=381 DEFAULT CHARSET=utf8mb4 COMMENT='代码生成表字段定义';
-- ----------------------------
-- Records of tool_codegen_column
@@ -1148,6 +1148,18 @@ INSERT INTO `tool_codegen_column` VALUES (365, 29, 'create_time', 'datetime', '
INSERT INTO `tool_codegen_column` VALUES (366, 29, 'update_by', 'varchar(64)', '更新者', b'1', b'0', '0', 8, 'String', 'updateBy', '', NULL, b'0', b'0', b'0', '=', b'0', 'input', '', '2021-03-06 03:52:57', '', '2021-03-06 03:52:57', b'0');
INSERT INTO `tool_codegen_column` VALUES (367, 29, 'update_time', 'datetime', '更新时间', b'0', b'0', '0', 9, 'Date', 'updateTime', '', NULL, b'0', b'0', b'0', 'BETWEEN', b'0', 'datetime', '', '2021-03-06 03:52:57', '', '2021-03-06 03:52:57', b'0');
INSERT INTO `tool_codegen_column` VALUES (368, 29, 'deleted', 'bit(1)', '是否删除', b'0', b'0', '0', 10, 'Boolean', 'deleted', '', NULL, b'0', b'0', b'0', '=', b'0', 'radio', '', '2021-03-06 03:52:57', '', '2021-03-06 03:52:57', b'0');
+INSERT INTO `tool_codegen_column` VALUES (369, 30, 'id', 'bigint(20)', '字典编码', b'0', b'1', '1', 1, 'Long', 'id', '', NULL, b'0', b'1', b'0', '=', b'1', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
+INSERT INTO `tool_codegen_column` VALUES (370, 30, 'sort', 'int(4)', '字典排序', b'0', b'0', '0', 2, 'Integer', 'sort', '', NULL, b'1', b'1', b'0', '=', b'1', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (371, 30, 'label', 'varchar(100)', '字典标签', b'0', b'0', '0', 3, 'String', 'label', '', NULL, b'1', b'1', b'1', 'LIKE', b'1', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (372, 30, 'value', 'varchar(100)', '字典键值', b'0', b'0', '0', 4, 'String', 'value', '', NULL, b'1', b'1', b'0', '=', b'1', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (373, 30, 'dict_type', 'varchar(100)', '字典类型', b'0', b'0', '0', 5, 'String', 'dictType', '', NULL, b'1', b'1', b'1', 'LIKE', b'1', 'select', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (374, 30, 'status', 'tinyint(4)', '状态(0正常 1停用)', b'0', b'0', '0', 6, 'Integer', 'status', '', NULL, b'1', b'1', b'1', 'LIKE', b'1', 'radio', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (375, 30, 'remark', 'varchar(500)', '备注', b'1', b'0', '0', 7, 'String', 'remark', '', NULL, b'1', b'1', b'0', '=', b'1', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:38', b'0');
+INSERT INTO `tool_codegen_column` VALUES (376, 30, 'create_by', 'varchar(64)', '创建者', b'1', b'0', '0', 8, 'String', 'createBy', '', NULL, b'0', b'0', b'0', '=', b'0', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
+INSERT INTO `tool_codegen_column` VALUES (377, 30, 'create_time', 'datetime', '创建时间', b'0', b'0', '0', 9, 'Date', 'createTime', '', NULL, b'0', b'0', b'1', 'BETWEEN', b'1', 'datetime', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
+INSERT INTO `tool_codegen_column` VALUES (378, 30, 'update_by', 'varchar(64)', '更新者', b'1', b'0', '0', 10, 'String', 'updateBy', '', NULL, b'0', b'0', b'0', '=', b'0', 'input', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
+INSERT INTO `tool_codegen_column` VALUES (379, 30, 'update_time', 'datetime', '更新时间', b'0', b'0', '0', 11, 'Date', 'updateTime', '', NULL, b'0', b'0', b'0', 'BETWEEN', b'0', 'datetime', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
+INSERT INTO `tool_codegen_column` VALUES (380, 30, 'deleted', 'bit(1)', '是否删除', b'0', b'0', '0', 12, 'Boolean', 'deleted', '', NULL, b'0', b'0', b'0', '=', b'0', 'radio', '', '2021-03-06 06:48:28', '', '2021-03-06 06:48:28', b'0');
COMMIT;
-- ----------------------------
@@ -1173,7 +1185,7 @@ CREATE TABLE `tool_codegen_table` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8mb4 COMMENT='代码生成表定义';
+) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COMMENT='代码生成表定义';
-- ----------------------------
-- Records of tool_codegen_table
@@ -1189,6 +1201,7 @@ INSERT INTO `tool_codegen_table` VALUES (26, 1, 'inf_api_access_log', 'API 访
INSERT INTO `tool_codegen_table` VALUES (27, 1, 'inf_api_error_log', 'API 错误日志', NULL, 'infra', 'apiErrorLog', 'InfApiErrorLog', 'API 错误日志', '芋道源码', 1, 1083, '', '2021-02-26 06:54:49', '', '2021-02-26 07:53:03', b'0');
INSERT INTO `tool_codegen_table` VALUES (28, 1, 'sys_dict_type', '字典类型表', NULL, 'system', 'dictType', 'SysDictType', '字典类型', '芋艿', 1, NULL, '', '2021-03-06 03:45:55', '', '2021-03-06 03:51:02', b'1');
INSERT INTO `tool_codegen_table` VALUES (29, 1, 'sys_dict_type', '字典类型表', NULL, 'system', 'dict', 'SysDictType', '字典类型', '芋艿', 1, NULL, '', '2021-03-06 03:52:57', '', '2021-03-06 04:03:52', b'0');
+INSERT INTO `tool_codegen_table` VALUES (30, 1, 'sys_dict_data', '字典数据表', NULL, 'system', 'type', 'SysDictData', '字典数据', '芋道源码', 1, NULL, '', '2021-03-06 06:48:28', '', '2021-03-06 06:50:47', b'0');
COMMIT;
-- ----------------------------
diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java
index 41bb5a357e..27e49771d1 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java
@@ -12,6 +12,7 @@ import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer;
import cn.iocoder.dashboard.modules.infra.service.config.InfConfigService;
+import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -99,7 +100,8 @@ public class InfConfigServiceImpl implements InfConfigService {
checkConfigKeyUnique(id, key);
}
- private InfConfigDO checkConfigExists(Long id) {
+ @VisibleForTesting
+ public InfConfigDO checkConfigExists(Long id) {
if (id == null) {
return null;
}
@@ -110,7 +112,8 @@ public class InfConfigServiceImpl implements InfConfigService {
return config;
}
- private void checkConfigKeyUnique(Long id, String key) {
+ @VisibleForTesting
+ public void checkConfigKeyUnique(Long id, String key) {
InfConfigDO config = configMapper.selectByKey(key);
if (config == null) {
return;
diff --git a/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
index 07691ba00c..94903e6dca 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
@@ -24,8 +24,7 @@ import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.*;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
-import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
-import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
+import static cn.iocoder.dashboard.util.RandomUtils.*;
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.times;
@@ -145,19 +144,6 @@ public class InfConfigServiceTest extends BaseSpringBootUnitTest {
verify(configProducer, times(1)).sendConfigRefreshMessage();
}
- @Test
- public void testCreateConfig_keyDuplicate() {
- // 准备参数
- InfConfigCreateReqVO reqVO = randomPojo(InfConfigCreateReqVO.class);
- // mock 数据
- configMapper.insert(randomInfConfigDO(o -> { // @Sql
- o.setKey(reqVO.getKey()); // 模拟 key 重复
- }));
-
- // 调用, 并断言异常
- assertServiceException(() -> configService.createConfig(reqVO), CONFIG_KEY_DUPLICATE);
- }
-
@Test
public void testUpdateConfig_success() {
// mock 数据
@@ -177,15 +163,6 @@ public class InfConfigServiceTest extends BaseSpringBootUnitTest {
verify(configProducer, times(1)).sendConfigRefreshMessage();
}
- @Test
- public void testUpdateConfig_notExists() {
- // 准备参数
- InfConfigUpdateReqVO reqVO = randomPojo(InfConfigUpdateReqVO.class);
-
- // 调用, 并断言异常
- assertServiceException(() -> configService.updateConfig(reqVO), CONFIG_NOT_EXISTS);
- }
-
@Test
public void testDeleteConfig_success() {
// mock 数据
@@ -219,12 +196,49 @@ public class InfConfigServiceTest extends BaseSpringBootUnitTest {
}
@Test
- public void testDeleteConfig_notExists() {
+ public void testCheckConfigExists_success() {
+ // mock 数据
+ InfConfigDO dbConfigDO = randomInfConfigDO();
+ configMapper.insert(dbConfigDO);// @Sql: 先插入出一条存在的数据
+
+ // 调用成功
+ configService.checkConfigExists(dbConfigDO.getId());
+ }
+
+ @Test
+ public void testCheckConfigExist_notExists() {
+ assertServiceException(() -> configService.checkConfigExists(randomLongId()), CONFIG_NOT_EXISTS);
+ }
+
+ @Test
+ public void testCheckConfigKeyUnique_success() {
+ // 调用,成功
+ configService.checkConfigKeyUnique(randomLongId(), randomString());
+ }
+
+ @Test
+ public void testCheckConfigKeyUnique_keyDuplicateForCreate() {
+ // 准备参数
+ String key = randomString();
+ // mock 数据
+ configMapper.insert(randomInfConfigDO(o -> o.setKey(key)));
+
+ // 调用,校验异常
+ assertServiceException(() -> configService.checkConfigKeyUnique(null, key),
+ CONFIG_KEY_DUPLICATE);
+ }
+
+ @Test
+ public void testCheckConfigKeyUnique_keyDuplicateForUpdate() {
// 准备参数
Long id = randomLongId();
+ String key = randomString();
+ // mock 数据
+ configMapper.insert(randomInfConfigDO(o -> o.setKey(key)));
- // 调用, 并断言异常
- assertServiceException(() -> configService.deleteConfig(id), CONFIG_NOT_EXISTS);
+ // 调用,校验异常
+ assertServiceException(() -> configService.checkConfigKeyUnique(id, key),
+ CONFIG_KEY_DUPLICATE);
}
// ========== 随机对象 ==========
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
index 05441a7075..ae8d0662b5 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
@@ -234,7 +234,6 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
DICT_TYPE_TYPE_DUPLICATE);
}
-
@Test
public void testCheckDictTypNameUnique_success() {
// 调用,成功
@@ -242,7 +241,7 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
}
@Test
- public void testCheckDictTypeNameUnique_valueDuplicateForCreate() {
+ public void testCheckDictTypeNameUnique_nameDuplicateForCreate() {
// 准备参数
String name = randomString();
// mock 数据
@@ -254,7 +253,7 @@ public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
}
@Test
- public void testCheckDictTypeNameUnique_valueDuplicateForUpdate() {
+ public void testCheckDictTypeNameUnique_nameDuplicateForUpdate() {
// 准备参数
Long id = randomLongId();
String name = randomString();
From 0e5802adb8b30d57b65d6799eb8eb93984e539b7 Mon Sep 17 00:00:00 2001
From: hezhouqun
Date: Mon, 8 Mar 2021 11:16:46 +0800
Subject: [PATCH 11/17] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=85=85=EF=BC=8C=E5=A6=82=E6=9E=9C?=
=?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=98=BE=E5=BC=8F=E7=9A=84=E5=AF=B9=E9=80=9A?=
=?UTF-8?q?=E7=94=A8=E5=AD=97=E6=AE=B5=E8=BF=9B=E8=A1=8C=E8=B5=8B=E5=80=BC?=
=?UTF-8?q?=EF=BC=8C=E5=88=99=E4=BC=9A=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=85=85?=
=?UTF-8?q?=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mybatis/config/DefaultParamHandler.java | 65 +++++++++++++++++++
.../mybatis/core/dataobject/BaseDO.java | 8 +--
2 files changed, 69 insertions(+), 4 deletions(-)
create mode 100644 src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java
new file mode 100644
index 0000000000..f94100fbce
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java
@@ -0,0 +1,65 @@
+package cn.iocoder.dashboard.framework.mybatis.config;
+
+import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.dashboard.framework.security.core.LoginUser;
+import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * 通用参数填充实现类
+ *
+ * 如果没有显式的对通用参数进行赋值,这里会对通用参数进行填充、赋值
+ *
+ * @author hexiaowu
+ */
+@Component
+public class DefaultParamHandler implements MetaObjectHandler {
+
+ @Override
+ public void insertFill(MetaObject metaObject) {
+ if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO) {
+ LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
+ BaseDO baseDO = (BaseDO) metaObject.getOriginalObject();
+ Date current = new Date();
+
+ // 创建时间为空,则以当前时间为插入时间
+ if (Objects.isNull(baseDO.getCreateTime())) {
+ baseDO.setCreateTime(current);
+ }
+ // 更新时间为空,则以当前时间为更新时间
+ if (Objects.isNull(baseDO.getUpdateTime())) {
+ baseDO.setUpdateTime(current);
+ }
+ // 当前登录用户不为空,创建人为空,则当前登录用户为创建人
+ if (Objects.nonNull(loginUser) && Objects.isNull(baseDO.getCreator())) {
+ baseDO.setCreator(loginUser.getId().toString());
+ }
+ // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
+ if (Objects.nonNull(loginUser) && Objects.isNull(baseDO.getUpdater())) {
+ baseDO.setUpdater(loginUser.getId().toString());
+ }
+ }
+ }
+
+ @Override
+ public void updateFill(MetaObject metaObject) {
+ Object modifyTime = getFieldValByName("updateTime", metaObject);
+ Object modifier = getFieldValByName("updater", metaObject);
+ // 获取登录用户信息
+ LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
+
+ // 更新时间为空,则以当前时间为更新时间
+ if (Objects.isNull(modifyTime)) {
+ setFieldValByName("updateTime", new Date(), metaObject);
+ }
+ // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
+ if (Objects.nonNull(loginUser) && Objects.isNull(modifier)) {
+ setFieldValByName("updater", loginUser.getId(), metaObject);
+ }
+ }
+}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java
index 7f6c76150f..df9ddb22e1 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java
@@ -21,13 +21,13 @@ public class BaseDO implements Serializable {
*/
private Date updateTime;
/**
- * 创建者 TODO 芋艿:迁移成编号
+ * 创建者
*/
- private String createBy;
+ private String creator;
/**
- * 更新者 TODO 芋艿:迁移成编号
+ * 更新者
*/
- private String updateBy;
+ private String updater;
/**
* 是否删除
*/
From ce7947b162680def57a51a5f24becd48b4cd02b0 Mon Sep 17 00:00:00 2001
From: hezhouqun
Date: Mon, 8 Mar 2021 19:11:38 +0800
Subject: [PATCH 12/17] =?UTF-8?q?=E5=B0=86=20DefaultParamHandler=20?=
=?UTF-8?q?=E4=BB=8E=20config=20=E5=8C=85=E7=A7=BB=E5=8A=A8=E5=88=B0=20cor?=
=?UTF-8?q?e/handle=20=E5=8C=85=E4=B8=8B=20=E5=B0=86=20DefaultParamHandler?=
=?UTF-8?q?=20=E6=94=B9=E5=90=8D=E4=B8=BA=20DefaultDBFieldHandler?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../handle/DefaultDBFieldHandler.java} | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
rename src/main/java/cn/iocoder/dashboard/framework/mybatis/{config/DefaultParamHandler.java => core/handle/DefaultDBFieldHandler.java} (95%)
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/handle/DefaultDBFieldHandler.java
similarity index 95%
rename from src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java
rename to src/main/java/cn/iocoder/dashboard/framework/mybatis/core/handle/DefaultDBFieldHandler.java
index f94100fbce..1651ecc479 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/DefaultParamHandler.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/handle/DefaultDBFieldHandler.java
@@ -1,4 +1,4 @@
-package cn.iocoder.dashboard.framework.mybatis.config;
+package cn.iocoder.dashboard.framework.mybatis.core.handle;
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
@@ -18,7 +18,7 @@ import java.util.Objects;
* @author hexiaowu
*/
@Component
-public class DefaultParamHandler implements MetaObjectHandler {
+public class DefaultDBFieldHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
From eca27cd18faef135a9b226334a2b265b074b3353 Mon Sep 17 00:00:00 2001
From: asas6559 <302811456@qq.com>
Date: Mon, 8 Mar 2021 20:41:19 +0800
Subject: [PATCH 13/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=80=80=E5=87=BA?=
=?UTF-8?q?=E9=A1=B5=E9=9D=A2=20=E9=80=80=E5=87=BA=E5=90=8E=E9=87=8D?=
=?UTF-8?q?=E5=AE=9A=E5=90=91=E5=88=B0=E7=99=BB=E5=BD=95=E9=A1=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../framework/security/config/SecurityConfiguration.java | 2 +-
.../security/core/handler/LogoutSuccessHandlerImpl.java | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/framework/security/config/SecurityConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/security/config/SecurityConfiguration.java
index 927c729965..2b9e2202bb 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/security/config/SecurityConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/security/config/SecurityConfiguration.java
@@ -152,7 +152,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable();
- httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
+ httpSecurity.logout().logoutUrl(webProperties.getApiPrefix() + "/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加 JWT Filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/security/core/handler/LogoutSuccessHandlerImpl.java b/src/main/java/cn/iocoder/dashboard/framework/security/core/handler/LogoutSuccessHandlerImpl.java
index 07826b9ab7..262f56fe2b 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/security/core/handler/LogoutSuccessHandlerImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/security/core/handler/LogoutSuccessHandlerImpl.java
@@ -1,6 +1,7 @@
package cn.iocoder.dashboard.framework.security.core.handler;
import cn.hutool.core.util.StrUtil;
+import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFrameworkService;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
@@ -36,6 +37,6 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
securityFrameworkService.logout(token);
}
// 返回成功
- ServletUtils.writeJSON(response, null);
+ ServletUtils.writeJSON(response, CommonResult.success(null));
}
}
From ac17cf180598a6eb7154508da773fc55a5834b76 Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Mon, 8 Mar 2021 21:12:29 +0800
Subject: [PATCH 14/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8D=95=E5=85=83?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=8C=E6=96=B0=E5=A2=9E=20BaseDbUnitTest?=
=?UTF-8?q?=20=E5=92=8C=20BaseDbAndRedisUnitTest=20=E5=9F=BA=E7=B1=BB?=
=?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=20SpringBoot=20=E8=87=AA=E5=8A=A8?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=90=AF=E5=8A=A8?=
=?UTF-8?q?=E8=BF=87=E6=85=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mybatis/config/MybatisConfiguration.java | 3 +-
.../dashboard/BaseDbAndRedisUnitTest.java | 46 +++++++++++++++++++
.../cn/iocoder/dashboard/BaseDbUnitTest.java | 37 +++++++++++++++
.../dashboard/BaseSpringBootUnitTest.java | 1 +
.../config/RedisTestConfiguration.java | 2 -
.../config/SecurityTestConfiguration.java | 16 -------
.../service/config/InfConfigServiceTest.java | 6 ++-
.../service/auth/SysAuthServiceImplTest.java | 22 ++++++++-
.../service/dict/SysDictDataServiceTest.java | 6 ++-
.../service/dict/SysDictTypeServiceTest.java | 7 +--
src/test/resources/application-unit-test.yaml | 45 +++---------------
src/test/resources/sql/create_tables.sql | 28 +++++------
12 files changed, 138 insertions(+), 81 deletions(-)
create mode 100644 src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java
create mode 100644 src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java
delete mode 100644 src/test/java/cn/iocoder/dashboard/config/SecurityTestConfiguration.java
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/MybatisConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/MybatisConfiguration.java
index a955c402ec..2a70b53d4c 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/MybatisConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/config/MybatisConfiguration.java
@@ -13,7 +13,8 @@ import org.springframework.context.annotation.Configuration;
* @author 芋道源码
*/
@Configuration
-@MapperScan(value = "${yudao.info.base-package}", annotationClass = Mapper.class)
+@MapperScan(value = "${yudao.info.base-package}", annotationClass = Mapper.class,
+ lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
public class MybatisConfiguration {
@Bean
diff --git a/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java b/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java
new file mode 100644
index 0000000000..59bacb052f
--- /dev/null
+++ b/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java
@@ -0,0 +1,46 @@
+package cn.iocoder.dashboard;
+
+import cn.iocoder.dashboard.config.RedisTestConfiguration;
+import cn.iocoder.dashboard.framework.datasource.config.DataSourceConfiguration;
+import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration;
+import cn.iocoder.dashboard.framework.redis.config.RedisConfig;
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
+import org.redisson.spring.starter.RedissonAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.jdbc.Sql;
+
+/**
+ * 依赖内存 DB 的单元测试
+ *
+ * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
+ *
+ * @author 芋道源码
+ */
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
+@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
+@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
+public class BaseDbAndRedisUnitTest {
+
+ @Import({
+ // DB 配置类
+ DataSourceConfiguration.class, // 自己的 DB 配置类
+ DataSourceAutoConfiguration.class, // Spring DB 自动配置类
+ DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+ // MyBatis 配置类
+ MybatisConfiguration.class, // 自己的 MyBatis 配置类
+ MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+ // Redis 配置类
+ RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
+ RedisAutoConfiguration.class, // Spring Redis 自动配置类
+ RedisConfig.class, // 自己的 Redis 配置类
+ RedissonAutoConfiguration.class, // Redisson 自动高配置类
+ })
+ public static class Application {
+ }
+
+}
diff --git a/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java b/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java
new file mode 100644
index 0000000000..8211182792
--- /dev/null
+++ b/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java
@@ -0,0 +1,37 @@
+package cn.iocoder.dashboard;
+
+import cn.iocoder.dashboard.framework.datasource.config.DataSourceConfiguration;
+import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration;
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.jdbc.Sql;
+
+/**
+ * 依赖内存 DB 的单元测试
+ *
+ * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
+ *
+ * @author 芋道源码
+ */
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
+@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
+@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
+public class BaseDbUnitTest {
+
+ @Import({
+ // DB 配置类
+ DataSourceConfiguration.class, // 自己的 DB 配置类
+ DataSourceAutoConfiguration.class, // Spring DB 自动配置类
+ DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+ // MyBatis 配置类
+ MybatisConfiguration.class, // 自己的 MyBatis 配置类
+ MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+ })
+ public static class Application {
+ }
+
+}
diff --git a/src/test/java/cn/iocoder/dashboard/BaseSpringBootUnitTest.java b/src/test/java/cn/iocoder/dashboard/BaseSpringBootUnitTest.java
index a00fc472d0..fe615dcaff 100644
--- a/src/test/java/cn/iocoder/dashboard/BaseSpringBootUnitTest.java
+++ b/src/test/java/cn/iocoder/dashboard/BaseSpringBootUnitTest.java
@@ -12,6 +12,7 @@ import javax.annotation.Resource;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
+@Deprecated
public class BaseSpringBootUnitTest {
@Resource
diff --git a/src/test/java/cn/iocoder/dashboard/config/RedisTestConfiguration.java b/src/test/java/cn/iocoder/dashboard/config/RedisTestConfiguration.java
index 1cddd9e1c0..c93d766a4f 100644
--- a/src/test/java/cn/iocoder/dashboard/config/RedisTestConfiguration.java
+++ b/src/test/java/cn/iocoder/dashboard/config/RedisTestConfiguration.java
@@ -8,12 +8,10 @@ import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
import java.io.IOException;
@Configuration(proxyBeanMethods = false)
-@Lazy(false) // 禁用懒加载,因为需要保证 Redis Server 必须先启动
@EnableConfigurationProperties(RedisProperties.class)
@AutoConfigureBefore({RedisAutoConfiguration.class, RedissonAutoConfiguration.class}) // 在 Redis 自动配置前,进行初始化
public class RedisTestConfiguration {
diff --git a/src/test/java/cn/iocoder/dashboard/config/SecurityTestConfiguration.java b/src/test/java/cn/iocoder/dashboard/config/SecurityTestConfiguration.java
deleted file mode 100644
index 08738388a2..0000000000
--- a/src/test/java/cn/iocoder/dashboard/config/SecurityTestConfiguration.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package cn.iocoder.dashboard.config;
-
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-
-@Configuration
-public class SecurityTestConfiguration {
-
- @Bean
- public AuthenticationManager authenticationManager() {
- return Mockito.mock(AuthenticationManager.class);
- }
-
-}
diff --git a/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
index 94903e6dca..a01330527c 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceTest.java
@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.modules.infra.service.config;
-import cn.iocoder.dashboard.BaseSpringBootUnitTest;
+import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO;
import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigExportReqVO;
@@ -15,6 +15,7 @@ import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
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;
@@ -35,7 +36,8 @@ import static org.mockito.Mockito.verify;
*
* @author 芋道源码
*/
-public class InfConfigServiceTest extends BaseSpringBootUnitTest {
+@Import(InfConfigServiceImpl.class)
+public class InfConfigServiceTest extends BaseDbUnitTest {
@Resource
private InfConfigServiceImpl configService;
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
index 5d9ac58a73..1be999efb2 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
@@ -1,15 +1,19 @@
package cn.iocoder.dashboard.modules.system.service.auth;
-import cn.iocoder.dashboard.BaseSpringBootUnitTest;
+import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl;
+import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService;
+import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.AssertUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.Import;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import javax.annotation.Resource;
@@ -21,7 +25,13 @@ import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
-public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
+/**
+ * {@link SysAuthServiceImpl} 的单元测试
+ *
+ * @author 芋道源码
+ */
+@Import(SysAuthServiceImpl.class)
+public class SysAuthServiceImplTest extends BaseDbUnitTest {
@Resource
private SysAuthServiceImpl authService;
@@ -30,6 +40,14 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
private SysUserService userService;
@MockBean
private SysPermissionService permissionService;
+ @MockBean
+ private AuthenticationManager authenticationManager;
+ @MockBean
+ private SysCaptchaService captchaService;
+ @MockBean
+ private SysLoginLogService loginLogService;
+ @MockBean
+ private SysUserSessionService userSessionService;
@Test
public void testLoadUserByUsername_success() {
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
index ae029f73b9..79c89518d2 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.modules.system.service.dict;
-import cn.iocoder.dashboard.BaseSpringBootUnitTest;
+import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.SysDictDataCreateReqVO;
@@ -17,6 +17,7 @@ import cn.iocoder.dashboard.util.object.ObjectUtils;
import com.google.common.collect.ImmutableTable;
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.Date;
@@ -37,7 +38,8 @@ import static org.mockito.Mockito.*;
*
* @author 芋道源码
*/
-public class SysDictDataServiceTest extends BaseSpringBootUnitTest {
+@Import(SysDictDataServiceImpl.class)
+public class SysDictDataServiceTest extends BaseDbUnitTest {
@Resource
private SysDictDataServiceImpl dictDataService;
diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
index ae8d0662b5..9dd0727333 100644
--- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
+++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeServiceTest.java
@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.modules.system.service.dict;
-import cn.iocoder.dashboard.BaseSpringBootUnitTest;
+import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.type.SysDictTypeCreateReqVO;
@@ -14,6 +14,7 @@ import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
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;
@@ -24,7 +25,6 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
import static cn.iocoder.dashboard.util.RandomUtils.*;
-import static cn.iocoder.dashboard.util.RandomUtils.randomString;
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
@@ -35,7 +35,8 @@ import static org.mockito.Mockito.when;
*
* @author 芋道源码
*/
-public class SysDictTypeServiceTest extends BaseSpringBootUnitTest {
+@Import(SysDictTypeServiceImpl.class)
+public class SysDictTypeServiceTest extends BaseDbUnitTest {
@Resource
private SysDictTypeServiceImpl dictTypeService;
diff --git a/src/test/resources/application-unit-test.yaml b/src/test/resources/application-unit-test.yaml
index b8406322cc..70cecc4c3c 100644
--- a/src/test/resources/application-unit-test.yaml
+++ b/src/test/resources/application-unit-test.yaml
@@ -3,21 +3,6 @@ spring:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
- # 去除的自动配置项
- autoconfigure:
- exclude:
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration # 单元测试,禁用 SpringSecurity
- - org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration # 单元测试,禁用 SpringSecurity
- - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 单元测试,禁用 Quartz
- - com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration # 单元测试,禁用 Lock4j 分布式锁
- - org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration # 单元测试,禁用 Scheduler 定时任务
- - org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration # 项目没有使用 Spring Data,所以禁用配置类,加速启动
-
-# Swagger 接口文档的自动配置(单元测试,禁用 Swagger)
-springfox:
- documentation:
- auto-startup: false
-
--- #################### 数据库相关配置 ####################
spring:
@@ -29,6 +14,9 @@ spring:
username: sa
password:
schema: classpath:sql/create_tables.sql # MySQL 转 H2 的语句,使用 https://www.jooq.org/translate/ 工具
+ druid:
+ async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
+ initial-size: 1 # 单元测试,配置为 1,提升启动速度
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
@@ -36,17 +24,13 @@ spring:
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
+mybatis:
+ lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
+
--- #################### 定时任务相关配置 ####################
-# Quartz 配置项,对应 QuartzProperties 配置类(单元测试,禁用 Quartz)
-
--- #################### 配置中心相关配置 ####################
-# Apollo 配置中心
-apollo:
- bootstrap:
- enabled: false # 单元测试,禁用配置中心
-
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项(单元测试,禁用 Lock4j)
@@ -63,23 +47,6 @@ resilience4j:
--- #################### 监控相关配置 ####################
-# Actuator 监控端点的配置项
-management:
- endpoints:
- enabled-by-default: false
-
-# Spring Boot Admin 配置项
-spring:
- boot:
- admin:
- # Spring Boot Admin Client 客户端的相关配置
- client:
- enabled: false
- # Spring Boot Admin Server 服务端的相关配置
- context-path: /admin # 配置 Spring
-
-# 日志文件配置(不需要配置)
-
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
diff --git a/src/test/resources/sql/create_tables.sql b/src/test/resources/sql/create_tables.sql
index 29078224ee..a5fb42520e 100644
--- a/src/test/resources/sql/create_tables.sql
+++ b/src/test/resources/sql/create_tables.sql
@@ -9,9 +9,9 @@ CREATE TABLE IF NOT EXISTS "inf_config" (
"value" varchar(500) NOT NULL DEFAULT '',
"sensitive" bit NOT NULL,
"remark" varchar(500) DEFAULT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -28,9 +28,9 @@ CREATE TABLE IF NOT EXISTS "sys_dept" (
"phone" varchar(11) DEFAULT NULL,
"email" varchar(50) DEFAULT NULL,
"status" tinyint NOT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -44,9 +44,9 @@ CREATE TABLE IF NOT EXISTS "sys_dict_data" (
"dict_type" varchar(100) NOT NULL DEFAULT '',
"status" tinyint NOT NULL DEFAULT '0',
"remark" varchar(500) DEFAULT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -62,9 +62,9 @@ CREATE TABLE IF NOT EXISTS "sys_role" (
"status" tinyint NOT NULL,
"type" tinyint NOT NULL,
"remark" varchar(500) DEFAULT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -74,9 +74,9 @@ CREATE TABLE IF NOT EXISTS "sys_role_menu" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"role_id" bigint NOT NULL,
"menu_id" bigint NOT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -93,9 +93,9 @@ CREATE TABLE IF NOT EXISTS "sys_menu" (
"icon" varchar(100) DEFAULT '#',
"component" varchar(255) DEFAULT NULL,
"status" tinyint NOT NULL DEFAULT '0',
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
@@ -107,9 +107,9 @@ CREATE TABLE "sys_dict_type" (
"type" varchar(100) NOT NULL DEFAULT '',
"status" tinyint NOT NULL DEFAULT '0',
"remark" varchar(500) DEFAULT NULL,
- "create_by" varchar(64) DEFAULT '',
+ "creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "update_by" varchar(64) DEFAULT '',
+ "updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
From d5ac6e7a199e3e36b46d89445fe1f8fe3a16130a Mon Sep 17 00:00:00 2001
From: asas6559 <302811456@qq.com>
Date: Mon, 8 Mar 2021 22:26:47 +0800
Subject: [PATCH 15/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=99=BB=E5=87=BA?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/auth/impl/SysAuthServiceImpl.java | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
index 1cbc7bb0b4..d8deefaaee 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
@@ -160,7 +160,23 @@ public class SysAuthServiceImpl implements SysAuthService {
@Override
public void logout(String token) {
-// AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); TODO 需要搞一搞
+ // 查询用户信息
+ LoginUser loginUser = userSessionService.getLoginUser(token);
+ if(loginUser == null) return;
+ // 删除session
+ userSessionService.deleteUserSession(token);
+ this.createLogoutLog(loginUser.getUsername(), SysLoginResultEnum.SUCCESS);
+ }
+
+ private void createLogoutLog(String username, SysLoginResultEnum loginResult) {
+ SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO();
+ reqVO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType());
+ reqVO.setTraceId(TracerUtils.getTraceId());
+ reqVO.setUsername(username);
+ reqVO.setUserAgent(ServletUtils.getUserAgent());
+ reqVO.setUserIp(ServletUtils.getClientIP());
+ reqVO.setResult(loginResult.getResult());
+ loginLogService.createLoginLog(reqVO);
}
@Override
From 4294ed2548dcffe7233cf9858bf6c51e241e238d Mon Sep 17 00:00:00 2001
From: asas6559 <302811456@qq.com>
Date: Mon, 8 Mar 2021 22:34:39 +0800
Subject: [PATCH 16/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=99=BB=E5=87=BA?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../modules/system/service/auth/impl/SysAuthServiceImpl.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
index d8deefaaee..675d26a54d 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
@@ -162,7 +162,9 @@ public class SysAuthServiceImpl implements SysAuthService {
public void logout(String token) {
// 查询用户信息
LoginUser loginUser = userSessionService.getLoginUser(token);
- if(loginUser == null) return;
+ if(loginUser == null) {
+ return;
+ }
// 删除session
userSessionService.deleteUserSession(token);
this.createLogoutLog(loginUser.getUsername(), SysLoginResultEnum.SUCCESS);
From d79bf7956cdbafd31d9574f672bf6e872473ae6b Mon Sep 17 00:00:00 2001
From: YunaiV
Date: Tue, 9 Mar 2021 00:35:04 +0800
Subject: [PATCH 17/17] =?UTF-8?q?SecurityFrameworkUtils=20=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=E6=97=B6=EF=BC=8C?=
=?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C?=
=?UTF-8?q?=E4=BF=9D=E8=AF=81=E6=AD=A3=E7=A1=AE=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/util/SecurityFrameworkUtils.java | 24 ++++++++++++++++---
.../service/auth/impl/SysAuthServiceImpl.java | 11 +++++----
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/main/java/cn/iocoder/dashboard/framework/security/core/util/SecurityFrameworkUtils.java b/src/main/java/cn/iocoder/dashboard/framework/security/core/util/SecurityFrameworkUtils.java
index eb67479d4b..b6c509b930 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/security/core/util/SecurityFrameworkUtils.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/security/core/util/SecurityFrameworkUtils.java
@@ -2,7 +2,10 @@ package cn.iocoder.dashboard.framework.security.core.util;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.framework.web.core.util.WebFrameworkUtils;
+import org.springframework.lang.Nullable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
@@ -40,9 +43,20 @@ public class SecurityFrameworkUtils {
/**
* 获取当前用户
+ *
+ * @return 当前用户
*/
+ @Nullable
public static LoginUser getLoginUser() {
- return (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ SecurityContext context = SecurityContextHolder.getContext();
+ if (context == null) {
+ return null;
+ }
+ Authentication authentication = context.getAuthentication();
+ if (authentication == null) {
+ return null;
+ }
+ return (LoginUser) authentication.getPrincipal();
}
/**
@@ -50,8 +64,10 @@ public class SecurityFrameworkUtils {
*
* @return 用户编号
*/
+ @Nullable
public static Long getLoginUserId() {
- return getLoginUser().getId();
+ LoginUser loginUser = getLoginUser();
+ return loginUser != null ? loginUser.getId() : null;
}
/**
@@ -59,8 +75,10 @@ public class SecurityFrameworkUtils {
*
* @return 角色编号数组
*/
+ @Nullable
public static Set getLoginUserRoleIds() {
- return getLoginUser().getRoleIds();
+ LoginUser loginUser = getLoginUser();
+ return loginUser != null ? loginUser.getRoleIds() : null;
}
/**
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
index 675d26a54d..dc5b3be848 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
@@ -162,22 +162,23 @@ public class SysAuthServiceImpl implements SysAuthService {
public void logout(String token) {
// 查询用户信息
LoginUser loginUser = userSessionService.getLoginUser(token);
- if(loginUser == null) {
+ if (loginUser == null) {
return;
}
- // 删除session
+ // 删除 session
userSessionService.deleteUserSession(token);
- this.createLogoutLog(loginUser.getUsername(), SysLoginResultEnum.SUCCESS);
+ // 记录登出日子和
+ this.createLogoutLog(loginUser.getUsername());
}
- private void createLogoutLog(String username, SysLoginResultEnum loginResult) {
+ private void createLogoutLog(String username) {
SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO();
reqVO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType());
reqVO.setTraceId(TracerUtils.getTraceId());
reqVO.setUsername(username);
reqVO.setUserAgent(ServletUtils.getUserAgent());
reqVO.setUserIp(ServletUtils.getClientIP());
- reqVO.setResult(loginResult.getResult());
+ reqVO.setResult(SysLoginResultEnum.SUCCESS.getResult());
loginLogService.createLoginLog(reqVO);
}