From 22e1bc19f035cabd25b143eda21c2716368c3da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Wed, 8 Dec 2021 13:50:53 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BD=BF=E7=94=A8=E6=96=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=E6=B3=A8=E8=A7=A3=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/common/annotation/DataColumn.java | 19 +++ .../common/annotation/DataPermission.java | 17 +++ .../com/ruoyi/demo/mapper/TestDemoMapper.java | 18 ++- .../com/ruoyi/demo/mapper/TestTreeMapper.java | 8 +- .../service/impl/TestDemoServiceImpl.java | 3 - .../service/impl/TestTreeServiceImpl.java | 3 - .../handler/PlusDataPermissionHandler.java | 115 ++++++++++-------- .../ruoyi/system/mapper/SysDeptMapper.java | 11 +- .../ruoyi/system/mapper/SysRoleMapper.java | 11 +- .../ruoyi/system/mapper/SysUserMapper.java | 23 +++- .../service/impl/SysConfigServiceImpl.java | 3 +- 11 files changed, 152 insertions(+), 79 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataPermission.java diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java new file mode 100644 index 000000000..343aaebc8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataColumn.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.*; + +/** + * 数据权限 + * + * @author Lion Li + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataColumn { + + String key(); + + String value(); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataPermission.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataPermission.java new file mode 100644 index 000000000..e04b23696 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataPermission.java @@ -0,0 +1,17 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.*; + +/** + * 数据权限组 + * + * @author Lion Li + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataPermission { + + DataColumn[] value(); + +} diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java index de597aae5..fd5b84951 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java @@ -4,7 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import com.ruoyi.demo.domain.TestDemo; import com.ruoyi.demo.domain.vo.TestDemoVo; @@ -20,14 +21,23 @@ import java.util.List; */ public interface TestDemoMapper extends BaseMapperPlus { - @DataScope(deptName = "dept_id", userName = "user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + @DataColumn(key = "userName", value = "user_id") + }) Page customPageList(@Param("page") Page page, @Param("ew") Wrapper wrapper); @Override - @DataScope(deptName = "dept_id", userName = "user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + @DataColumn(key = "userName", value = "user_id") + })

> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper queryWrapper); @Override - @DataScope(deptName = "dept_id", userName = "user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + @DataColumn(key = "userName", value = "user_id") + }) List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java index 315dad771..590b50d0d 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java @@ -2,7 +2,8 @@ package com.ruoyi.demo.mapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import com.ruoyi.demo.domain.TestTree; import org.apache.ibatis.annotations.Param; @@ -18,6 +19,9 @@ import java.util.List; public interface TestTreeMapper extends BaseMapperPlus { @Override - @DataScope(deptName = "dept_id", userName = "user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + @DataColumn(key = "userName", value = "user_id") + }) List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java index 1fa2057d5..1cb526848 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java @@ -59,14 +59,11 @@ public class TestDemoServiceImpl extends ServicePlusImpl buildQueryWrapper(TestDemoBo bo) { Map params = bo.getParams(); - Object dataScope = params.get("dataScope"); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey()); lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue()); lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); - lqw.apply(dataScope != null && StringUtils.isNotBlank(dataScope.toString()), - dataScope != null ? dataScope.toString() : null); return lqw; } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java index d86465c10..c4097e667 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java @@ -40,13 +40,10 @@ public class TestTreeServiceImpl extends ServicePlusImpl buildQueryWrapper(TestTreeBo bo) { Map params = bo.getParams(); - Object dataScope = params.get("dataScope"); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName()); lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); - lqw.apply(dataScope != null && StringUtils.isNotBlank(dataScope.toString()), - dataScope != null ? dataScope.toString() : null); return lqw; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java index e3c0cf6c1..4f811ca7f 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java @@ -1,10 +1,12 @@ package com.ruoyi.framework.handler; import cn.hutool.core.annotation.AnnotationUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.service.UserService; @@ -26,7 +28,6 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -38,76 +39,64 @@ import java.util.stream.Collectors; @Slf4j public class PlusDataPermissionHandler implements DataPermissionHandler { + private final ExpressionParser parser = new SpelExpressionParser(); + private final TemplateParserContext parserContext = new TemplateParserContext(); + @Override public Expression getSqlSegment(Expression where, String mappedStatementId) { - DataScope dataScope = findDataScopeAnnotation(mappedStatementId); - if (ObjectUtil.isNull(dataScope)) { + DataColumn[] dataColumns = findAnnotation(mappedStatementId); + if (ArrayUtil.isEmpty(dataColumns)) { return where; } SysUser currentUser = SpringUtils.getBean(UserService.class).selectUserById(SecurityUtils.getUserId()); // 如果是超级管理员,则不过滤数据 - if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) { - String dataScopeSql = dataScopeFilter(currentUser, dataScope); - if (StringUtils.isNotBlank(dataScopeSql)) { - try { - Expression expression = CCJSqlParserUtil.parseExpression(dataScopeSql); - return new AndExpression(where, expression); - } catch (JSQLParserException e) { - throw new ServiceException("数据权限解析异常 => " + e.getMessage()); - } - } + if (StringUtils.isNull(currentUser) || currentUser.isAdmin()) { + return where; } - return where; - } - - private DataScope findDataScopeAnnotation(String mappedStatementId) { - StringBuilder sb = new StringBuilder(mappedStatementId); - int index = sb.lastIndexOf("."); - String clazzName = sb.substring(0, index); - String methodName = sb.substring(index + 1, sb.length()); - Class clazz = ClassUtil.loadClass(clazzName); - List methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz)) - .filter(method -> method.getName().equals(methodName)).collect(Collectors.toList()); - DataScope dataScope = null; - for (Method method : methods) { - if (AnnotationUtil.hasAnnotation(method, DataScope.class)) { - dataScope = AnnotationUtil.getAnnotation(method, DataScope.class); - break; - } + String dataFilterSql = buildDataFilter(currentUser, dataColumns); + if (StringUtils.isBlank(dataFilterSql)) { + return where; + } + try { + Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql); + if (ObjectUtil.isNotNull(where)) { + return new AndExpression(where, expression); + } else { + return expression; + } + } catch (JSQLParserException e) { + throw new ServiceException("数据权限解析异常 => " + e.getMessage()); } - return dataScope; } /** - * 数据范围过滤 - * - * @param user 用户 + * 构造数据过滤sql */ - public static String dataScopeFilter(SysUser user, DataScope annotation) { + private String buildDataFilter(SysUser user, DataColumn[] dataColumns) { StringBuilder sqlString = new StringBuilder(); - ExpressionParser parser = new SpelExpressionParser(); - TemplateParserContext parserContext = new TemplateParserContext(); - EvaluationContext context = new StandardEvaluationContext(new HashMap<>()); - context.setVariable("deptName", annotation.deptName()); - context.setVariable("userName", annotation.userName()); + EvaluationContext context = new StandardEvaluationContext(); context.setVariable("userId", user.getUserId()); context.setVariable("deptId", user.getDeptId()); - - for (SysRole role : user.getRoles()) { - context.setVariable("roleId", role.getRoleId()); - DataScopeType type = DataScopeType.findCode(role.getDataScope()); - if (ObjectUtil.isNull(type)) { - throw new ServiceException("角色数据范围异常 => " + role.getDataScope()); + for (DataColumn dataColumn : dataColumns) { + // 设置注解变量 key 为表达式变量 value 为变量值 + context.setVariable(dataColumn.key(), dataColumn.value()); + for (SysRole role : user.getRoles()) { + context.setVariable("roleId", role.getRoleId()); + // 获取角色权限泛型 + DataScopeType type = DataScopeType.findCode(role.getDataScope()); + if (ObjectUtil.isNull(type)) { + throw new ServiceException("角色数据范围异常 => " + role.getDataScope()); + } + // 全部数据权限直接返回 + if (type == DataScopeType.DATA_SCOPE_ALL) { + return ""; + } + // 解析sql模板并填充 + String sql = parser.parseExpression(type.getSql(), parserContext).getValue(context, String.class); + sqlString.append(sql); } - if (type == DataScopeType.DATA_SCOPE_ALL) { - sqlString = new StringBuilder(); - break; - } - org.springframework.expression.Expression expression = parser.parseExpression(type.getSql(), parserContext); - String sql = expression.getValue(context, String.class); - sqlString.append(sql); } if (StringUtils.isNotBlank(sqlString.toString())) { @@ -115,4 +104,22 @@ public class PlusDataPermissionHandler implements DataPermissionHandler { } return ""; } + + private DataColumn[] findAnnotation(String mappedStatementId) { + StringBuilder sb = new StringBuilder(mappedStatementId); + int index = sb.lastIndexOf("."); + String clazzName = sb.substring(0, index); + String methodName = sb.substring(index + 1, sb.length()); + Class clazz = ClassUtil.loadClass(clazzName); + List methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz)) + .filter(method -> method.getName().equals(methodName)).collect(Collectors.toList()); + DataPermission dataPermission; + for (Method method : methods) { + if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) { + dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class); + return dataPermission.value(); + } + } + return null; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java index 95a4a3e14..08c88caba 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java @@ -2,7 +2,8 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import org.apache.ibatis.annotations.Param; @@ -22,11 +23,15 @@ public interface SysDeptMapper extends BaseMapperPlus { * @param dept 部门信息 * @return 部门信息集合 */ - @DataScope(deptName = "d.dept_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id") + }) List selectDeptList(SysDept dept); @Override - @DataScope(deptName = "dept_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id") + }) List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java index cbd216ac0..d2721ee4d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java @@ -1,7 +1,8 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import org.apache.ibatis.annotations.Param; @@ -15,7 +16,9 @@ import java.util.List; */ public interface SysRoleMapper extends BaseMapperPlus { - @DataScope(deptName = "d.dept_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id") + }) Page selectPageRoleList(@Param("page") Page page, @Param("role") SysRole role); /** @@ -24,7 +27,9 @@ public interface SysRoleMapper extends BaseMapperPlus { * @param role 角色信息 * @return 角色数据集合信息 */ - @DataScope(deptName = "d.dept_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id") + }) List selectRoleList(SysRole role); /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java index b3780df71..1a07f7f92 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -1,7 +1,8 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.annotation.DataColumn; +import com.ruoyi.common.annotation.DataPermission; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import org.apache.ibatis.annotations.Param; @@ -15,7 +16,10 @@ import java.util.List; */ public interface SysUserMapper extends BaseMapperPlus { - @DataScope(deptName = "d.dept_id", userName = "u.user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id"), + @DataColumn(key = "userName", value = "u.user_id") + }) Page selectPageUserList(@Param("page") Page page, @Param("user") SysUser user); /** @@ -24,7 +28,10 @@ public interface SysUserMapper extends BaseMapperPlus { * @param sysUser 用户信息 * @return 用户信息集合信息 */ - @DataScope(deptName = "d.dept_id", userName = "u.user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id"), + @DataColumn(key = "userName", value = "u.user_id") + }) List selectUserList(SysUser sysUser); /** @@ -33,7 +40,10 @@ public interface SysUserMapper extends BaseMapperPlus { * @param user 用户信息 * @return 用户信息集合信息 */ - @DataScope(deptName = "d.dept_id", userName = "u.user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id"), + @DataColumn(key = "userName", value = "u.user_id") + }) Page selectAllocatedList(@Param("page") Page page, @Param("user") SysUser user); /** @@ -42,7 +52,10 @@ public interface SysUserMapper extends BaseMapperPlus { * @param user 用户信息 * @return 用户信息集合信息 */ - @DataScope(deptName = "d.dept_id", userName = "u.user_id") + @DataPermission({ + @DataColumn(key = "deptName", value = "d.dept_id"), + @DataColumn(key = "userName", value = "u.user_id") + }) Page selectUnallocatedList(@Param("page") Page page, @Param("user") SysUser user); /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java index 1888068d0..fdd672976 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java @@ -1,16 +1,15 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.convert.Convert; +import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.annotation.DataSource; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.service.ConfigService; -import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.RedisUtils;