Commit 65a86e8d755750e674c081a1035e3a42bd81deee

Authored by YunaiV
2 parents eb147a92 c9d39135

Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/1.6.2-qcloud

 Conflicts:
	yudao-ui-admin/yarn.lock
Showing 213 changed files with 4685 additions and 2209 deletions

Too many changes.

To preserve performance only 100 of 213 files are displayed.

sql/ruoyi-vue-pro.sql
No preview for this file type
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/http/HttpUtils.java
1 1 package cn.iocoder.yudao.framework.common.util.http;
2 2  
3   -import cn.hutool.core.io.FileUtil;
4 3 import cn.hutool.core.map.TableMap;
5 4 import cn.hutool.core.net.url.UrlBuilder;
6   -import cn.hutool.core.util.ReferenceUtil;
7 5 import cn.hutool.core.util.ReflectUtil;
8 6  
9 7 import java.nio.charset.Charset;
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/IoUtils.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.common.util.io;
2 2  
3 3 import cn.hutool.core.io.IORuntimeException;
4 4 import cn.hutool.core.io.IoUtil;
5   -import cn.hutool.core.util.CharsetUtil;
6 5 import cn.hutool.core.util.StrUtil;
7 6  
8 7 import java.io.InputStream;
... ...
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClient.java
... ... @@ -44,7 +44,7 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
44 44 String dir = StrUtil.removeSuffix(filePath, fileName);
45 45 boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content));
46 46 if (!success) {
47   - throw new FtpException(StrUtil.format("上海文件到目标目录 ({}) 失败", filePath));
  47 + throw new FtpException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath));
48 48 }
49 49 // 拼接返回路径
50 50 return super.formatFileUrl(config.getDomain(), path);
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -75,12 +75,20 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
75 75 return selectList(new LambdaQueryWrapper<T>().in(field, values));
76 76 }
77 77  
  78 + /**
  79 + * 逐条插入,适合少量数据插入,或者对性能要求不高的场景
  80 + *
  81 + * 如果大量,请使用 {@link com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch(Collection)} 方法
  82 + * 使用示例,可见 RoleMenuBatchInsertMapper、UserRoleBatchInsertMapper 类
  83 + *
  84 + * @param entities 实体们
  85 + */
78 86 default void insertBatch(Collection<T> entities) {
79   - // TODO 芋艿:修改成支持批量的
80 87 entities.forEach(this::insert);
81 88 }
82 89  
83 90 default void updateBatch(T update) {
84 91 update(update, new QueryWrapper<>());
85 92 }
  93 +
86 94 }
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/StringLiSTTypeHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.type;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import org.apache.ibatis.type.JdbcType;
  6 +import org.apache.ibatis.type.MappedJdbcTypes;
  7 +import org.apache.ibatis.type.MappedTypes;
  8 +import org.apache.ibatis.type.TypeHandler;
  9 +
  10 +import java.sql.CallableStatement;
  11 +import java.sql.PreparedStatement;
  12 +import java.sql.ResultSet;
  13 +import java.sql.SQLException;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * List<String> 的类型转换器实现类,对应数据库的 varchar 类型
  18 + *
  19 + * @author 永不言败
  20 + * @since 2022 3/23 12:50:15
  21 + */
  22 +@MappedJdbcTypes(JdbcType.VARCHAR)
  23 +@MappedTypes(List.class)
  24 +public class StringLiSTTypeHandler implements TypeHandler<List<String>> {
  25 +
  26 + private static final String COMMA = ",";
  27 +
  28 + @Override
  29 + public void setParameter(PreparedStatement ps, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
  30 + // 设置占位符
  31 + ps.setString(i, CollUtil.join(strings, COMMA));
  32 + }
  33 +
  34 + @Override
  35 + public List<String> getResult(ResultSet rs, String columnName) throws SQLException {
  36 + String value = rs.getString(columnName);
  37 + return getResult(value);
  38 + }
  39 +
  40 + @Override
  41 + public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {
  42 + String value = rs.getString(columnIndex);
  43 + return getResult(value);
  44 + }
  45 +
  46 + @Override
  47 + public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {
  48 + String value = cs.getString(columnIndex);
  49 + return getResult(value);
  50 + }
  51 +
  52 + private List<String> getResult(String value) {
  53 + if (value == null) {
  54 + return null;
  55 + }
  56 + return StrUtil.splitTrim(value, COMMA);
  57 + }
  58 +}
... ...
yudao-framework/yudao-spring-boot-starter-redis/pom.xml
... ... @@ -26,6 +26,12 @@
26 26 <groupId>org.redisson</groupId>
27 27 <artifactId>redisson-spring-boot-starter</artifactId>
28 28 </dependency>
  29 +
  30 + <dependency>
  31 + <groupId>org.springframework.boot</groupId>
  32 + <artifactId>spring-boot-starter-cache</artifactId> <!-- 实现对 Caches 的自动化配置 -->
  33 + </dependency>
  34 +
