diff --git a/pom.xml b/pom.xml index c3929d0..454470f 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,11 @@ + + + org.springframework.boot + spring-boot-starter-aop + org.springframework.boot spring-boot-starter-data-redis diff --git a/src/main/java/com/zsc/edu/gateway/common/util/TreeUtil.java b/src/main/java/com/zsc/edu/gateway/common/util/TreeUtil.java index 312f984..7bb1ba1 100644 --- a/src/main/java/com/zsc/edu/gateway/common/util/TreeUtil.java +++ b/src/main/java/com/zsc/edu/gateway/common/util/TreeUtil.java @@ -31,7 +31,7 @@ public class TreeUtil { } /** - * 将树打平成tree + * 将树打平成list * * @param tree 需要打平的树 * @param getSubChildren 设置下级数据方法,如:Menu::getSubMenus,x->x.setSubMenus(null) @@ -125,6 +125,9 @@ public class TreeUtil { } private static List makeChildren(E parent, List allData, BiFunction parentCheck, BiConsumer> children) { - return allData.stream().filter(x -> parentCheck.apply(parent, x)).peek(x -> children.accept(x, makeChildren(x, allData, parentCheck, children))).collect(Collectors.toList()); + return allData.stream() + .filter(x -> parentCheck.apply(parent, x)) + .peek(x -> children.accept(x, makeChildren(x, allData, parentCheck, children))) + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/zsc/edu/gateway/framework/jackson/JacksonConfig.java b/src/main/java/com/zsc/edu/gateway/framework/jackson/JacksonConfig.java deleted file mode 100644 index e216f8b..0000000 --- a/src/main/java/com/zsc/edu/gateway/framework/jackson/JacksonConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.zsc.edu.gateway.framework.jackson; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; - -import java.text.SimpleDateFormat; - -@Configuration -public class JacksonConfig { - - - @Bean - public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { - return builder -> builder.serializationInclusion(JsonInclude.Include.NON_NULL) - .serializationInclusion(JsonInclude.Include.NON_EMPTY); - } -} diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermission.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermission.java new file mode 100644 index 0000000..f5b42cb --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermission.java @@ -0,0 +1,22 @@ +package com.zsc.edu.gateway.framework.mybatisplus; + +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataPermission { + /** + * 目标表的别名 + */ + String tableAlias() default ""; + /** + * 部门表的别名 + */ + String deptAlias() default "dept_id"; + + /** + * 用户表的别名 + */ + String userAlias() default "create_id"; +} diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermissionContext.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermissionContext.java new file mode 100644 index 0000000..9531671 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataPermissionContext.java @@ -0,0 +1,18 @@ +package com.zsc.edu.gateway.framework.mybatisplus; + +public class DataPermissionContext { + + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static void set(DataPermission dataPermission) { + contextHolder.set(dataPermission); + } + + public static DataPermission get() { + return contextHolder.get(); + } + + public static void clear() { + contextHolder.remove(); + } +} diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeAspect.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeAspect.java new file mode 100644 index 0000000..275f43a --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeAspect.java @@ -0,0 +1,44 @@ +package com.zsc.edu.gateway.framework.mybatisplus; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +/** + * 数据权限注解切面 + */ +@Aspect +@Component +public class DataScopeAspect { + + /** + * 环绕通知,拦截带有 @DataPermission 注解的方法 + * @param joinPoint + * @throws Throwable + */ + @Around("@annotation(DataPermission)()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + // 获取方法上的 @DataPermission 注解 + DataPermission dataPermission = method.getAnnotation(DataPermission.class); + + if (dataPermission != null) { + // 将注解信息存储在上下文中,供 MyBatis 拦截器使用 + DataPermissionContext.set(dataPermission); + } + + try { + // 执行目标方法 + return joinPoint.proceed(); + } finally { + // 方法执行完毕,清除数据权限上下文,避免内存泄露 + DataPermissionContext.clear(); + } + } +} diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeHandler.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeHandler.java new file mode 100644 index 0000000..67adb71 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeHandler.java @@ -0,0 +1,130 @@ +package com.zsc.edu.gateway.framework.mybatisplus; + +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; +import com.zsc.edu.gateway.framework.security.SecurityUtil; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.Parenthesis; +import net.sf.jsqlparser.expression.operators.relational.EqualsTo; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.InExpression; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; + +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 数据权限拼装逻辑处理 + * + */ +@Slf4j +public class DataScopeHandler implements MultiDataPermissionHandler { + + /** + * 获取数据权限 SQL 片段。 + *

{@link MultiDataPermissionHandler#getSqlSegment(Table, Expression, String)} 方法不能覆盖原有的 where 数据,如果 return 了 null 则表示不追加任何 where 条件

+ * + * @param table 所执行的数据库表信息,可以通过此参数获取表名和表别名 + * @param where 原有的 where 条件信息 + * @param mappedStatementId Mybatis MappedStatementId 根据该参数可以判断具体执行方法 + * @return JSqlParser 条件表达式,返回的条件表达式会拼接在原有的表达式后面(不会覆盖原有的表达式) + */ + @Override + public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { +// try { + // 获取当前线程中的数据权限信息 + DataPermission dataPermission = DataPermissionContext.get(); + if (Objects.isNull(dataPermission)) { + return null; + } + return buildDataScopeByAnnotation(dataPermission); + + } + /** + * DataScope注解方式,拼装数据权限 + * @param dataScope + * @return + */ + private Expression buildDataScopeByAnnotation(DataPermission dataScope) { + UserDetailsImpl userInfo = SecurityUtil.getUserInfo(); + if (userInfo == null) { + return null; + } + Set dataScopeDeptIds = userInfo.getDataScopeDeptIds(); + DataScopeType dataScopeType = userInfo.getRole().getDataScope(); + // 本人ID + Long dataScopeCreateId = userInfo.getId(); + // 本人部门ID + Long deptId = userInfo.getDept().getId(); + // 表别名 + String tableAlias = dataScope.tableAlias(); + // 部门限制范围的字段名称 + String deptAlias = dataScope.deptAlias(); + // 本人限制范围的字段名称 + String userAlias = dataScope.userAlias(); + + // 拼装数据权限 + return switch (dataScopeType) { + // 全部数据权限 + case DATA_SCOPE_ALL -> null; + // 本部门数据权限, 构建部门eq表达式 + case DATA_SCOPE_DEPT -> equalsTo(tableAlias, deptAlias, deptId); + // 本部门及以下数据权限,构建部门in表达式 + case DATA_SCOPE_DEPT_AND_CHILD -> inExpression(tableAlias, deptAlias, dataScopeDeptIds); + // 本人数据权限,构建本人eq表达式 + case DATA_SCOPE_SELF -> equalsTo(tableAlias, userAlias, dataScopeCreateId); + }; + } + + /** + * 构建eq表达式 + * @param tableAlias 表别名 + * @param itemAlias 字段别名 + * @param itemId id + * @return + */ + private EqualsTo equalsTo(String tableAlias, String itemAlias, Long itemId) { + if (Objects.nonNull(itemId)) { + EqualsTo equalsTo = new EqualsTo(); + equalsTo.withLeftExpression(buildColumn(tableAlias, itemAlias)); + equalsTo.setRightExpression(new LongValue(itemId)); + return equalsTo; + } else { + return null; + } + } + + private InExpression inExpression(String tableAlias, String itemAlias, Set itemIds) { + if (!itemIds.isEmpty()) { + InExpression deptIdInExpression = new InExpression(); + ParenthesedExpressionList deptIds = new ParenthesedExpressionList<>(itemIds.stream().map(LongValue::new).collect(Collectors.toList())); + deptIdInExpression.withLeftExpression(buildColumn(tableAlias, itemAlias)); + deptIdInExpression.setRightExpression(deptIds); + return deptIdInExpression; + } else { + return null; + } + } + + + /** + * 构建Column + * + * @param tableAlias 表别名 + * @param columnName 字段名称 + * @return 带表别名字段 + */ + public static Column buildColumn(String tableAlias, String columnName) { + if (StringUtils.isNotEmpty(tableAlias)) { + columnName = tableAlias + "." + columnName; + } + return new Column(columnName); + } +} \ No newline at end of file diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeType.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeType.java new file mode 100644 index 0000000..6673eed --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/DataScopeType.java @@ -0,0 +1,36 @@ +package com.zsc.edu.gateway.framework.mybatisplus; + +import com.baomidou.mybatisplus.annotation.IEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum DataScopeType implements IEnum { + /** + * 全部数据权限 + */ + DATA_SCOPE_ALL(1), + /** + * 部门数据权限 + */ + DATA_SCOPE_DEPT(2), + /** + * 部门及以下数据权限 + */ + DATA_SCOPE_DEPT_AND_CHILD(3), + /** + * 仅个人数据权限 + */ + DATA_SCOPE_SELF(4); + /** + * 自定义数据权限 + */ +// DATA_SCOPE_CUSTOM(5); + + private final int value; + + @Override + public Integer getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MybatisPlusConfig.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MybatisPlusConfig.java index 42fc7db..2d9898d 100644 --- a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MybatisPlusConfig.java +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MybatisPlusConfig.java @@ -2,7 +2,9 @@ package com.zsc.edu.gateway.framework.mybatisplus; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.apache.ibatis.plugin.Interceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -13,18 +15,15 @@ import org.springframework.context.annotation.Configuration; @MapperScan(basePackages = "com.zsc.edu.gateway.modules.**.repo") @Configuration public class MybatisPlusConfig { - @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 添加数据权限插件 + DataPermissionInterceptor dataPermissionInterceptor = new DataPermissionInterceptor(new DataScopeHandler()); + // 添加自定义的数据权限处理器 + interceptor.addInnerInterceptor(dataPermissionInterceptor); + // 添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL)); -// // 添加数据权限插件 -// MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor(); -// // 添加自定义的数据权限处理器 -// dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler()); -// interceptor.addInnerInterceptor(dataPermissionInterceptor); return interceptor; } - - } diff --git a/src/main/java/com/zsc/edu/gateway/framework/security/JpaUserDetailsServiceImpl.java b/src/main/java/com/zsc/edu/gateway/framework/security/JpaUserDetailsServiceImpl.java index 6331ec7..6294330 100644 --- a/src/main/java/com/zsc/edu/gateway/framework/security/JpaUserDetailsServiceImpl.java +++ b/src/main/java/com/zsc/edu/gateway/framework/security/JpaUserDetailsServiceImpl.java @@ -1,6 +1,8 @@ package com.zsc.edu.gateway.framework.security; +import com.zsc.edu.gateway.common.util.TreeUtil; import com.zsc.edu.gateway.exception.StateException; +import com.zsc.edu.gateway.modules.system.entity.Dept; import com.zsc.edu.gateway.modules.system.entity.Menu; import com.zsc.edu.gateway.modules.system.entity.RoleAuthority; import com.zsc.edu.gateway.modules.system.entity.User; @@ -8,6 +10,7 @@ import com.zsc.edu.gateway.modules.system.repo.AuthorityRepository; import com.zsc.edu.gateway.modules.system.repo.MenuRepository; import com.zsc.edu.gateway.modules.system.repo.RoleAuthoritiesRepository; import com.zsc.edu.gateway.modules.system.repo.UserRepository; +import com.zsc.edu.gateway.modules.system.service.DeptService; import lombok.AllArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -27,9 +30,9 @@ import java.util.stream.Collectors; public class JpaUserDetailsServiceImpl implements UserDetailsService { private final UserRepository userRepo; -// private final RoleAuthoritiesRepository roleAuthoritiesRepository; private final AuthorityRepository authorityRepository; private final MenuRepository menuRepository; + private final DeptService deptService; @Override @Transactional(rollbackFor = Exception.class) @@ -38,7 +41,10 @@ public class JpaUserDetailsServiceImpl implements UserDetailsService { if (!user.getEnableState()) { throw new StateException("用户 '" + username + "' 已被禁用!请联系管理员"); } - + List depts = deptService.listTree(user.deptId); + List flat = TreeUtil.flat(depts, Dept::getChildren, d -> d.setChildren(null)); + Set dataScopeDeptIds = flat.stream().map(Dept::getId).collect(Collectors.toSet()); + user.setDataScopeDeptIds(dataScopeDeptIds); // List roleAuthorities= roleAuthoritiesRepository.selectByRoleId(user.getRoleId()); // user.role.authorities = authorityRepository.selectAuthoritiesByRoleId(user.getRoleId()); List menus = menuRepository.selectByRoleId(user.getRoleId()); diff --git a/src/main/java/com/zsc/edu/gateway/framework/security/UserDetailsImpl.java b/src/main/java/com/zsc/edu/gateway/framework/security/UserDetailsImpl.java index 2d0be83..de286aa 100644 --- a/src/main/java/com/zsc/edu/gateway/framework/security/UserDetailsImpl.java +++ b/src/main/java/com/zsc/edu/gateway/framework/security/UserDetailsImpl.java @@ -34,14 +34,16 @@ public class UserDetailsImpl implements UserDetails { public Role role; public Set authorities; public Set permissions; + public Set dataScopeDeptIds; - public UserDetailsImpl(Long id, String username, String password, String name, Boolean enableState, Dept dept, Role role, Set authorities, Set permissions) { + public UserDetailsImpl(Long id, String username, String password, String name, Boolean enableState, Dept dept, Set dataScopeDeptIds, Role role, Set authorities, Set permissions) { this.id = id; this.username = username; this.password = password; this.enableState = enableState; this.name = name; this.dept = dept; + this.dataScopeDeptIds = dataScopeDeptIds; this.role = role; this.authorities = authorities; this.permissions = permissions; @@ -55,6 +57,7 @@ public class UserDetailsImpl implements UserDetails { user.name, user.enableState, user.dept, + user.dataScopeDeptIds, user.role, user.role.authorities, permissions diff --git a/src/main/java/com/zsc/edu/gateway/modules/iot/product/controller/ProductController.java b/src/main/java/com/zsc/edu/gateway/modules/iot/product/controller/ProductController.java index 1321243..6e1b098 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/iot/product/controller/ProductController.java +++ b/src/main/java/com/zsc/edu/gateway/modules/iot/product/controller/ProductController.java @@ -2,6 +2,7 @@ package com.zsc.edu.gateway.modules.iot.product.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zsc.edu.gateway.framework.mybatisplus.DataPermission; import com.zsc.edu.gateway.modules.iot.product.dto.ProductDto; import com.zsc.edu.gateway.modules.iot.product.entity.Product; import com.zsc.edu.gateway.modules.iot.product.query.ProductQuery; @@ -26,8 +27,6 @@ public class ProductController { private final ProductService service; - - /** * 创建产品 * @@ -60,6 +59,7 @@ public class ProductController { * @param page 分页参数 * @return Page 产品分页数据 */ + @DataPermission @GetMapping @PreAuthorize("hasAuthority('iot:product:query')") public Page page(Page page, ProductQuery query) { diff --git a/src/main/java/com/zsc/edu/gateway/modules/iot/product/repo/ProductRepository.java b/src/main/java/com/zsc/edu/gateway/modules/iot/product/repo/ProductRepository.java index efb4d2c..1f02143 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/iot/product/repo/ProductRepository.java +++ b/src/main/java/com/zsc/edu/gateway/modules/iot/product/repo/ProductRepository.java @@ -1,10 +1,16 @@ package com.zsc.edu.gateway.modules.iot.product.repo; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.zsc.edu.gateway.framework.mybatisplus.DataPermission; import com.zsc.edu.gateway.modules.iot.product.entity.Product; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import java.util.List; + /** * @author Yao diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Role.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Role.java index 40fc44c..7107a36 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Role.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Role.java @@ -2,6 +2,7 @@ package com.zsc.edu.gateway.modules.system.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.zsc.edu.gateway.framework.mybatisplus.DataScopeType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -23,6 +24,10 @@ public class Role extends BaseEntity { * 名称,唯一 */ public String name; + /** + * 数据权限 + */ + public DataScopeType dataScope; /** * 启用状态 diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java index bda4d53..27f0485 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.*; +import java.util.Set; + /** * 用户 * @@ -59,6 +61,11 @@ public class User extends BaseEntity { */ @TableField(exist = false) public Dept dept; + /** + * 所属部门及子部门ID + */ + @TableField(exist = false) + public Set dataScopeDeptIds; /** * 角色ID diff --git a/src/main/resources/mappers/system/UserMapper.xml b/src/main/resources/mappers/system/UserMapper.xml index dbdb833..546ffe3 100644 --- a/src/main/resources/mappers/system/UserMapper.xml +++ b/src/main/resources/mappers/system/UserMapper.xml @@ -1,7 +1,7 @@ - + @@ -14,14 +14,19 @@ - - - - + + + + + + + + + - - + + @@ -36,21 +41,20 @@ id, username, password, email, phone, create_time - + select su.*, sr.name as role_name, sr.data_scope, sd.name as dept_name from sys_user su + left join sys_role sr on su.role_id = sr.id + left join sys_dept sd on su.dept_id = sd.id where su.username = #{username,jdbcType=VARCHAR} - select * from sys_user ${ew.customSqlSegment} - select * from sys_user diff --git a/src/test/java/com/zsc/edu/gateway/service/system/UserServiceTest.java b/src/test/java/com/zsc/edu/gateway/service/system/UserServiceTest.java index b740c71..d8fe0a6 100644 --- a/src/test/java/com/zsc/edu/gateway/service/system/UserServiceTest.java +++ b/src/test/java/com/zsc/edu/gateway/service/system/UserServiceTest.java @@ -49,20 +49,20 @@ public class UserServiceTest { private User user2; private User user3; - @BeforeEach - void setUp() { - user1 = UserBuilder.anUser().username("A张三").password("123456").enable(true).build(); - repo.insert(user1); - user2 = UserBuilder.anUser().username("A李四").password("123456").enable(true).build(); - repo.insert(user2); - user3 = UserBuilder.anUser().username("A王五").password("123456").enable(true).build(); - repo.insert(user3); - } - - @AfterEach - void tearDown() { - repo.delete(new LambdaQueryWrapper().in(User::getUsername, "A张三", "A李四", "A王五", "A赵六", "A陈七", "A刘八")); - } +// @BeforeEach +// void setUp() { +// user1 = UserBuilder.anUser().username("A张三").password("123456").enable(true).build(); +// repo.insert(user1); +// user2 = UserBuilder.anUser().username("A李四").password("123456").enable(true).build(); +// repo.insert(user2); +// user3 = UserBuilder.anUser().username("A王五").password("123456").enable(true).build(); +// repo.insert(user3); +// } +// +// @AfterEach +// void tearDown() { +// repo.delete(new LambdaQueryWrapper().in(User::getId, user1.getId(), user2.getId(), user3.getId())); +// } @Test void list() { @@ -107,6 +107,12 @@ public class UserServiceTest { void updatePassword() { assertTrue(service.updatePassword("777777", user3.id)); } + + @Test + void getOne() { + User byId = repo.selectByUsername("admin"); + assertNotNull(byId.role.dataScope); + } }