29 35 </dependencies>
30 36  
31 37 </project>
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.redis.config;
  2 +
  3 +import org.springframework.boot.autoconfigure.cache.CacheProperties;
  4 +import org.springframework.cache.annotation.EnableCaching;
  5 +import org.springframework.context.annotation.Bean;
  6 +import org.springframework.context.annotation.Configuration;
  7 +import org.springframework.context.annotation.Primary;
  8 +import org.springframework.data.redis.cache.RedisCacheConfiguration;
  9 +import org.springframework.data.redis.serializer.RedisSerializationContext;
  10 +import org.springframework.data.redis.serializer.RedisSerializer;
  11 +
  12 +/**
  13 + * Cache 配置类,基于 Redis 实现
  14 + */
  15 +@Configuration
  16 +@EnableCaching
  17 +public class YudaoCacheAutoConfiguration {
  18 +
  19 + /**
  20 + * RedisCacheConfiguration Bean
  21 + *
  22 + * 参考 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration 的 createConfiguration 方法
  23 + */
  24 + @Bean
  25 + @Primary
  26 + public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
  27 + // 设置使用 JSON 序列化方式
  28 + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
  29 + config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
  30 +
  31 + // 设置 CacheProperties.Redis 的属性
  32 + CacheProperties.Redis redisProperties = cacheProperties.getRedis();
  33 + if (redisProperties.getTimeToLive() != null) {
  34 + config = config.entryTtl(redisProperties.getTimeToLive());
  35 + }
  36 + if (redisProperties.getKeyPrefix() != null) {
  37 + config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
  38 + }
  39 + if (!redisProperties.isCacheNullValues()) {
  40 + config = config.disableCachingNullValues();
  41 + }
  42 + if (!redisProperties.isUseKeyPrefix()) {
  43 + config = config.disableKeyPrefix();
  44 + }
  45 + return config;
  46 + }
  47 +
  48 +}
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoRedisAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.redis.config;
2 2  
3   -import lombok.extern.slf4j.Slf4j;
4 3 import org.springframework.context.annotation.Bean;
5 4 import org.springframework.context.annotation.Configuration;
6 5 import org.springframework.data.redis.connection.RedisConnectionFactory;
... ... @@ -11,7 +10,6 @@ import org.springframework.data.redis.serializer.RedisSerializer;
11 10 * Redis 配置类
12 11 */
13 12 @Configuration
14   -@Slf4j
15 13 public class YudaoRedisAutoConfiguration {
16 14  
17 15 /**
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/resources/META-INF/spring.factories
1 1 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2   - cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration
  2 + cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration,\
  3 + cn.iocoder.yudao.framework.redis.config.YudaoCacheAutoConfiguration
... ...
yudao-framework/yudao-spring-boot-starter-redis/《芋道 Spring Boot Cache 入门》.md 0 → 100644
  1 +<http://www.iocoder.cn/Spring-Boot/Cache/?yudao>
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java
... ... @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 6 import com.fasterxml.jackson.annotation.JsonIgnore;
7 7 import lombok.Data;
8 8 import org.springframework.security.core.GrantedAuthority;
9   -import org.springframework.security.core.authority.SimpleGrantedAuthority;
10 9 import org.springframework.security.core.userdetails.UserDetails;
11 10  
12 11 import java.util.*;
... ... @@ -61,10 +60,6 @@ public class LoginUser implements UserDetails {
61 60 * 部门编号
62 61 */
63 62 private Long deptId;
64   - /**
65   - * 所属岗位
66   - */
67   - private Set<Long> postIds;
68 63  
69 64 // ========== 上下文 ==========
70 65 /**
... ...
yudao-framework/yudao-spring-boot-starter-test/pom.xml
... ... @@ -21,6 +21,17 @@
21 21 <artifactId>yudao-common</artifactId>
22 22 </dependency>
23 23  
  24 + <!-- DB 相关 -->
  25 + <dependency>
  26 + <groupId>cn.iocoder.boot</groupId>
  27 + <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
  28 + </dependency>
  29 +
  30 + <dependency>
  31 + <groupId>cn.iocoder.boot</groupId>
  32 + <artifactId>yudao-spring-boot-starter-redis</artifactId>
  33 + </dependency>
  34 +
24 35 <!-- Test 测试相关 -->
25 36 <dependency>
26 37 <groupId>org.mockito</groupId>
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbAndRedisUnitTest.java renamed to yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/ut/BaseDbAndRedisUnitTest.java
1   -package cn.iocoder.yudao.module.infra.test;
  1 +package cn.iocoder.yudao.framework.test.core.ut;
2 2  
3 3 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4 4 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java renamed to yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/ut/BaseDbUnitTest.java
1   -package cn.iocoder.yudao.module.bpm.test;
  1 +package cn.iocoder.yudao.framework.test.core.ut;
2 2  
3 3 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4 4 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java renamed to yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/ut/BaseRedisUnitTest.java
1   -package cn.iocoder.yudao.module.pay.test;
  1 +package cn.iocoder.yudao.framework.test.core.ut;
2 2  
3 3 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
4 4 import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java
... ... @@ -2,21 +2,18 @@ package cn.iocoder.yudao.framework.apilog.core.filter;
2 2  
3 3 import cn.hutool.core.exceptions.ExceptionUtil;
4 4 import cn.hutool.core.map.MapUtil;
5   -import cn.hutool.core.util.StrUtil;
6 5 import cn.hutool.extra.servlet.ServletUtil;
7   -import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
8   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
9 6 import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
10 7 import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
  8 +import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
  9 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  10 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
11 11 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
  12 +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
12 13 import cn.iocoder.yudao.framework.web.config.WebProperties;
  14 +import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter;
13 15 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14   -import cn.iocoder.yudao.framework.common.util.date.DateUtils;
15   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
16   -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
17   -import lombok.RequiredArgsConstructor;
18 16 import lombok.extern.slf4j.Slf4j;
19   -import org.springframework.web.filter.OncePerRequestFilter;
20 17  
21 18 import javax.servlet.FilterChain;
22 19 import javax.servlet.ServletException;
... ... @@ -26,27 +23,24 @@ import java.io.IOException;
26 23 import java.util.Date;
27 24 import java.util.Map;
28 25  
29   -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.*;
  26 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
30 27  
31 28 /**
32 29 * API 访问日志 Filter
33 30 *
34 31 * @author 芋道源码
35 32 */
36   -@RequiredArgsConstructor
37 33 @Slf4j
38   -public class ApiAccessLogFilter extends OncePerRequestFilter {
  34 +public class ApiAccessLogFilter extends ApiRequestFilter {
39 35  
40   - private final WebProperties webProperties;
41 36 private final String applicationName;
42 37  
43 38 private final ApiAccessLogFrameworkService apiAccessLogFrameworkService;
44 39  
45   - @Override
46   - protected boolean shouldNotFilter(HttpServletRequest request) {
47   - // 只过滤 API 请求的地址
48   - return !StrUtil.startWithAny(request.getRequestURI(), webProperties.getAppApi().getPrefix(),
49   - webProperties.getAppApi().getPrefix());
  40 + public ApiAccessLogFilter(WebProperties webProperties, String applicationName, ApiAccessLogFrameworkService apiAccessLogFrameworkService) {
  41 + super(webProperties);
  42 + this.applicationName = applicationName;
  43 + this.apiAccessLogFrameworkService = apiAccessLogFrameworkService;
50 44 }
51 45  
52 46 @Override
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
1 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2  
  3 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
3 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
4 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 6 import org.apache.ibatis.annotations.Mapper;
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.util.RandomUtil;
4   -import cn.iocoder.yudao.module.bpm.test.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
6 8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
7 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
8 10 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
9 11 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;
10 12 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO;
11   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
12   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
13 13 import org.junit.jupiter.api.Test;
14 14 import org.springframework.context.annotation.Import;
15 15  
... ... @@ -18,12 +18,12 @@ import java.util.List;
18 18 import java.util.stream.Collectors;
19 19 import java.util.stream.Stream;
20 20  
21   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FORM_NOT_EXISTS;
22 21 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
23 22 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
24 23 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
25 24 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
26 25 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  26 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FORM_NOT_EXISTS;
27 27 import static org.junit.jupiter.api.Assertions.*;
28 28  
29 29 /**
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3   -import cn.iocoder.yudao.module.bpm.test.BaseDbUnitTest;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
7   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
8   -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
9 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
10 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
11 5 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
12 7 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
13 8 import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
  11 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
  12 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
  13 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
14 14 import org.junit.jupiter.api.Assertions;
15 15 import org.junit.jupiter.api.Test;
16 16 import org.springframework.context.annotation.Import;
17 17  
18 18 import javax.annotation.Resource;
19 19  
20   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;
21 20 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  21 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;
22 22  
23 23 /**
24 24 * {@link BpmUserGroupServiceImpl} 的单元测试类
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
... ... @@ -215,6 +215,9 @@ public class BpmModelServiceImpl implements BpmModelService {
215 215 if (oldDefinition == null) {
216 216 return;
217 217 }
  218 + if(oldDefinition.isSuspended()) {
  219 + return;
  220 + }
218 221 processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
219 222 }
220 223  
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
... ... @@ -103,6 +103,9 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
103 103 }
104 104 // 执行查询
105 105 List<ProcessDefinition> processDefinitions = definitionQuery.list();
  106 + if (CollUtil.isEmpty(processDefinitions)) {
  107 + return Collections.emptyList();
  108 + }
106 109  
107 110 // 获得 BpmProcessDefinitionDO Map
108 111 List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java deleted
1   -package cn.iocoder.yudao.module.bpm.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
6   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
7   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
8   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
9   -import org.springframework.boot.test.context.SpringBootTest;
10   -import org.springframework.context.annotation.Import;
11   -import org.springframework.test.context.ActiveProfiles;
12   -import org.springframework.test.context.jdbc.Sql;
13   -
14   -/**
15   - * 依赖内存 DB 的单元测试
16   - *
17   - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
18   - *
19   - * @author 芋道源码
20   - */
21   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
22   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
23   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
24   -public class BaseDbUnitTest {
25   -
26   - @Import({
27   - // DB 配置类
28   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
29   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
30   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
31   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
32   - // MyBatis 配置类
33   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
34   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
35   - })
36   - public static class Application {
37   - }
38   -
39   -}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
... ... @@ -236,6 +236,9 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
236 236 }
237 237 // 执行查询
238 238 List<ProcessDefinition> processDefinitions = definitionQuery.list();
  239 + if (CollUtil.isEmpty(processDefinitions)) {
  240 + return Collections.emptyList();
  241 + }
239 242  
240 243 // 获得 BpmProcessDefinitionDO Map
241 244 List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
... ... @@ -21,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.permission.RoleApi;
21 21 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
22 22 import lombok.extern.slf4j.Slf4j;
23 23 import org.flowable.bpmn.model.BpmnModel;
24   -import org.flowable.bpmn.model.FlowElement;
25 24 import org.flowable.bpmn.model.UserTask;
26 25 import org.springframework.context.annotation.Lazy;
27 26 import org.springframework.stereotype.Service;
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.http 0 → 100644
  1 +### 请求 /infra/test-demo/get 接口 => 成功
  2 +GET {{baseUrl}}/infra/test-demo/get?id=106
  3 +Authorization: Bearer {{token}}
  4 +tenant-id: {{adminTenentId}}
  5 +
  6 +### 请求 /infra/test-demo/update 接口 => 成功
  7 +PUT {{baseUrl}}/infra/test-demo/update
  8 +Authorization: Bearer {{token}}
  9 +tenant-id: {{adminTenentId}}
  10 +Content-Type: application/json
  11 +
  12 +
  13 +{
  14 + "id": 106,
  15 + "name": "测试",
  16 + "status": "0",
  17 + "type": 1,
  18 + "category": 1
  19 +}
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.java
1 1 package cn.iocoder.yudao.module.infra.controller.admin.test;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
3 7 import cn.iocoder.yudao.module.infra.controller.admin.test.vo.*;
4 8 import cn.iocoder.yudao.module.infra.convert.test.TestDemoConvert;
5 9 import cn.iocoder.yudao.module.infra.dal.dataobject.test.TestDemoDO;
6   -import org.springframework.web.bind.annotation.*;
7   -import javax.annotation.Resource;
8   -import org.springframework.validation.annotation.Validated;
  10 +import cn.iocoder.yudao.module.infra.service.test.TestDemoService;
  11 +import io.swagger.annotations.Api;
  12 +import io.swagger.annotations.ApiImplicitParam;
  13 +import io.swagger.annotations.ApiOperation;
9 14 import org.springframework.security.access.prepost.PreAuthorize;
10   -import io.swagger.annotations.*;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
11 17  
12   -import javax.validation.*;
13   -import javax.servlet.http.*;
14   -import java.util.*;
  18 +import javax.annotation.Resource;
  19 +import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
15 21 import java.io.IOException;
  22 +import java.util.Collection;
  23 +import java.util.List;
16 24  
17   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
18   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
19 25 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
20   -
21   -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
22   -
23   -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
24   -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
25   -
26   -import cn.iocoder.yudao.module.infra.controller.admin.test.vo.*;
27   -import cn.iocoder.yudao.module.infra.service.test.TestDemoService;
  26 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
28 27  
29 28 @Api(tags = "管理后台 - 字典类型")
30 29 @RestController
... ... @@ -37,13 +36,15 @@ public class TestDemoController {
37 36  
38 37 @PostMapping("/create")
39 38 @ApiOperation("创建字典类型")
40   - @PreAuthorize("@ss.hasPermission('infra:test-demo:create')") public CommonResult<Long> createTestDemo(@Valid @RequestBody TestDemoCreateReqVO createReqVO) {
  39 + @PreAuthorize("@ss.hasPermission('infra:test-demo:create')")
  40 + public CommonResult<Long> createTestDemo(@Valid @RequestBody TestDemoCreateReqVO createReqVO) {
41 41 return success(testDemoService.createTestDemo(createReqVO));
42 42 }
43 43  
44 44 @PutMapping("/update")
45 45 @ApiOperation("更新字典类型")
46   - @PreAuthorize("@ss.hasPermission('infra:test-demo:update')") public CommonResult<Boolean> updateTestDemo(@Valid @RequestBody TestDemoUpdateReqVO updateReqVO) {
  46 + @PreAuthorize("@ss.hasPermission('infra:test-demo:update')")
  47 + public CommonResult<Boolean> updateTestDemo(@Valid @RequestBody TestDemoUpdateReqVO updateReqVO) {
47 48 testDemoService.updateTestDemo(updateReqVO);
48 49 return success(true);
49 50 }
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java
... ... @@ -160,8 +160,9 @@ public class CodegenBuilder {
160 160 // 处理 javaField 字段
161 161 column.setJavaField(toCamelCase(column.getColumnName()));
162 162 // 处理 dictType 字段,暂无
163   - // 处理 javaType 字段
164   - String dbType = subBefore(column.getColumnType(), '(', false);
  163 + // 处理 javaType 字段(兼容无符号类型)
  164 + String dbType = replaceIgnoreCase(subBefore(column.getColumnType(), '(', false),
  165 + " UNSIGNED", "");
165 166 javaTypeMappings.entrySet().stream()
166 167 .filter(entry -> entry.getValue().contains(dbType))
167 168 .findFirst().ifPresent(entry -> column.setJavaType(entry.getKey()));
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -217,7 +217,7 @@ public class CodegenEngine {
217 217 private static String mapperXmlFilePath() {
218 218 return "yudao-module-${table.moduleName}/" + // 顶级模块
219 219 "yudao-module-${table.moduleName}-impl/" + // 子模块
220   - "src/resources/mapper/${table.businessName}/${table.className}Mapper.xml";
  220 + "src/main/java/resources/mapper/${table.businessName}/${table.className}Mapper.xml";
221 221 }
222 222  
223 223 private static String vueTemplatePath(String path) {
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java
... ... @@ -8,6 +8,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoUpdateReqV
8 8 import cn.iocoder.yudao.module.infra.convert.test.TestDemoConvert;
9 9 import cn.iocoder.yudao.module.infra.dal.dataobject.test.TestDemoDO;
10 10 import cn.iocoder.yudao.module.infra.dal.mysql.test.TestDemoMapper;
  11 +import org.springframework.cache.annotation.CacheEvict;
  12 +import org.springframework.cache.annotation.Cacheable;
11 13 import org.springframework.stereotype.Service;
12 14 import org.springframework.validation.annotation.Validated;
13 15  
... ... @@ -40,6 +42,7 @@ public class TestDemoServiceImpl implements TestDemoService {
40 42 }
41 43  
42 44 @Override
  45 + @CacheEvict(value = "test", key = "#updateReqVO.id")
43 46 public void updateTestDemo(TestDemoUpdateReqVO updateReqVO) {
44 47 // 校验存在
45 48 this.validateTestDemoExists(updateReqVO.getId());
... ... @@ -49,6 +52,7 @@ public class TestDemoServiceImpl implements TestDemoService {
49 52 }
50 53  
51 54 @Override
  55 + @CacheEvict(value = "test", key = "#id")
52 56 public void deleteTestDemo(Long id) {
53 57 // 校验存在
54 58 this.validateTestDemoExists(id);
... ... @@ -63,6 +67,7 @@ public class TestDemoServiceImpl implements TestDemoService {
63 67 }
64 68  
65 69 @Override
  70 + @Cacheable(cacheNames = "test", key = "#id")
66 71 public TestDemoDO getTestDemo(Long id) {
67 72 return testDemoMapper.selectById(id);
68 73 }
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/resources/codegen/java/test/serviceTest.vm
... ... @@ -6,7 +6,7 @@ import org.springframework.boot.test.mock.mockito.MockBean;
6 6  
7 7 import javax.annotation.Resource;
8 8  
9   -import ${basePackage}.module.${table.moduleName}.test.BaseDbUnitTest;## 每个项目,默认有一个基础 DB Test 基类
  9 +import ${baseFrameworkPackage}.test.core.ut.BaseDbUnitTest;
10 10  
11 11 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
12 12 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
... ...
yudao-module-infra/yudao-module-infra-impl/src/main/resources/codegen/vue/views/index.vue.vm
... ... @@ -2,7 +2,7 @@
2 2 <div class="app-container">
3 3  
4 4 <!-- 搜索工作栏 -->
5   - <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  5 + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
6 6 #foreach($column in $columns)
7 7 #if ($column.listOperation)
8 8 #set ($dictType=$column.dictType)
... ... @@ -11,7 +11,7 @@
11 11 #set ($comment=$column.columnComment)
12 12 #if ($column.htmlType == "input")
13 13 <el-form-item label="${comment}" prop="${javaField}">
14   - <el-input v-model="queryParams.${javaField}" placeholder="请输入${comment}" clearable size="small" @keyup.enter.native="handleQuery"/>
  14 + <el-input v-model="queryParams.${javaField}" placeholder="请输入${comment}" clearable @keyup.enter.native="handleQuery"/>
15 15 </el-form-item>
16 16 #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
17 17 <el-form-item label="${comment}" prop="${javaField}">
... ... @@ -27,11 +27,11 @@
27 27 #elseif($column.htmlType == "datetime")
28 28 #if ($column.listOperationCondition != "BETWEEN")## 非范围
29 29 <el-form-item label="${comment}" prop="${javaField}">
30   - <el-date-picker clearable size="small" v-model="queryParams.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
  30 + <el-date-picker clearable v-model="queryParams.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
31 31 </el-form-item>
32 32 #else## 范围
33 33 <el-form-item label="${comment}">
34   - <el-date-picker v-model="dateRange${AttrName}" size="small" style="width: 240px" value-format="yyyy-MM-dd"
  34 + <el-date-picker v-model="dateRange${AttrName}" style="width: 240px" value-format="yyyy-MM-dd"
35 35 type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
36 36 </el-form-item>
37 37 #end
... ... @@ -39,8 +39,8 @@
39 39 #end
40 40 #end
41 41 <el-form-item>
42   - <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
43   - <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  42 + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
  43 + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
44 44 </el-form-item>
45 45 </el-form>
46 46  
... ... @@ -160,7 +160,7 @@
160 160 </el-form-item>
161 161 #elseif($column.htmlType == "datetime")## 时间框
162 162 <el-form-item label="${comment}" prop="${javaField}">
163   - <el-date-picker clearable size="small" v-model="form.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
  163 + <el-date-picker clearable v-model="form.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
164 164 </el-form-item>
165 165 #elseif($column.htmlType == "textarea")## 文本框
166 166 <el-form-item label="${comment}" prop="${javaField}">
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.service.config;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
5 5 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
6 7 import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
7 8 import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
8 9 import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO;
... ... @@ -12,7 +13,6 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
12 13 import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper;
13 14 import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
14 15 import cn.iocoder.yudao.module.infra.mq.producer.config.ConfigProducer;
15   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
16 16 import org.junit.jupiter.api.Assertions;
17 17 import org.junit.jupiter.api.Test;
18 18 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
... ... @@ -7,13 +7,13 @@ import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
7 7 import cn.iocoder.yudao.framework.file.core.client.FileClientFactory;
8 8 import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig;
9 9 import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
10 11 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigCreateReqVO;
11 12 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
12 13 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigUpdateReqVO;
13 14 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
14 15 import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
15 16 import cn.iocoder.yudao.module.infra.mq.producer.file.FileConfigProducer;
16   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
17 17 import lombok.Data;
18 18 import org.junit.jupiter.api.Test;
19 19 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java
... ... @@ -4,11 +4,11 @@ import cn.hutool.core.io.resource.ResourceUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
6 6 import cn.iocoder.yudao.framework.file.core.client.FileClient;
  7 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
7 8 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
8 9 import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
9 10 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
10 11 import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
11   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
12 12 import org.junit.jupiter.api.Test;
13 13 import org.springframework.boot.test.mock.mockito.MockBean;
14 14 import org.springframework.context.annotation.Import;
... ... @@ -18,7 +18,7 @@ import javax.annotation.Resource;
18 18 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
19 19 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
20 20 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
21   -import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
  21 +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
22 22 import static org.junit.jupiter.api.Assertions.*;
23 23 import static org.mockito.ArgumentMatchers.same;
24 24 import static org.mockito.Mockito.*;
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceTest.java
1 1 package cn.iocoder.yudao.module.infra.service.job;
2 2  
3   -import static cn.hutool.core.util.RandomUtil.randomEle;
4   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
5   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
6   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
7   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
8   -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
9   -import static org.junit.jupiter.api.Assertions.assertEquals;
10   -import static org.junit.jupiter.api.Assertions.assertNotNull;
11   -
12   -import java.util.ArrayList;
13   -import java.util.List;
14   -
15   -import javax.annotation.Resource;
16   -
17   -import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
18   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
19   -import org.junit.jupiter.api.Test;
20   -import org.springframework.context.annotation.Import;
21   -
22 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
23 6 import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
24 7 import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
25 9 import cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper;
26 10 import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum;
27   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.context.annotation.Import;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.util.ArrayList;
  16 +import java.util.List;
  17 +
  18 +import static cn.hutool.core.util.RandomUtil.randomEle;
  19 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
  20 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  21 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  22 +import static org.junit.jupiter.api.Assertions.assertEquals;
  23 +import static org.junit.jupiter.api.Assertions.assertNotNull;
28 24  
29 25 @Import(JobLogServiceImpl.class)
30 26 public class JobLogServiceTest extends BaseDbUnitTest {
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceTest.java
1 1 package cn.iocoder.yudao.module.infra.service.job;
2 2  
3   -import static cn.hutool.core.util.RandomUtil.randomEle;
4   -import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
5   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
6   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
7   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
8   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
9   -import static org.junit.jupiter.api.Assertions.assertEquals;
10   -import static org.junit.jupiter.api.Assertions.assertNotNull;
11   -import static org.junit.jupiter.api.Assertions.assertNull;
12   -import static org.mockito.ArgumentMatchers.eq;
13   -import static org.mockito.Mockito.times;
14   -import static org.mockito.Mockito.verify;
15   -
16   -import java.util.ArrayList;
17   -import java.util.List;
18   -
19   -import javax.annotation.Resource;
20   -
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  5 +import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
21 7 import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO;
  8 +import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
  9 +import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
22 10 import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO;
23 11 import cn.iocoder.yudao.module.infra.convert.job.JobConvert;
24 12 import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
25   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
  13 +import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
  14 +import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
26 15 import org.junit.jupiter.api.Test;
27 16 import org.quartz.SchedulerException;
28 17 import org.springframework.boot.test.mock.mockito.MockBean;
29 18 import org.springframework.context.annotation.Import;
30 19  
31   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
32   -import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager;
33   -import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
34   -import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
35   -import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
36   -import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
37   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  20 +import javax.annotation.Resource;
  21 +import java.util.ArrayList;
  22 +import java.util.List;
  23 +
  24 +import static cn.hutool.core.util.RandomUtil.randomEle;
  25 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  26 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  27 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  28 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
  29 +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
  30 +import static org.junit.jupiter.api.Assertions.*;
  31 +import static org.mockito.ArgumentMatchers.eq;
  32 +import static org.mockito.Mockito.times;
  33 +import static org.mockito.Mockito.verify;
38 34  
39 35 @Import(JobServiceImpl.class)
40 36 public class JobServiceTest extends BaseDbUnitTest {
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java
... ... @@ -6,12 +6,12 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 6 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
7 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  9 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 10 import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
10 11 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
11 12 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
12 13 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
13 14 import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiAccessLogMapper;
14   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
15 15 import org.junit.jupiter.api.Test;
16 16 import org.springframework.context.annotation.Import;
17 17  
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImplTest.java
... ... @@ -5,13 +5,13 @@ import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDT
5 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  8 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
8 9 import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
9 10 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
10 11 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
11 12 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
12 13 import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper;
13 14 import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum;
14   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
15 15 import org.junit.jupiter.api.Assertions;
16 16 import org.junit.jupiter.api.Test;
17 17 import org.springframework.context.annotation.Import;
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImplTest.java
... ... @@ -3,13 +3,13 @@ package cn.iocoder.yudao.module.infra.service.test;
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
6   -import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoExportReqVO;
7   -import cn.iocoder.yudao.module.infra.dal.dataobject.test.TestDemoDO;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
8 7 import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoCreateReqVO;
  8 +import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoExportReqVO;
9 9 import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoPageReqVO;
10 10 import cn.iocoder.yudao.module.infra.controller.admin.test.vo.TestDemoUpdateReqVO;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.test.TestDemoDO;
11 12 import cn.iocoder.yudao.module.infra.dal.mysql.test.TestDemoMapper;
12   -import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
13 13 import org.junit.jupiter.api.Test;
14 14 import org.springframework.context.annotation.Import;
15 15  
... ...
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbUnitTest.java deleted
1   -package cn.iocoder.yudao.module.infra.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
6   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
7   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
8   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
9   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
10   -import org.springframework.boot.test.context.SpringBootTest;
11   -import org.springframework.context.annotation.Import;
12   -import org.springframework.test.context.ActiveProfiles;
13   -import org.springframework.test.context.jdbc.Sql;
14   -
15   -/**
16   - * 依赖内存 DB 的单元测试
17   - *
18   - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
19   - *
20   - * @author 芋道源码
21   - */
22   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
23   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
24   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
25   -public class BaseDbUnitTest {
26   -
27   - @Import({
28   - // DB 配置类
29   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
30   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
31   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
32   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
33   - SqlInitializationTestConfiguration.class, // SQL 初始化
34   - // MyBatis 配置类
35   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
36   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
37   - })
38   - public static class Application {
39   - }
40   -
41   -}
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/QuartzTestConfiguration.java deleted
1   -package cn.iocoder.yudao.module.infra.test;
2   -
3   -import org.mockito.Mockito;
4   -import org.quartz.Scheduler;
5   -import org.springframework.context.annotation.Bean;
6   -import org.springframework.context.annotation.Configuration;
7   -
8   -@Configuration
9   -public class QuartzTestConfiguration {
10   -
11   - @Bean
12   - public Scheduler scheduler() {
13   - return Mockito.mock(Scheduler.class);
14   - }
15   -
16   -}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
... ... @@ -33,6 +33,6 @@ public interface AuthConvert {
33 33  
34 34 SmsCodeSendReqDTO convert(AppAuthSendSmsReqVO reqVO);
35 35 SmsCodeUseReqDTO convert(AppAuthResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
36   - SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String userIp);
  36 + SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp);
37 37  
38 38 }
... ...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
... ... @@ -87,7 +87,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
87 87 LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword());
88 88  
89 89 // 缓存登录用户到 Redis 中,返回 sessionId 编号
90   - return userSessionApi.createUserSession(loginUser, userIp, userAgent);
  90 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
91 91 }
92 92  
93 93 @Override
... ... @@ -101,11 +101,10 @@ public class MemberAuthServiceImpl implements MemberAuthService {
101 101 Assert.notNull(user, "获取用户失败,结果为空");
102 102  
103 103 // 执行登陆
104   - this.createLoginLog(user.getMobile(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.SUCCESS);
105 104 LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
106 105  
107 106 // 缓存登录用户到 Redis 中,返回 sessionId 编号
108   - return userSessionApi.createUserSession(loginUser, userIp, userAgent);
  107 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SMS, userIp, userAgent);
109 108 }
110 109  
111 110 @Override
... ... @@ -122,7 +121,6 @@ public class MemberAuthServiceImpl implements MemberAuthService {
122 121 if (user == null) {
123 122 throw exception(USER_NOT_EXISTS);
124 123 }
125   - this.createLoginLog(user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, LoginResultEnum.SUCCESS);
126 124  
127 125 // 创建 LoginUser 对象
128 126 LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
... ... @@ -131,7 +129,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
131 129 socialUserApi.bindSocialUser(AuthConvert.INSTANCE.convert(loginUser.getId(), getUserType().getValue(), reqVO));
132 130  
133 131 // 缓存登录用户到 Redis 中,返回 sessionId 编号
134   - return userSessionApi.createUserSession(loginUser, userIp, userAgent);
  132 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
135 133 }
136 134  
137 135 @Override
... ... @@ -150,6 +148,13 @@ public class MemberAuthServiceImpl implements MemberAuthService {
150 148 return sessionId;
151 149 }
152 150  
  151 + private String createUserSessionAfterLoginSuccess(LoginUser loginUser, LoginLogTypeEnum logType, String userIp, String userAgent) {
  152 + // 插入登陆日志
  153 + createLoginLog(loginUser.getUsername(), logType, LoginResultEnum.SUCCESS);
  154 + // 缓存登录用户到 Redis 中,返回 sessionId 编号
  155 + return userSessionApi.createUserSession(loginUser, userIp, userAgent);
  156 + }
  157 +
153 158 @Override
154 159 public void socialBind(Long userId, AppAuthSocialBindReqVO reqVO) {
155 160 // 绑定社交用户(新增)
... ... @@ -186,9 +191,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
186 191 this.createLoginLog(username, logType, LoginResultEnum.UNKNOWN_ERROR);
187 192 throw exception(AUTH_LOGIN_FAIL_UNKNOWN);
188 193 }
189   - // 登录成功的日志
190 194 Assert.notNull(authentication.getPrincipal(), "Principal 不会为空");
191   - this.createLoginLog(username, logType, LoginResultEnum.SUCCESS);
192 195 return (LoginUser) authentication.getPrincipal();
193 196 }
194 197  
... ...
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceTest.java
... ... @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.member.service.auth;
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
5 5 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
6 7 import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthResetPasswordReqVO;
7 8 import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthUpdatePasswordReqVO;
8 9 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 10 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
10 11 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
11   -import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest;
12 12 import cn.iocoder.yudao.module.system.api.auth.UserSessionApi;
13 13 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
14 14 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
... ...
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImplTest.java
... ... @@ -4,12 +4,12 @@ import cn.hutool.core.util.RandomUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
6 6 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
  7 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
7 8 import cn.iocoder.yudao.module.infra.api.file.FileApi;
8 9 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
9 10 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
10 11 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
11 12 import cn.iocoder.yudao.module.member.service.auth.MemberAuthServiceImpl;
12   -import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest;
13 13 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
14 14 import org.junit.jupiter.api.Test;
15 15 import org.springframework.boot.test.mock.mockito.MockBean;
... ... @@ -25,7 +25,8 @@ import static cn.hutool.core.util.RandomUtil.*;
25 25 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
26 26 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
27 27 import static org.junit.jupiter.api.Assertions.assertEquals;
28   -import static org.mockito.Mockito.*;
  28 +import static org.mockito.Mockito.eq;
  29 +import static org.mockito.Mockito.when;
29 30  
30 31 // TODO @芋艿:单测的 review,等逻辑都达成一致后
31 32 /**
... ...
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java deleted
1   -package cn.iocoder.yudao.module.member.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
6   -import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
7   -import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
8   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
9   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
10   -import org.redisson.spring.starter.RedissonAutoConfiguration;
11   -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
12   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
13   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
14   -import org.springframework.boot.test.context.SpringBootTest;
15   -import org.springframework.context.annotation.Import;
16   -import org.springframework.test.context.ActiveProfiles;
17   -import org.springframework.test.context.jdbc.Sql;
18   -
19   -/**
20   - * 依赖内存 DB + Redis 的单元测试
21   - *
22   - * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis
23   - *
24   - * @author 芋道源码
25   - */
26   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
27   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
28   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
29   -public class BaseDbAndRedisUnitTest {
30   -
31   - @Import({
32   - // DB 配置类
33   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
34   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
35   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
36   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
37   - SqlInitializationTestConfiguration.class, // SQL 初始化
38   - // MyBatis 配置类
39   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
40   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
41   -
42   - // Redis 配置类
43   - RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
44   - RedisAutoConfiguration.class, // Spring Redis 自动配置类
45   - YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
46   - RedissonAutoConfiguration.class, // Redisson 自动高配置类
47   - })
48   - public static class Application {
49   - }
50   -
51   -}
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java deleted
1   -package cn.iocoder.yudao.module.member.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
6   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
7   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
8   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
9   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
10   -import org.springframework.boot.test.context.SpringBootTest;
11   -import org.springframework.context.annotation.Import;
12   -import org.springframework.test.context.ActiveProfiles;
13   -import org.springframework.test.context.jdbc.Sql;
14   -
15   -/**
16   - * 依赖内存 DB 的单元测试
17   - *
18   - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
19   - *
20   - * @author 芋道源码
21   - */
22   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
23   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
24   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
25   -public class BaseDbUnitTest {
26   -
27   - @Import({
28   - // DB 配置类
29   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
30   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
31   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
32   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
33   - SqlInitializationTestConfiguration.class, // SQL 初始化
34   - // MyBatis 配置类
35   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
36   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
37   - })
38   - public static class Application {
39   - }
40   -
41   -}
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java
1 1 package cn.iocoder.yudao.module.pay.service.merchant;
2 2  
3 3 import cn.hutool.core.util.RandomUtil;
4   -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 7 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppCreateReqVO;
6 8 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppExportReqVO;
7 9 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppPageReqVO;
... ... @@ -10,9 +12,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
10 12 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
11 13 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayAppMapper;
12 14 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper;
13   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
14   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
15   -import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest;
16 15 import org.junit.jupiter.api.Test;
17 16 import org.mockito.Mockito;
18 17 import org.springframework.boot.test.mock.mockito.MockBean;
... ... @@ -28,7 +27,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
28 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 28 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
30 29 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
31   -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
  30 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_NOT_FOUND;
32 31 import static org.junit.jupiter.api.Assertions.*;
33 32  
34 33 @Import(PayAppServiceImpl.class)
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java
... ... @@ -6,13 +6,13 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
6 6 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
7 7 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
8 8 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  9 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 10 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO;
10 11 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO;
11 12 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO;
12 13 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelUpdateReqVO;
13 14 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
14 15 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayChannelMapper;
15   -import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest;
16 16 import com.alibaba.fastjson.JSON;
17 17 import org.junit.jupiter.api.Test;
18 18 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java
1 1 package cn.iocoder.yudao.module.pay.service.merchant;
2 2  
3 3 import cn.hutool.core.util.RandomUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4 7 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantCreateReqVO;
5 8 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExportReqVO;
6 9 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantPageReqVO;
7 10 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantUpdateReqVO;
8 11 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
9 12 import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper;
10   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
11   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
12   -import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest;
13 13 import org.junit.jupiter.api.Test;
14 14 import org.springframework.context.annotation.Import;
15 15  
... ... @@ -22,7 +22,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
22 22 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
23 23 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
24 24 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
25   -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
  25 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_MERCHANT_NOT_EXISTS;
26 26 import static org.junit.jupiter.api.Assertions.*;
27 27  
28 28 /**
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
7 7 import cn.iocoder.yudao.framework.pay.config.PayProperties;
8 8 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
9 9 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
10 11 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
11 12 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
12 13 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
... ... @@ -17,7 +18,6 @@ import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum;
17 18 import cn.iocoder.yudao.module.pay.service.merchant.PayAppService;
18 19 import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
19 20 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
20   -import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest;
21 21 import org.junit.jupiter.api.Test;
22 22 import org.springframework.boot.test.mock.mockito.MockBean;
23 23 import org.springframework.context.annotation.Import;
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java deleted
1   -package cn.iocoder.yudao.module.pay.service;
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
5 5 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
6 6 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  7 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
7 8 import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
8 9 import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO;
9 10 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
... ... @@ -16,7 +17,6 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
16 17 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
17 18 import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
18 19 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
19   -import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest;
20 20 import org.junit.jupiter.api.Test;
21 21 import org.springframework.boot.test.mock.mockito.MockBean;
22 22 import org.springframework.context.annotation.Import;
... ...
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java deleted
1   -package cn.iocoder.yudao.module.pay.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
6   -import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
7   -import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
8   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
9   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
10   -import org.redisson.spring.starter.RedissonAutoConfiguration;
11   -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
12   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
13   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
14   -import org.springframework.boot.test.context.SpringBootTest;
15   -import org.springframework.context.annotation.Import;
16   -import org.springframework.test.context.ActiveProfiles;
17   -import org.springframework.test.context.jdbc.Sql;
18   -
19   -/**
20   - * 依赖内存 DB + Redis 的单元测试
21   - *
22   - * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis
23   - *
24   - * @author 芋道源码
25   - */
26   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
27   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
28   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
29   -public class BaseDbAndRedisUnitTest {
30   -
31   - @Import({
32   - // DB 配置类
33   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
34   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
35   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
36   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
37   - SqlInitializationTestConfiguration.class, // SQL 初始化
38   - // MyBatis 配置类
39   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
40   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
41   -
42   - // Redis 配置类
43   - RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
44   - RedisAutoConfiguration.class, // Spring Redis 自动配置类
45   - YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
46   - RedissonAutoConfiguration.class, // Redisson 自动高配置类
47   - })
48   - public static class Application {
49   - }
50   -
51   -}
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java deleted
1   -package cn.iocoder.yudao.module.pay.test;
2   -
3   -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
4   -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
5   -import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
6   -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
7   -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
8   -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
9   -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
10   -import org.springframework.boot.test.context.SpringBootTest;
11   -import org.springframework.context.annotation.Import;
12   -import org.springframework.test.context.ActiveProfiles;
13   -import org.springframework.test.context.jdbc.Sql;
14   -
15   -/**
16   - * 依赖内存 DB 的单元测试
17   - *
18   - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
19   - *
20   - * @author 芋道源码
21   - */
22   -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
23   -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
24   -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
25   -public class BaseDbUnitTest {
26   -
27   - @Import({
28   - // DB 配置类
29   - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
30   - DataSourceAutoConfiguration.class, // Spring DB 自动配置类
31   - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
32   - DruidDataSourceAutoConfigure.class, // Druid 自动配置类
33   - SqlInitializationTestConfiguration.class, // SQL 初始化
34   - // MyBatis 配置类
35   - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
36   - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
37   - })
38   - public static class Application {
39   - }
40   -
41   -}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sensitiveword/SensitiveWordApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.sensitiveword;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * 敏感词 API 接口
  7 + *
  8 + * @author 永不言败
  9 + */
  10 +public interface SensitiveWordApi {
  11 +
  12 + /**
  13 + * 获得文本所包含的不合法的敏感词数组
  14 + *
  15 + * @param text 文本
  16 + * @param tags 标签数组
  17 + * @return 不合法的敏感词数组
  18 + */
  19 + List<String> validateText(String text, List<String> tags);
  20 +
  21 + /**
  22 + * 判断文本是否包含敏感词
  23 + *
  24 + * @param text 文本
  25 + * @param tags 表述数组
  26 + * @return 是否包含
  27 + */
  28 + boolean isTextValid(String text, List<String> tags);
  29 +
  30 +}
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java
... ... @@ -14,16 +14,16 @@ public interface DictTypeConstants {
14 14  
15 15 String USER_SEX = "system_user_sex"; // 用户性别
16 16  
17   - String OPERATE_TYPE = "sys_operate_type"; // 操作类型
  17 + String OPERATE_TYPE = "system_operate_type"; // 操作类型
18 18  
19   - String LOGIN_TYPE = "sys_login_type"; // 登录日志的类型
20   - String LOGIN_RESULT = "sys_login_result"; // 登录结果
  19 + String LOGIN_TYPE = "system_login_type"; // 登录日志的类型
  20 + String LOGIN_RESULT = "system_login_result"; // 登录结果
21 21  
22 22 String ERROR_CODE_TYPE = "system_error_code_type"; // 错误码的类型枚举
23 23  
24   - String SMS_CHANNEL_CODE = "sys_sms_channel_code"; // 短信渠道编码
25   - String SMS_TEMPLATE_TYPE = "sys_sms_template_type"; // 短信模板类型
26   - String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态
27   - String SMS_RECEIVE_STATUS = "sys_sms_receive_status"; // 短信接收状态
  24 + String SMS_CHANNEL_CODE = "system_sms_channel_code"; // 短信渠道编码
  25 + String SMS_TEMPLATE_TYPE = "system_sms_template_type"; // 短信模板类型
  26 + String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态
  27 + String SMS_RECEIVE_STATUS = "system_sms_receive_status"; // 短信接收状态
28 28  
29 29 }
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
... ... @@ -119,4 +119,8 @@ public interface ErrorCodeConstants {
119 119 ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1002018001, "社交解绑失败,非当前用户绑定");
120 120 ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1002018002, "社交授权失败,找不到对应的用户");
121 121  
  122 + // ========== 系统铭感词 1002019000 =========
  123 + ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1002019000, "系统敏感词在所有标签中都不存在");
  124 + ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1002019001, "系统敏感词已在标签中存在");
  125 +
122 126 }
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/api/sensitiveword/SensitiveWordApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService;
  4 +import org.springframework.stereotype.Service;
  5 +
  6 +import javax.annotation.Resource;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 敏感词 API 实现类
  11 + *
  12 + * @author 永不言败
  13 + */
  14 +@Service
  15 +public class SensitiveWordApiImpl implements SensitiveWordApi {
  16 +
  17 + @Resource
  18 + private SensitiveWordService sensitiveWordService;
  19 +
  20 + @Override
  21 + public List<String> validateText(String text, List<String> tags) {
  22 + return sensitiveWordService.validateText(text, tags);
  23 + }
  24 +
  25 + @Override
  26 + public boolean isTextValid(String text, List<String> tags) {
  27 + return sensitiveWordService.isTextValid(text, tags);
  28 + }
  29 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.http 0 → 100644
  1 +### 请求 /system/sensitive-word/validate-text 接口 => 成功
  2 +GET {{baseUrl}}/system/sensitive-word/validate-text?text=XXX&tags=短信&tags=蔬菜
  3 +Authorization: Bearer {{token}}
  4 +tenant-id: {{adminTenentId}}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  7 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.*;
  8 +import cn.iocoder.yudao.module.system.convert.sensitiveword.SensitiveWordConvert;
  9 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  10 +import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService;
  11 +import io.swagger.annotations.Api;
  12 +import io.swagger.annotations.ApiImplicitParam;
  13 +import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
  21 +import java.io.IOException;
  22 +import java.util.List;
  23 +import java.util.Set;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  26 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  27 +
  28 +@Api(tags = "管理后台 - 敏感词")
  29 +@RestController
  30 +@RequestMapping("/system/sensitive-word")
  31 +@Validated
  32 +public class SensitiveWordController {
  33 +
  34 + @Resource
  35 + private SensitiveWordService sensitiveWordService;
  36 +
  37 + @PostMapping("/create")
  38 + @ApiOperation("创建敏感词")
  39 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:create')")
  40 + public CommonResult<Long> createSensitiveWord(@Valid @RequestBody SensitiveWordCreateReqVO createReqVO) {
  41 + return success(sensitiveWordService.createSensitiveWord(createReqVO));
  42 + }
  43 +
  44 + @PutMapping("/update")
  45 + @ApiOperation("更新敏感词")
  46 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:update')")
  47 + public CommonResult<Boolean> updateSensitiveWord(@Valid @RequestBody SensitiveWordUpdateReqVO updateReqVO) {
  48 + sensitiveWordService.updateSensitiveWord(updateReqVO);
  49 + return success(true);
  50 + }
  51 +
  52 + @DeleteMapping("/delete")
  53 + @ApiOperation("删除敏感词")
  54 + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
  55 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:delete')")
  56 + public CommonResult<Boolean> deleteSensitiveWord(@RequestParam("id") Long id) {
  57 + sensitiveWordService.deleteSensitiveWord(id);
  58 + return success(true);
  59 + }
  60 +
  61 + @GetMapping("/get")
  62 + @ApiOperation("获得敏感词")
  63 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  64 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
  65 + public CommonResult<SensitiveWordRespVO> getSensitiveWord(@RequestParam("id") Long id) {
  66 + SensitiveWordDO sensitiveWord = sensitiveWordService.getSensitiveWord(id);
  67 + return success(SensitiveWordConvert.INSTANCE.convert(sensitiveWord));
  68 + }
  69 +
  70 + @GetMapping("/page")
  71 + @ApiOperation("获得敏感词分页")
  72 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
  73 + public CommonResult<PageResult<SensitiveWordRespVO>> getSensitiveWordPage(@Valid SensitiveWordPageReqVO pageVO) {
  74 + PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(pageVO);
  75 + return success(SensitiveWordConvert.INSTANCE.convertPage(pageResult));
  76 + }
  77 +
  78 + @GetMapping("/export-excel")
  79 + @ApiOperation("导出敏感词 Excel")
  80 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:export')")
  81 + @OperateLog(type = EXPORT)
  82 + public void exportSensitiveWordExcel(@Valid SensitiveWordExportReqVO exportReqVO,
  83 + HttpServletResponse response) throws IOException {
  84 + List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordList(exportReqVO);
  85 + // 导出 Excel
  86 + List<SensitiveWordExcelVO> datas = SensitiveWordConvert.INSTANCE.convertList02(list);
  87 + ExcelUtils.write(response, "敏感词.xls", "数据", SensitiveWordExcelVO.class, datas);
  88 + }
  89 +
  90 + @GetMapping("/get-tags")
  91 + @ApiOperation("获取所有敏感词的标签数组")
  92 + @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
  93 + public CommonResult<Set<String>> getSensitiveWordTags() throws IOException {
  94 + return success(sensitiveWordService.getSensitiveWordTags());
  95 + }
  96 +
  97 + @GetMapping("/validate-text")
  98 + @ApiOperation("获得文本所包含的不合法的敏感词数组")
  99 + public CommonResult<List<String>> validateText(@RequestParam("text") String text,
  100 + @RequestParam(value = "tags", required = false) List<String> tags) {
  101 + return success(sensitiveWordService.validateText(text, tags));
  102 + }
  103 +
  104 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +import java.util.List;
  8 +
  9 +/**
  10 +* 敏感词 Base VO,提供给添加、修改、详细的子 VO 使用
  11 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 +*/
  13 +@Data
  14 +public class SensitiveWordBaseVO {
  15 +
  16 + @ApiModelProperty(value = "敏感词", required = true, example = "敏感词")
  17 + @NotNull(message = "敏感词不能为空")
  18 + private String name;
  19 +
  20 + @ApiModelProperty(value = "标签", required = true, example = "短信,评论")
  21 + @NotNull(message = "标签不能为空")
  22 + private List<String> tags;
  23 +
  24 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类")
  25 + @NotNull(message = "状态不能为空")
  26 + private Integer status;
  27 +
  28 + @ApiModelProperty(value = "描述", example = "污言秽语")
  29 + private String description;
  30 +
  31 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@ApiModel("管理后台 - 敏感词创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class SensitiveWordCreateReqVO extends SensitiveWordBaseVO {
  13 +
  14 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelProperty;
  4 +import lombok.Data;
  5 +
  6 +import java.util.Date;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 敏感词 Excel VO
  11 + *
  12 + * @author 永不言败
  13 + */
  14 +@Data
  15 +public class SensitiveWordExcelVO {
  16 +
  17 + @ExcelProperty("编号")
  18 + private Long id;
  19 +
  20 + @ExcelProperty("敏感词")
  21 + private String name;
  22 +
  23 + @ExcelProperty("标签")
  24 + private List<String> tags;
  25 +
  26 + @ExcelProperty("状态,true-启用,false-禁用")
  27 + private Integer status;
  28 +
  29 + @ExcelProperty("描述")
  30 + private String description;
  31 +
  32 + @ExcelProperty("创建时间")
  33 + private Date createTime;
  34 +
  35 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.util.Date;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@ApiModel(value = "管理后台 - 敏感词 Excel 导出 Request VO", description = "参数和 SensitiveWordPageReqVO 是一致的")
  13 +@Data
  14 +public class SensitiveWordExportReqVO {
  15 +
  16 + @ApiModelProperty(value = "敏感词", example = "敏感词")
  17 + private String name;
  18 +
  19 + @ApiModelProperty(value = "标签", example = "短信,评论")
  20 + private String tag;
  21 +
  22 + @ApiModelProperty(value = "状态", example = "true-启用,false-禁用")
  23 + private Integer status;
  24 +
  25 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  26 + @ApiModelProperty(value = "开始创建时间")
  27 + private Date beginCreateTime;
  28 +
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + @ApiModelProperty(value = "结束创建时间")
  31 + private Date endCreateTime;
  32 +
  33 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import java.util.Date;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  14 +
  15 +@ApiModel("管理后台 - 敏感词分页 Request VO")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +public class SensitiveWordPageReqVO extends PageParam {
  20 +
  21 + @ApiModelProperty(value = "敏感词", example = "敏感词")
  22 + private String name;
  23 +
  24 + @ApiModelProperty(value = "标签", example = "短信,评论")
  25 + private String tag;
  26 +
  27 + @ApiModelProperty(value = "状态", example = "true-启用,true-禁用")
  28 + private Integer status;
  29 +
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + @ApiModelProperty(value = "开始创建时间")
  32 + private Date beginCreateTime;
  33 +
  34 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  35 + @ApiModelProperty(value = "结束创建时间")
  36 + private Date endCreateTime;
  37 +
  38 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("管理后台 - 敏感词 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class SensitiveWordRespVO extends SensitiveWordBaseVO {
  16 +
  17 + @ApiModelProperty(value = "编号", required = true, example = "1")
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "创建时间", required = true)
  21 + private Date createTime;
  22 +
  23 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.constraints.NotNull;
  10 +
  11 +@ApiModel("管理后台 - 敏感词更新 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class SensitiveWordUpdateReqVO extends SensitiveWordBaseVO {
  16 +
  17 + @ApiModelProperty(value = "编号", required = true, example = "1")
  18 + @NotNull(message = "编号不能为空")
  19 + private Long id;
  20 +
  21 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/convert/logger/OperateLogConvert.java
... ... @@ -30,7 +30,7 @@ public interface OperateLogConvert {
30 30 default List<OperateLogExcelVO> convertList(List<OperateLogDO> list, Map<Long, AdminUserDO> userMap) {
31 31 return list.stream().map(operateLog -> {
32 32 OperateLogExcelVO excelVO = convert02(operateLog);
33   - MapUtils.findAndThen(userMap, operateLog.getId(), user -> excelVO.setUserNickname(user.getNickname()));
  33 + MapUtils.findAndThen(userMap, operateLog.getUserId(), user -> excelVO.setUserNickname(user.getNickname()));
34 34 excelVO.setSuccessStr(SUCCESS.getCode().equals(operateLog.getResultCode()) ? "成功" : "失败");
35 35 return excelVO;
36 36 }).collect(Collectors.toList());
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/convert/sensitiveword/SensitiveWordConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.convert.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordCreateReqVO;
  5 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExcelVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordRespVO;
  7 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordUpdateReqVO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  9 +import org.mapstruct.Mapper;
  10 +import org.mapstruct.factory.Mappers;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 敏感词 Convert
  16 + *
  17 + * @author 永不言败
  18 + */
  19 +@Mapper
  20 +public interface SensitiveWordConvert {
  21 +
  22 + SensitiveWordConvert INSTANCE = Mappers.getMapper(SensitiveWordConvert.class);
  23 +
  24 + SensitiveWordDO convert(SensitiveWordCreateReqVO bean);
  25 +
  26 + SensitiveWordDO convert(SensitiveWordUpdateReqVO bean);
  27 +
  28 + SensitiveWordRespVO convert(SensitiveWordDO bean);
  29 +
  30 + List<SensitiveWordRespVO> convertList(List<SensitiveWordDO> list);
  31 +
  32 + PageResult<SensitiveWordRespVO> convertPage(PageResult<SensitiveWordDO> page);
  33 +
  34 + List<SensitiveWordExcelVO> convertList02(List<SensitiveWordDO> list);
  35 +
  36 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/package-info.java deleted
1   -package cn.iocoder.yudao.module.system.dal.dataobject;
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sensitiveword/SensitiveWordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.framework.mybatis.core.type.StringLiSTTypeHandler;
  6 +import com.baomidou.mybatisplus.annotation.TableField;
  7 +import com.baomidou.mybatisplus.annotation.TableId;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 敏感词 DO
  15 + *
  16 + * @author 永不言败
  17 + */
  18 +@TableName(value = "system_sensitive_word", autoResultMap = true)
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class SensitiveWordDO extends BaseDO {
  26 +
  27 + /**
  28 + * 编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 敏感词
  34 + */
  35 + private String name;
  36 + /**
  37 + * 描述
  38 + */
  39 + private String description;
  40 + /**
  41 + * 标签数组
  42 + *
  43 + * 用于实现不同的业务场景下,需要使用不同标签的敏感词。
  44 + * 例如说,tag 有短信、论坛两种,敏感词 "推广" 在短信下是敏感词,在论坛下不是敏感词。
  45 + * 此时,我们会存储一条敏感词记录,它的 name 为"推广",tag 为短信。
  46 + */
  47 + @TableField(typeHandler = StringLiSTTypeHandler.class)
  48 + private List<String> tags;
  49 + /**
  50 + * 状态
  51 + *
  52 + * 枚举 {@link CommonStatusEnum}
  53 + */
  54 + private Integer status;
  55 +
  56 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java
... ... @@ -15,12 +15,14 @@ import java.util.List;
15 15 public interface DeptMapper extends BaseMapperX<DeptDO> {
16 16  
17 17 default List<DeptDO> selectList(DeptListReqVO reqVO) {
18   - return selectList(new LambdaQueryWrapperX<DeptDO>().likeIfPresent(DeptDO::getName, reqVO.getName())
  18 + return selectList(new LambdaQueryWrapperX<DeptDO>()
  19 + .likeIfPresent(DeptDO::getName, reqVO.getName())
19 20 .eqIfPresent(DeptDO::getStatus, reqVO.getStatus()));
20 21 }
21 22  
22 23 default DeptDO selectByParentIdAndName(Long parentId, String name) {
23   - return selectOne(new LambdaQueryWrapper<DeptDO>().eq(DeptDO::getParentId, parentId)
  24 + return selectOne(new LambdaQueryWrapper<DeptDO>()
  25 + .eq(DeptDO::getParentId, parentId)
24 26 .eq(DeptDO::getName, name));
25 27 }
26 28  
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuBatchInsertMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.mysql.permission;
  2 +
  3 +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
  4 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5 +import org.springframework.stereotype.Repository;
  6 +
  7 +/**
  8 + * 实体 {@link RoleMenuDO} 的批量插入 Mapper
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Repository
  13 +public class RoleMenuBatchInsertMapper extends ServiceImpl<RoleMenuMapper, RoleMenuDO> {
  14 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMenuMapper.java
... ... @@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.system.dal.mysql.permission;
3 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
5 5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
6 7 import org.apache.ibatis.annotations.Mapper;
7 8 import org.apache.ibatis.annotations.Select;
  9 +import org.springframework.stereotype.Repository;
8 10  
9 11 import java.util.Collection;
10 12 import java.util.Date;
... ... @@ -14,18 +16,12 @@ import java.util.stream.Collectors;
14 16 @Mapper
15 17 public interface RoleMenuMapper extends BaseMapperX<RoleMenuDO> {
16 18  
17   - default List<RoleMenuDO> selectListByRoleId(Long roleId) {
18   - return selectList(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
  19 + @Repository
  20 + class BatchInsertMapper extends ServiceImpl<RoleMenuMapper, RoleMenuDO> {
19 21 }
20 22  
21   - default void insertList(Long roleId, Collection<Long> menuIds) {
22   - List<RoleMenuDO> list = menuIds.stream().map(menuId -> {
23   - RoleMenuDO entity = new RoleMenuDO();
24   - entity.setRoleId(roleId);
25   - entity.setMenuId(menuId);
26   - return entity;
27   - }).collect(Collectors.toList());
28   - insertBatch(list);
  23 + default List<RoleMenuDO> selectListByRoleId(Long roleId) {
  24 + return selectList(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
29 25 }
30 26  
31 27 default void deleteListByRoleIdAndMenuIds(Long roleId, Collection<Long> menuIds) {
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleBatchInsertMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.mysql.permission;
  2 +
  3 +import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
  4 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5 +import org.springframework.stereotype.Repository;
  6 +
  7 +/**
  8 + * 实体 {@link UserRoleDO} 的批量插入 Mapper
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Repository
  13 +public class UserRoleBatchInsertMapper extends ServiceImpl<UserRoleMapper, UserRoleDO> {
  14 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java
... ... @@ -7,7 +7,6 @@ import org.apache.ibatis.annotations.Mapper;
7 7  
8 8 import java.util.Collection;
9 9 import java.util.List;
10   -import java.util.stream.Collectors;
11 10  
12 11 @Mapper
13 12 public interface UserRoleMapper extends BaseMapperX<UserRoleDO> {
... ... @@ -20,17 +19,6 @@ public interface UserRoleMapper extends BaseMapperX&lt;UserRoleDO&gt; {
20 19 return selectList(new QueryWrapper<UserRoleDO>().eq("role_id", roleId));
21 20 }
22 21  
23   -
24   - default void insertList(Long userId, Collection<Long> roleIds) {
25   - List<UserRoleDO> list = roleIds.stream().map(roleId -> {
26   - UserRoleDO entity = new UserRoleDO();
27   - entity.setUserId(userId);
28   - entity.setRoleId(roleId);
29   - return entity;
30   - }).collect(Collectors.toList());
31   - insertBatch(list);
32   - }
33   -
34 22 default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {
35 23 delete(new QueryWrapper<UserRoleDO>().eq("user_id", userId)
36 24 .in("role_id", roleIds));
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sensitiveword/SensitiveWordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.mysql.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExportReqVO;
  7 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +import org.apache.ibatis.annotations.Select;
  11 +
  12 +import java.util.Date;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 敏感词 Mapper
  17 + *
  18 + * @author 永不言败
  19 + */
  20 +@Mapper
  21 +public interface SensitiveWordMapper extends BaseMapperX<SensitiveWordDO> {
  22 +
  23 + default PageResult<SensitiveWordDO> selectPage(SensitiveWordPageReqVO reqVO) {
  24 + return selectPage(reqVO, new LambdaQueryWrapperX<SensitiveWordDO>()
  25 + .likeIfPresent(SensitiveWordDO::getName, reqVO.getName())
  26 + .likeIfPresent(SensitiveWordDO::getTags, reqVO.getTag())
  27 + .eqIfPresent(SensitiveWordDO::getStatus, reqVO.getStatus())
  28 + .betweenIfPresent(SensitiveWordDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  29 + .orderByDesc(SensitiveWordDO::getId));
  30 + }
  31 +
  32 + default List<SensitiveWordDO> selectList(SensitiveWordExportReqVO reqVO) {
  33 + return selectList(new LambdaQueryWrapperX<SensitiveWordDO>()
  34 + .likeIfPresent(SensitiveWordDO::getName, reqVO.getName())
  35 + .likeIfPresent(SensitiveWordDO::getTags, reqVO.getTag())
  36 + .eqIfPresent(SensitiveWordDO::getStatus, reqVO.getStatus())
  37 + .betweenIfPresent(SensitiveWordDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  38 + .orderByDesc(SensitiveWordDO::getId));
  39 + }
  40 +
  41 + default SensitiveWordDO selectByName(String name) {
  42 + return selectOne(SensitiveWordDO::getName, name);
  43 + }
  44 +
  45 + @Select("SELECT id FROM system_sensitive_word WHERE update_time > #{maxUpdateTime} LIMIT 1")
  46 + SensitiveWordDO selectExistsByUpdateTimeAfter(Date maxUpdateTime);
  47 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/redis/auth/LoginUserRedisDAO.java
... ... @@ -41,7 +41,7 @@ public class LoginUserRedisDAO {
41 41 }
42 42  
43 43 private static String formatKey(String sessionId) {
44   - return String.format(LOGIN_USER.getKeyTemplate(), sessionId);
  44 + return LOGIN_USER.formatKey(sessionId);
45 45 }
46 46  
47 47 }
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sensitiveword/SensitiveWordRefreshConsumer.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.mq.consumer.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
  4 +import cn.iocoder.yudao.module.system.mq.message.sensitiveword.SensitiveWordRefreshMessage;
  5 +import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +import javax.annotation.Resource;
  10 +
  11 +/**
  12 + * 针对 {@link SensitiveWordRefreshMessage} 的消费者
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Component
  17 +@Slf4j
  18 +public class SensitiveWordRefreshConsumer extends AbstractChannelMessageListener<SensitiveWordRefreshMessage> {
  19 +
  20 + @Resource
  21 + private SensitiveWordService sensitiveWordService;
  22 +
  23 + @Override
  24 + public void onMessage(SensitiveWordRefreshMessage message) {
  25 + log.info("[onMessage][收到 SensitiveWord 刷新消息]");
  26 + sensitiveWordService.initLocalCache();
  27 + }
  28 +
  29 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/message/sensitiveword/SensitiveWordRefreshMessage.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.mq.message.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +
  7 +/**
  8 + * 敏感词的刷新 Message
  9 + */
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +public class SensitiveWordRefreshMessage extends AbstractChannelMessage {
  13 +
  14 + @Override
  15 + public String getChannel() {
  16 + return "system.sensitive-word.refresh";
  17 + }
  18 +
  19 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sensitiveword/SensitiveWordProducer.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.mq.producer.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
  4 +import cn.iocoder.yudao.module.system.mq.message.sensitiveword.SensitiveWordRefreshMessage;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +import javax.annotation.Resource;
  8 +
  9 +/**
  10 + * 敏感词相关的 Producer
  11 + */
  12 +@Component
  13 +public class SensitiveWordProducer {
  14 +
  15 + @Resource
  16 + private RedisMQTemplate redisMQTemplate;
  17 +
  18 + /**
  19 + * 发送 {@link SensitiveWordRefreshMessage} 消息
  20 + */
  21 + public void sendSensitiveWordRefreshMessage() {
  22 + SensitiveWordRefreshMessage message = new SensitiveWordRefreshMessage();
  23 + redisMQTemplate.send(message);
  24 + }
  25 +
  26 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
... ... @@ -107,7 +107,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
107 107 LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
108 108  
109 109 // 缓存登陆用户到 Redis 中,返回 sessionId 编号
110   - return userSessionService.createUserSession(loginUser, userIp, userAgent);
  110 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
111 111 }
112 112  
113 113 private void verifyCaptcha(AuthLoginReqVO reqVO) {
... ... @@ -155,9 +155,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
155 155 this.createLoginLog(username, logTypeEnum, LoginResultEnum.UNKNOWN_ERROR);
156 156 throw exception(AUTH_LOGIN_FAIL_UNKNOWN);
157 157 }
158   - // 登录成功的日志
159 158 Assert.notNull(authentication.getPrincipal(), "Principal 不会为空");
160   - this.createLoginLog(username, logTypeEnum, LoginResultEnum.SUCCESS);
161 159 return (LoginUser) authentication.getPrincipal();
162 160 }
163 161  
... ... @@ -207,7 +205,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
207 205 if (user == null) {
208 206 throw exception(USER_NOT_EXISTS);
209 207 }
210   - this.createLoginLog(user.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL, LoginResultEnum.SUCCESS);
211 208  
212 209 // 创建 LoginUser 对象
213 210 LoginUser loginUser = this.buildLoginUser(user);
... ... @@ -216,7 +213,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
216 213 socialUserService.bindSocialUser(AuthConvert.INSTANCE.convert(loginUser.getId(), getUserType().getValue(), reqVO));
217 214  
218 215 // 缓存登录用户到 Redis 中,返回 sessionId 编号
219   - return userSessionService.createUserSession(loginUser, userIp, userAgent);
  216 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
220 217 }
221 218  
222 219 @Override
... ... @@ -232,6 +229,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
232 229 socialUserService.bindSocialUser(AuthConvert.INSTANCE.convert(loginUser.getId(), getUserType().getValue(), reqVO));
233 230  
234 231 // 缓存登录用户到 Redis 中,返回 sessionId 编号
  232 + return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
  233 + }
  234 +
  235 + private String createUserSessionAfterLoginSuccess(LoginUser loginUser, LoginLogTypeEnum logType, String userIp, String userAgent) {
  236 + // 插入登陆日志
  237 + createLoginLog(loginUser.getUsername(), logType, LoginResultEnum.SUCCESS);
  238 + // 缓存登录用户到 Redis 中,返回 sessionId 编号
235 239 return userSessionService.createUserSession(loginUser, userIp, userAgent);
236 240 }
237 241  
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
... ... @@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
8 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 9 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
10 10 import cn.iocoder.yudao.framework.security.core.LoginUser;
11   -import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
12 11 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
13 12 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
14 13 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
... ... @@ -16,8 +15,11 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
16 15 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
17 16 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
18 17 import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
  18 +import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuBatchInsertMapper;
19 19 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
  20 +import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleBatchInsertMapper;
20 21 import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
  22 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
21 23 import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
22 24 import cn.iocoder.yudao.module.system.service.dept.DeptService;
23 25 import com.google.common.collect.ImmutableMultimap;
... ... @@ -79,7 +81,11 @@ public class PermissionServiceImpl implements PermissionService {
79 81 @Resource
80 82 private RoleMenuMapper roleMenuMapper;
81 83 @Resource
  84 + private RoleMenuBatchInsertMapper roleMenuBatchInsertMapper;
  85 + @Resource
82 86 private UserRoleMapper userRoleMapper;
  87 + @Resource
  88 + private UserRoleBatchInsertMapper userRoleBatchInsertMapper;
83 89  
84 90 @Resource
85 91 private RoleService roleService;
... ... @@ -202,7 +208,12 @@ public class PermissionServiceImpl implements PermissionService {
202 208 Collection<Long> deleteMenuIds = CollUtil.subtract(dbMenuIds, menuIds);
203 209 // 执行新增和删除。对于已经授权的菜单,不用做任何处理
204 210 if (!CollectionUtil.isEmpty(createMenuIds)) {
205   - roleMenuMapper.insertList(roleId, createMenuIds);
  211 + roleMenuBatchInsertMapper.saveBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
  212 + RoleMenuDO entity = new RoleMenuDO();
  213 + entity.setRoleId(roleId);
  214 + entity.setMenuId(menuId);
  215 + return entity;
  216 + }));
206 217 }
207 218 if (!CollectionUtil.isEmpty(deleteMenuIds)) {
208 219 roleMenuMapper.deleteListByRoleIdAndMenuIds(roleId, deleteMenuIds);
... ... @@ -240,7 +251,12 @@ public class PermissionServiceImpl implements PermissionService {
240 251 Collection<Long> deleteMenuIds = CollUtil.subtract(dbRoleIds, roleIds);
241 252 // 执行新增和删除。对于已经授权的角色,不用做任何处理
242 253 if (!CollectionUtil.isEmpty(createRoleIds)) {
243   - userRoleMapper.insertList(userId, createRoleIds);
  254 + userRoleBatchInsertMapper.saveBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
  255 + UserRoleDO entity = new UserRoleDO();
  256 + entity.setUserId(userId);
  257 + entity.setRoleId(roleId);
  258 + return entity;
  259 + }));
244 260 }
245 261 if (!CollectionUtil.isEmpty(deleteMenuIds)) {
246 262 userRoleMapper.deleteListByUserIdAndRoleIdIds(userId, deleteMenuIds);
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
... ... @@ -126,6 +126,7 @@ public class RoleServiceImpl implements RoleService {
126 126 }
127 127  
128 128 @Override
  129 + @Transactional
129 130 public Long createRole(RoleCreateReqVO reqVO, Integer type) {
130 131 // 校验角色
131 132 checkDuplicateRole(reqVO.getName(), reqVO.getCode(), null);
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordCreateReqVO;
  5 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExportReqVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
  7 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordUpdateReqVO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  9 +
  10 +import javax.validation.Valid;
  11 +import java.util.List;
  12 +import java.util.Set;
  13 +
  14 +/**
  15 + * 敏感词 Service 接口
  16 + *
  17 + * @author 永不言败
  18 + */
  19 +public interface SensitiveWordService {
  20 +
  21 + /**
  22 + * 初始化本地缓存
  23 + */
  24 + void initLocalCache();
  25 +
  26 + /**
  27 + * 创建敏感词
  28 + *
  29 + * @param createReqVO 创建信息
  30 + * @return 编号
  31 + */
  32 + Long createSensitiveWord(@Valid SensitiveWordCreateReqVO createReqVO);
  33 +
  34 + /**
  35 + * 更新敏感词
  36 + *
  37 + * @param updateReqVO 更新信息
  38 + */
  39 + void updateSensitiveWord(@Valid SensitiveWordUpdateReqVO updateReqVO);
  40 +
  41 + /**
  42 + * 删除敏感词
  43 + *
  44 + * @param id 编号
  45 + */
  46 + void deleteSensitiveWord(Long id);
  47 +
  48 + /**
  49 + * 获得敏感词
  50 + *
  51 + * @param id 编号
  52 + * @return 敏感词
  53 + */
  54 + SensitiveWordDO getSensitiveWord(Long id);
  55 +
  56 + /**
  57 + * 获得敏感词列表
  58 + *
  59 + * @return 敏感词列表
  60 + */
  61 + List<SensitiveWordDO> getSensitiveWordList();
  62 +
  63 + /**
  64 + * 获得敏感词分页
  65 + *
  66 + * @param pageReqVO 分页查询
  67 + * @return 敏感词分页
  68 + */
  69 + PageResult<SensitiveWordDO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO);
  70 +
  71 + /**
  72 + * 获得敏感词列表, 用于 Excel 导出
  73 + *
  74 + * @param exportReqVO 查询条件
  75 + * @return 敏感词列表
  76 + */
  77 + List<SensitiveWordDO> getSensitiveWordList(SensitiveWordExportReqVO exportReqVO);
  78 +
  79 + /**
  80 + * 获得所有敏感词的标签数组
  81 + *
  82 + * @return 标签数组
  83 + */
  84 + Set<String> getSensitiveWordTags();
  85 +
  86 + /**
  87 + * 获得文本所包含的不合法的敏感词数组
  88 + *
  89 + * @param text 文本
  90 + * @param tags 标签数组
  91 + * @return 不合法的敏感词数组
  92 + */
  93 + List<String> validateText(String text, List<String> tags);
  94 +
  95 + /**
  96 + * 判断文本是否包含敏感词
  97 + *
  98 + * @param text 文本
  99 + * @param tags 表述数组
  100 + * @return 是否包含
  101 + */
  102 + boolean isTextValid(String text, List<String> tags);
  103 +
  104 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.sensitiveword;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordCreateReqVO;
  8 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExportReqVO;
  9 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
  10 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordUpdateReqVO;
  11 +import cn.iocoder.yudao.module.system.convert.sensitiveword.SensitiveWordConvert;
  12 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  13 +import cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper;
  14 +import cn.iocoder.yudao.module.system.mq.producer.sensitiveword.SensitiveWordProducer;
  15 +import cn.iocoder.yudao.module.system.util.collection.SimpleTrie;
  16 +import com.google.common.collect.HashMultimap;
  17 +import com.google.common.collect.Multimap;
  18 +import lombok.Getter;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.scheduling.annotation.Scheduled;
  21 +import org.springframework.stereotype.Service;
  22 +import org.springframework.validation.annotation.Validated;
  23 +
  24 +import javax.annotation.PostConstruct;
  25 +import javax.annotation.Resource;
  26 +import java.util.*;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  29 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_EXISTS;
  30 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS;
  31 +
  32 +/**
  33 + * 敏感词 Service 实现类
  34 + *
  35 + * @author 永不言败
  36 + */
  37 +@Service
  38 +@Slf4j
  39 +@Validated
  40 +public class SensitiveWordServiceImpl implements SensitiveWordService {
  41 +
  42 + /**
  43 + * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
  44 + * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
  45 + */
  46 + private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
  47 +
  48 + /**
  49 + * 敏感词标签缓存
  50 + * key:敏感词编号 {@link SensitiveWordDO#getId()}
  51 + * <p>
  52 + * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
  53 + */
  54 + @Getter
  55 + private volatile Set<String> sensitiveWordTagsCache = Collections.emptySet();
  56 +
  57 + /**
  58 + * 缓存敏感词的最大更新时间,用于后续的增量轮询,判断是否有更新
  59 + */
  60 + @Getter
  61 + private volatile Date maxUpdateTime;
  62 +
  63 + @Resource
  64 + private SensitiveWordMapper sensitiveWordMapper;
  65 +
  66 + @Resource
  67 + private SensitiveWordProducer sensitiveWordProducer;
  68 +
  69 + /**
  70 + * 默认的敏感词的字典树,包含所有敏感词
  71 + */
  72 + @Getter
  73 + private volatile SimpleTrie defaultSensitiveWordTrie = new SimpleTrie(Collections.emptySet());
  74 + /**
  75 + * 标签与敏感词的字段数的映射
  76 + */
  77 + @Getter
  78 + private volatile Map<String, SimpleTrie> tagSensitiveWordTries = Collections.emptyMap();
  79 +
  80 + /**
  81 + * 初始化缓存
  82 + */
  83 + @Override
  84 + @PostConstruct
  85 + public void initLocalCache() {
  86 + // 获取敏感词列表,如果有更新
  87 + List<SensitiveWordDO> sensitiveWordList = loadSensitiveWordIfUpdate(maxUpdateTime);
  88 + if (CollUtil.isEmpty(sensitiveWordList)) {
  89 + return;
  90 + }
  91 +
  92 + // 写入 sensitiveWordTagsCache 缓存
  93 + Set<String> tags = new HashSet<>();
  94 + sensitiveWordList.forEach(word -> tags.addAll(word.getTags()));
  95 + sensitiveWordTagsCache = tags;
  96 + // 写入 defaultSensitiveWordTrie、tagSensitiveWordTries 缓存
  97 + initSensitiveWordTrie(sensitiveWordList);
  98 + // 写入 maxUpdateTime 最大更新时间
  99 + maxUpdateTime = CollectionUtils.getMaxValue(sensitiveWordList, SensitiveWordDO::getUpdateTime);
  100 + log.info("[initLocalCache][初始化 敏感词 数量为 {}]", sensitiveWordList.size());
  101 + }
  102 +
  103 + private void initSensitiveWordTrie(List<SensitiveWordDO> wordDOs) {
  104 + // 过滤禁用的敏感词
  105 + wordDOs = CollectionUtils.filterList(wordDOs, word -> word.getStatus().equals(CommonStatusEnum.ENABLE.getStatus()));
  106 +
  107 + // 初始化默认的 defaultSensitiveWordTrie
  108 + this.defaultSensitiveWordTrie = new SimpleTrie(CollectionUtils.convertList(wordDOs, SensitiveWordDO::getName));
  109 +
  110 + // 初始化 tagSensitiveWordTries
  111 + Multimap<String, String> tagWords = HashMultimap.create();
  112 + for (SensitiveWordDO word : wordDOs) {
  113 + if (CollUtil.isEmpty(word.getTags())) {
  114 + continue;
  115 + }
  116 + word.getTags().forEach(tag -> tagWords.put(tag, word.getName()));
  117 + }
  118 + // 添加到 tagSensitiveWordTries 中
  119 + Map<String, SimpleTrie> tagSensitiveWordTries = new HashMap<>();
  120 + tagWords.asMap().forEach((tag, words) -> tagSensitiveWordTries.put(tag, new SimpleTrie(words)));
  121 + this.tagSensitiveWordTries = tagSensitiveWordTries;
  122 + }
  123 +
  124 + @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
  125 + public void schedulePeriodicRefresh() {
  126 + initLocalCache();
  127 + }
  128 +
  129 + /**
  130 + * 如果敏感词发生变化,从数据库中获取最新的全量敏感词。
  131 + * 如果未发生变化,则返回空
  132 + *
  133 + * @param maxUpdateTime 当前敏感词的最大更新时间
  134 + * @return 敏感词列表
  135 + */
  136 + private List<SensitiveWordDO> loadSensitiveWordIfUpdate(Date maxUpdateTime) {
  137 + // 第一步,判断是否要更新。
  138 + // 如果更新时间为空,说明 DB 一定有新数据
  139 + if (maxUpdateTime == null) {
  140 + log.info("[loadSensitiveWordIfUpdate][首次加载全量敏感词]");
  141 + } else { // 判断数据库中是否有更新的敏感词
  142 + if (sensitiveWordMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
  143 + return null;
  144 + }
  145 + log.info("[loadSensitiveWordIfUpdate][增量加载全量敏感词]");
  146 + }
  147 + // 第二步,如果有更新,则从数据库加载所有敏感词
  148 + return sensitiveWordMapper.selectList();
  149 + }
  150 +
  151 + @Override
  152 + public Long createSensitiveWord(SensitiveWordCreateReqVO createReqVO) {
  153 + // 校验唯一性
  154 + checkSensitiveWordNameUnique(null, createReqVO.getName());
  155 + // 插入
  156 + SensitiveWordDO sensitiveWord = SensitiveWordConvert.INSTANCE.convert(createReqVO);
  157 + sensitiveWordMapper.insert(sensitiveWord);
  158 + // 发送消息,刷新缓存
  159 + sensitiveWordProducer.sendSensitiveWordRefreshMessage();
  160 + return sensitiveWord.getId();
  161 + }
  162 +
  163 + @Override
  164 + public void updateSensitiveWord(SensitiveWordUpdateReqVO updateReqVO) {
  165 + // 校验唯一性
  166 + checkSensitiveWordExists(updateReqVO.getId());
  167 + checkSensitiveWordNameUnique(updateReqVO.getId(), updateReqVO.getName());
  168 + // 更新
  169 + SensitiveWordDO updateObj = SensitiveWordConvert.INSTANCE.convert(updateReqVO);
  170 + sensitiveWordMapper.updateById(updateObj);
  171 + // 发送消息,刷新缓存
  172 + sensitiveWordProducer.sendSensitiveWordRefreshMessage();
  173 + }
  174 +
  175 + @Override
  176 + public void deleteSensitiveWord(Long id) {
  177 + // 校验存在
  178 + checkSensitiveWordExists(id);
  179 + // 删除
  180 + sensitiveWordMapper.deleteById(id);
  181 + // 发送消息,刷新缓存
  182 + sensitiveWordProducer.sendSensitiveWordRefreshMessage();
  183 + }
  184 +
  185 + private void checkSensitiveWordNameUnique(Long id, String name) {
  186 + SensitiveWordDO word = sensitiveWordMapper.selectByName(name);
  187 + if (word == null) {
  188 + return;
  189 + }
  190 + // 如果 id 为空,说明不用比较是否为相同 id 的敏感词
  191 + if (id == null) {
  192 + throw exception(SENSITIVE_WORD_EXISTS);
  193 + }
  194 + if (!word.getId().equals(id)) {
  195 + throw exception(SENSITIVE_WORD_EXISTS);
  196 + }
  197 + }
  198 +
  199 + private void checkSensitiveWordExists(Long id) {
  200 + if (sensitiveWordMapper.selectById(id) == null) {
  201 + throw exception(SENSITIVE_WORD_NOT_EXISTS);
  202 + }
  203 + }
  204 +
  205 + @Override
  206 + public SensitiveWordDO getSensitiveWord(Long id) {
  207 + return sensitiveWordMapper.selectById(id);
  208 + }
  209 +
  210 + @Override
  211 + public List<SensitiveWordDO> getSensitiveWordList() {
  212 + return sensitiveWordMapper.selectList();
  213 + }
  214 +
  215 + @Override
  216 + public PageResult<SensitiveWordDO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO) {
  217 + return sensitiveWordMapper.selectPage(pageReqVO);
  218 + }
  219 +
  220 + @Override
  221 + public List<SensitiveWordDO> getSensitiveWordList(SensitiveWordExportReqVO exportReqVO) {
  222 + return sensitiveWordMapper.selectList(exportReqVO);
  223 + }
  224 +
  225 + @Override
  226 + public Set<String> getSensitiveWordTags() {
  227 + return sensitiveWordTagsCache;
  228 + }
  229 +
  230 + @Override
  231 + public List<String> validateText(String text, List<String> tags) {
  232 + if (CollUtil.isEmpty(tags)) {
  233 + return defaultSensitiveWordTrie.validate(text);
  234 + }
  235 + // 有标签的情况
  236 + Set<String> result = new HashSet<>();
  237 + tags.forEach(tag -> {
  238 + SimpleTrie trie = tagSensitiveWordTries.get(tag);
  239 + if (trie == null) {
  240 + return;
  241 + }
  242 + result.addAll(trie.validate(text));
  243 + });
  244 + return new ArrayList<>(result);
  245 + }
  246 +
  247 + @Override
  248 + public boolean isTextValid(String text, List<String> tags) {
  249 + if (CollUtil.isEmpty(tags)) {
  250 + return defaultSensitiveWordTrie.isValid(text);
  251 + }
  252 + // 有标签的情况
  253 + for (String tag : tags) {
  254 + SimpleTrie trie = tagSensitiveWordTries.get(tag);
  255 + if (trie == null) {
  256 + continue;
  257 + }
  258 + if (!trie.isValid(text)) {
  259 + return false;
  260 + }
  261 + }
  262 + return true;
  263 + }
  264 +
  265 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.util.collection;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +
  5 +import java.util.*;
  6 +
  7 +/**
  8 + * 基于前缀树,实现敏感词的校验
  9 + * <p>
  10 + * 相比 Apache Common 提供的 PatriciaTrie 来说,性能可能会更加好一些。
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@SuppressWarnings("unchecked")
  15 +public class SimpleTrie {
  16 +
  17 + /**
  18 + * 一个敏感词结束后对应的 key
  19 + */
  20 + private static final Character CHARACTER_END = '\0';
  21 +
  22 + /**
  23 + * 使用敏感词,构建的前缀树
  24 + */
  25 + private final Map<Character, Object> children;
  26 +
  27 + /**
  28 + * 基于字符串,构建前缀树
  29 + *
  30 + * @param strs 字符串数组
  31 + */
  32 + public SimpleTrie(Collection<String> strs) {
  33 + children = new HashMap<>();
  34 + // 构建树
  35 + CollUtil.sort(strs, String::compareTo); // 排序,优先使用较短的前缀
  36 + for (String str : strs) {
  37 + Map<Character, Object> child = children;
  38 + // 遍历每个字符
  39 + for (Character c : str.toCharArray()) {
  40 + // 如果已经到达结束,就没必要在添加更长的敏感词。
  41 + // 例如说,有两个敏感词是:吃饭啊、吃饭。输入一句话是 “我要吃饭啊”,则只要匹配到 “吃饭” 这个敏感词即可。
  42 + if (child.containsKey(CHARACTER_END)) {
  43 + break;
  44 + }
  45 + if (!child.containsKey(c)) {
  46 + child.put(c, new HashMap<>());
  47 + }
  48 + child = (Map<Character, Object>) child.get(c);
  49 + }
  50 + // 结束
  51 + child.put(CHARACTER_END, null);
  52 + }
  53 + }
  54 +
  55 + /**
  56 + * 验证文本是否合法,即不包含敏感词
  57 + *
  58 + * @param text 文本
  59 + * @return 是否 ok
  60 + */
  61 + public boolean isValid(String text) {
  62 + // 遍历 text,使用每一个 [i, n) 段的字符串,使用 children 前缀树匹配,是否包含敏感词
  63 + for (int i = 0; i < text.length() - 1; i++) {
  64 + Map<Character, Object> child = (Map<Character, Object>) children.get(text.charAt(i));
  65 + if (child == null) {
  66 + continue;
  67 + }
  68 + boolean ok = recursion(text, i + 1, child);
  69 + if (!ok) {
  70 + return false;
  71 + }
  72 + }
  73 + return true;
  74 + }
  75 +
  76 + /**
  77 + * 验证文本从指定位置开始,是否包含某个敏感词
  78 + *
  79 + * @param text 文本
  80 + * @param index 开始位置
  81 + * @param child 节点(当前遍历到的)
  82 + * @return 是否包含
  83 + */
  84 + private boolean recursion(String text, int index, Map<Character, Object> child) {
  85 + if (index == text.length()) {
  86 + return true;
  87 + }
  88 + child = (Map<Character, Object>) child.get(text.charAt(index));
  89 + return child == null || !child.containsKey(CHARACTER_END) && recursion(text, ++index, child);
  90 + }
  91 +
  92 + /**
  93 + * 获得文本所包含的不合法的敏感词
  94 + *
  95 + * 注意,才当即最短匹配原则。例如说:当敏感词存在 “煞笔”,“煞笔二货 ”时,只会返回 “煞笔”。
  96 + *
  97 + * @param text 文本
  98 + * @return 匹配的敏感词
  99 + */
  100 + public List<String> validate(String text) {
  101 + Set<String> results = new HashSet<>();
  102 + for (int i = 0; i < text.length() - 1; i++) {
  103 + Character c = text.charAt(i);
  104 + Map<Character, Object> child = (Map<Character, Object>) children.get(c);
  105 + if (child == null) {
  106 + continue;
  107 + }
  108 + StringBuilder result = new StringBuilder().append(c);
  109 + boolean ok = recursionWithResult(text, i + 1, child, result);
  110 + if (!ok) {
  111 + results.add(result.toString());
  112 + }
  113 + }
  114 + return new ArrayList<>(results);
  115 + }
  116 +
  117 + /**
  118 + * 返回文本从 index 开始的敏感词,并使用 StringBuilder 参数进行返回
  119 + *
  120 + * 逻辑和 {@link #recursion(String, int, Map)} 是一致,只是多了 result 返回结果
  121 + *
  122 + * @param text 文本
  123 + * @param index 开始未知
  124 + * @param child 节点(当前遍历到的)
  125 + * @param result 返回敏感词
  126 + * @return 是否有敏感词
  127 + */
  128 + @SuppressWarnings("unchecked")
  129 + private static boolean recursionWithResult(String text, int index, Map<Character, Object> child, StringBuilder result) {
  130 + if (index == text.length()) {
  131 + return true;
  132 + }
  133 + Character c = text.charAt(index);
  134 + child = (Map<Character, Object>) child.get(c);
  135 + if (child == null) {
  136 + return true;
  137 + }
  138 + if (child.containsKey(CHARACTER_END)) {
  139 + result.append(c);
  140 + return false;
  141 + }
  142 + return recursionWithResult(text, ++index, child, result.append(c));
  143 + }
  144 +
  145 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/util/package-info.java 0 → 100644
  1 +/**
  2 + * 每个模块的 util 包,放专属当前模块的 Utils 工具类
  3 + */
  4 +package cn.iocoder.yudao.module.system.util;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
... ... @@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.system.service.social.SocialUserService;
13 13 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
14 14 import cn.iocoder.yudao.framework.security.core.LoginUser;
15 15 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
16   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  16 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
17 17 import org.junit.jupiter.api.BeforeEach;
18 18 import org.junit.jupiter.api.Test;
19 19 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImplTest.java
... ... @@ -15,7 +15,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
15 15 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
16 16 import cn.iocoder.yudao.framework.common.pojo.PageResult;
17 17 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
18   -import cn.iocoder.yudao.module.system.test.BaseDbAndRedisUnitTest;
  18 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
19 19 import org.junit.jupiter.api.Test;
20 20 import org.springframework.boot.test.mock.mockito.MockBean;
21 21 import org.springframework.context.annotation.Import;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/common/CaptchaServiceTest.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.service.common;
3 3 import cn.iocoder.yudao.module.system.controller.admin.common.vo.CaptchaImageRespVO;
4 4 import cn.iocoder.yudao.module.system.dal.redis.common.CaptchaRedisDAO;
5 5 import cn.iocoder.yudao.module.system.framework.captcha.config.CaptchaProperties;
6   -import cn.iocoder.yudao.module.system.test.BaseRedisUnitTest;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseRedisUnitTest;
7 7 import org.junit.jupiter.api.Test;
8 8 import org.springframework.context.annotation.Import;
9 9  
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java
... ... @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
10 10 import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
11 11 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
12 12 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
13   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  13 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
14 14 import com.google.common.collect.Multimap;
15 15 import org.junit.jupiter.api.Test;
16 16 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceTest.java
... ... @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostExportRe
10 10 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO;
11 11 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostUpdateReqVO;
12 12 import cn.iocoder.yudao.module.system.dal.mysql.dept.PostMapper;
13   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  13 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
14 14 import org.junit.jupiter.api.Test;
15 15 import org.springframework.context.annotation.Import;
16 16  
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java
... ... @@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
12 12 import cn.iocoder.yudao.module.system.mq.producer.dict.DictDataProducer;
13 13 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
14 14 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
15   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  15 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
16 16 import com.google.common.collect.ImmutableTable;
17 17 import org.junit.jupiter.api.Test;
18 18 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceTest.java
... ... @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
10 10 import cn.iocoder.yudao.module.system.dal.mysql.dict.DictTypeMapper;
11 11 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
12 12 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
13   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  13 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
14 14 import org.junit.jupiter.api.Test;
15 15 import org.springframework.boot.test.mock.mockito.MockBean;
16 16 import org.springframework.context.annotation.Import;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java
... ... @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.errorcode.ErrorCodeMapper;
11 11 import cn.iocoder.yudao.module.system.enums.errorcode.ErrorCodeTypeEnum;
12 12 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
13 13 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
14   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  14 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
15 15 import org.assertj.core.util.Lists;
16 16 import org.junit.jupiter.api.Test;
17 17 import org.springframework.context.annotation.Import;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/logger/LoginLogServiceImplTest.java
... ... @@ -13,7 +13,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
13 13 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
14 14 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
15 15 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
16   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  16 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
17 17 import org.junit.jupiter.api.Test;
18 18 import org.springframework.context.annotation.Import;
19 19  
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java
... ... @@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
17 17 import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper;
18 18 import cn.iocoder.yudao.module.system.enums.common.SexEnum;
19 19 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
20   -import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
  20 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
21 21 import org.junit.jupiter.api.Test;
22 22 import org.springframework.boot.test.mock.mockito.MockBean;
23 23 import org.springframework.context.annotation.Import;
... ...