mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-31 22:57:19 +08:00 
			
		
		
		
	feat(data/mybatis-plus): 新增数据权限默认解决方案
1.新增数据权限默认解决方案 2.调整 BaseMapper 所属模块 crud => mybatis-plus 3.优化 mybatis-plus 模块包结构
This commit is contained in:
		| @@ -0,0 +1,33 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.autoconfigure; | ||||
|  | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
|  | ||||
| import java.lang.annotation.*; | ||||
|  | ||||
| /** | ||||
|  * 是否启用数据权限注解 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @Target({ ElementType.TYPE, ElementType.METHOD }) | ||||
| @Documented | ||||
| @ConditionalOnProperty(prefix = "mybatis-plus.extension.data-permission", name = "enabled", havingValue = "true") | ||||
| public @interface ConditionalOnEnabledDataPermission {} | ||||
| @@ -17,7 +17,6 @@ | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.autoconfigure; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.DbType; | ||||
| import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler; | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
|  | ||||
| @@ -46,15 +45,28 @@ public class MyBatisPlusExtensionProperties { | ||||
|     private String mapperPackage; | ||||
|  | ||||
|     /** | ||||
|      * 数据权限处理器实现类 | ||||
|      * 数据权限插件配置 | ||||
|      */ | ||||
|     private Class<? extends DataPermissionHandler> dataPermissionHandlerImpl; | ||||
|     private DataPermissionProperties dataPermission; | ||||
|  | ||||
|     /** | ||||
|      * 分页插件配置 | ||||
|      */ | ||||
|     private PaginationProperties pagination; | ||||
|  | ||||
|     /** | ||||
|      * 数据权限插件配置属性 | ||||
|      */ | ||||
|     @Data | ||||
|     public static class DataPermissionProperties { | ||||
|  | ||||
|         /** | ||||
|          * 是否启用数据权限插件 | ||||
|          */ | ||||
|         private boolean enabled = false; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 分页插件配置属性 | ||||
|      */ | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.autoconfigure; | ||||
|  | ||||
| import cn.hutool.core.net.NetUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.hutool.extra.spring.SpringUtil; | ||||
| import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator; | ||||
| import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; | ||||
| import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | ||||
| @@ -36,6 +36,8 @@ import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.PropertySource; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| import top.charles7c.continew.starter.core.handler.GeneralPropertySourceFactory; | ||||
| import top.charles7c.continew.starter.data.mybatis.plus.datapermission.DataPermissionFilter; | ||||
| import top.charles7c.continew.starter.data.mybatis.plus.datapermission.DataPermissionHandlerImpl; | ||||
|  | ||||
| /** | ||||
|  * MyBatis Plus 自动配置 | ||||
| @@ -60,13 +62,13 @@ public class MybatisPlusAutoConfiguration { | ||||
|     public MybatisPlusInterceptor mybatisPlusInterceptor(MyBatisPlusExtensionProperties properties) { | ||||
|         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); | ||||
|         // 数据权限插件 | ||||
|         Class<? extends DataPermissionHandler> dataPermissionHandlerImpl = properties.getDataPermissionHandlerImpl(); | ||||
|         if (null != dataPermissionHandlerImpl) { | ||||
|             interceptor.addInnerInterceptor(new DataPermissionInterceptor(ReflectUtil.newInstance(dataPermissionHandlerImpl))); | ||||
|         MyBatisPlusExtensionProperties.DataPermissionProperties dataPermissionProperties = properties.getDataPermission(); | ||||
|         if (null != dataPermissionProperties && dataPermissionProperties.isEnabled()) { | ||||
|             interceptor.addInnerInterceptor(new DataPermissionInterceptor(SpringUtil.getBean(DataPermissionHandler.class))); | ||||
|         } | ||||
|         // 分页插件 | ||||
|         MyBatisPlusExtensionProperties.PaginationProperties paginationProperties = properties.getPagination(); | ||||
|         if (properties.isEnabled() && paginationProperties.isEnabled()) { | ||||
|         if (null != paginationProperties && paginationProperties.isEnabled()) { | ||||
|             interceptor.addInnerInterceptor(this.paginationInnerInterceptor(paginationProperties)); | ||||
|         } | ||||
|         // 防全表更新与删除插件 | ||||
| @@ -74,6 +76,16 @@ public class MybatisPlusAutoConfiguration { | ||||
|         return interceptor; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 数据权限处理器 | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean | ||||
|     @ConditionalOnEnabledDataPermission | ||||
|     public DataPermissionHandler dataPermissionHandler(DataPermissionFilter dataPermissionFilter) { | ||||
|         return new DataPermissionHandlerImpl(dataPermissionFilter); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * ID 生成器配置(仅在主键类型(idType)配置为 ASSIGN_ID 或 ASSIGN_UUID 时有效) | ||||
|      * <p> | ||||
|   | ||||
| @@ -0,0 +1,112 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.base; | ||||
|  | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; | ||||
| import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; | ||||
| import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; | ||||
| import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper; | ||||
| import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers; | ||||
| import com.baomidou.mybatisplus.extension.toolkit.Db; | ||||
|  | ||||
| import java.util.Collection; | ||||
|  | ||||
| /** | ||||
|  * Mapper 基类 | ||||
|  * | ||||
|  * @param <T> 实体类 | ||||
|  * @author Charles7c | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> { | ||||
|  | ||||
|     /** | ||||
|      * 批量插入记录 | ||||
|      * | ||||
|      * @param entityList 实体列表 | ||||
|      * @return 是否成功 | ||||
|      */ | ||||
|     default boolean insertBatch(Collection<T> entityList) { | ||||
|         return Db.saveBatch(entityList); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 批量更新记录 | ||||
|      * | ||||
|      * @param entityList 实体列表 | ||||
|      * @return 是否成功 | ||||
|      */ | ||||
|     default boolean updateBatchById(Collection<T> entityList) { | ||||
|         return Db.updateBatchById(entityList); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 链式查询 | ||||
|      * | ||||
|      * @return QueryWrapper 的包装类 | ||||
|      */ | ||||
|     default QueryChainWrapper<T> query() { | ||||
|         return ChainWrappers.queryChain(this); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 链式查询(lambda 式) | ||||
|      * | ||||
|      * @return LambdaQueryWrapper 的包装类 | ||||
|      */ | ||||
|     default LambdaQueryChainWrapper<T> lambdaQuery() { | ||||
|         return ChainWrappers.lambdaQueryChain(this, this.currentEntityClass()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 链式查询(lambda 式) | ||||
|      * | ||||
|      * @param entity 实体对象 | ||||
|      * @return LambdaQueryWrapper 的包装类 | ||||
|      */ | ||||
|     default LambdaQueryChainWrapper<T> lambdaQuery(T entity) { | ||||
|         return ChainWrappers.lambdaQueryChain(this, entity); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 链式更改 | ||||
|      * | ||||
|      * @return UpdateWrapper 的包装类 | ||||
|      */ | ||||
|     default UpdateChainWrapper<T> update() { | ||||
|         return ChainWrappers.updateChain(this); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 链式更改(lambda 式) | ||||
|      * | ||||
|      * @return LambdaUpdateWrapper 的包装类 | ||||
|      */ | ||||
|     default LambdaUpdateChainWrapper<T> lambdaUpdate() { | ||||
|         return ChainWrappers.lambdaUpdateChain(this); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取实体类 Class 对象 | ||||
|      * | ||||
|      * @return 实体类 Class 对象 | ||||
|      */ | ||||
|     default Class<T> currentEntityClass() { | ||||
|         return (Class<T>) ClassUtil.getTypeArgument(this.getClass(), 0); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.datapermission; | ||||
|  | ||||
| import org.springframework.core.annotation.AliasFor; | ||||
|  | ||||
| import java.lang.annotation.*; | ||||
|  | ||||
| /** | ||||
|  * 数据权限注解 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Target(ElementType.METHOD) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @Documented | ||||
| public @interface DataPermission { | ||||
|  | ||||
|     /** | ||||
|      * Alias for the {@link #tableAlias()} attribute. | ||||
|      */ | ||||
|     @AliasFor("tableAlias") | ||||
|     String value() default ""; | ||||
|  | ||||
|     /** | ||||
|      * 表别名 | ||||
|      */ | ||||
|     @AliasFor("value") | ||||
|     String tableAlias() default ""; | ||||
|  | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     String id() default "id"; | ||||
|  | ||||
|     /** | ||||
|      * 部门 ID | ||||
|      */ | ||||
|     String deptId() default "dept_id"; | ||||
|  | ||||
|     /** | ||||
|      * 用户 ID | ||||
|      */ | ||||
|     String userId() default "create_user"; | ||||
|  | ||||
|     /** | ||||
|      * 角色 ID(角色和部门关联表) | ||||
|      */ | ||||
|     String roleId() default "role_id"; | ||||
|  | ||||
|     /** | ||||
|      * 部门表别名 | ||||
|      */ | ||||
|     String deptTableAlias() default "sys_dept"; | ||||
|  | ||||
|     /** | ||||
|      * 角色和部门关联表别名 | ||||
|      */ | ||||
|     String roleDeptTableAlias() default "sys_role_dept"; | ||||
| } | ||||
| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.datapermission; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * 当前用户信息 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Data | ||||
| public class DataPermissionCurrentUser { | ||||
|  | ||||
|     /** | ||||
|      * 用户 ID | ||||
|      */ | ||||
|     private String userId; | ||||
|  | ||||
|     /** | ||||
|      * 角色列表 | ||||
|      */ | ||||
|     private Set<CurrentUserRole> roles; | ||||
|  | ||||
|     /** | ||||
|      * 部门 ID | ||||
|      */ | ||||
|     private String deptId; | ||||
|  | ||||
|     /** | ||||
|      * 当前用户角色信息 | ||||
|      */ | ||||
|     @Data | ||||
|     @AllArgsConstructor | ||||
|     public static class CurrentUserRole { | ||||
|  | ||||
|         /** | ||||
|          * 角色 ID | ||||
|          */ | ||||
|         private String roleId; | ||||
|  | ||||
|         /** | ||||
|          * 数据权限 | ||||
|          */ | ||||
|         private DataScope dataScope; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.datapermission; | ||||
|  | ||||
| /** | ||||
|  * 数据权限过滤器接口 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| public interface DataPermissionFilter { | ||||
|  | ||||
|     /** | ||||
|      * 是否过滤 | ||||
|      * | ||||
|      * @return true:过滤;false:不过滤 | ||||
|      */ | ||||
|     boolean isFilter(); | ||||
|  | ||||
|     /** | ||||
|      * 获取当前用户信息 | ||||
|      * | ||||
|      * @return 当前用户信息 | ||||
|      */ | ||||
|     DataPermissionCurrentUser getCurrentUser(); | ||||
| } | ||||
| @@ -0,0 +1,173 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.datapermission; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.Collections; | ||||
| import java.util.Set; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | ||||
| import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler; | ||||
|  | ||||
| import top.charles7c.continew.starter.core.constant.StringConstants; | ||||
|  | ||||
| import net.sf.jsqlparser.expression.Expression; | ||||
| import net.sf.jsqlparser.expression.Function; | ||||
| import net.sf.jsqlparser.expression.LongValue; | ||||
| import net.sf.jsqlparser.expression.Parenthesis; | ||||
| import net.sf.jsqlparser.expression.operators.conditional.AndExpression; | ||||
| import net.sf.jsqlparser.expression.operators.conditional.OrExpression; | ||||
| 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.schema.Column; | ||||
| import net.sf.jsqlparser.schema.Table; | ||||
| import net.sf.jsqlparser.statement.select.PlainSelect; | ||||
| import net.sf.jsqlparser.statement.select.SelectExpressionItem; | ||||
| import net.sf.jsqlparser.statement.select.SubSelect; | ||||
|  | ||||
| /** | ||||
|  * 数据权限处理器实现类 | ||||
|  * | ||||
|  * @author <a href="https://gitee.com/baomidou/mybatis-plus/issues/I37I90">DataPermissionInterceptor 如何使用?</a> | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Slf4j | ||||
| @RequiredArgsConstructor | ||||
| public class DataPermissionHandlerImpl implements DataPermissionHandler { | ||||
|  | ||||
|     private final DataPermissionFilter dataPermissionFilter; | ||||
|  | ||||
|     @Override | ||||
|     public Expression getSqlSegment(Expression where, String mappedStatementId) { | ||||
|         try { | ||||
|             Class<?> clazz = | ||||
|                 Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(StringConstants.DOT))); | ||||
|             String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(StringConstants.DOT) + 1); | ||||
|             Method[] methodArr = clazz.getMethods(); | ||||
|             for (Method method : methodArr) { | ||||
|                 DataPermission dataPermission = method.getAnnotation(DataPermission.class); | ||||
|                 if (null != dataPermission | ||||
|                     && (method.getName().equals(methodName) || (method.getName() + "_COUNT").equals(methodName))) { | ||||
|                     if (dataPermissionFilter.isFilter()) { | ||||
|                         return buildDataScopeFilter(dataPermission, where); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } catch (ClassNotFoundException e) { | ||||
|             log.error("Data permission handler build data scope filter occurred an error: {}.", e.getMessage(), e); | ||||
|         } | ||||
|         return where; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 构建数据范围过滤条件 | ||||
|      * | ||||
|      * @param dataPermission | ||||
|      *            数据权限 | ||||
|      * @param where | ||||
|      *            当前查询条件 | ||||
|      * @return 构建后查询条件 | ||||
|      */ | ||||
|     private Expression buildDataScopeFilter(DataPermission dataPermission, Expression where) { | ||||
|         Expression expression = null; | ||||
|         String tableAlias = dataPermission.tableAlias(); | ||||
|         String id = dataPermission.id(); | ||||
|         String deptId = dataPermission.deptId(); | ||||
|         DataPermissionCurrentUser currentUser = dataPermissionFilter.getCurrentUser(); | ||||
|         Set<DataPermissionCurrentUser.CurrentUserRole> roles = currentUser.getRoles(); | ||||
|         for (DataPermissionCurrentUser.CurrentUserRole role : roles) { | ||||
|             DataScope dataScope = role.getDataScope(); | ||||
|             if (DataScope.ALL.equals(dataScope)) { | ||||
|                 return where; | ||||
|             } | ||||
|             if (DataScope.DEPT_AND_CHILD.equals(dataScope)) { | ||||
|                 // select t1.* from table as t1 where t1.`dept_id` in (select `id` from `sys_dept` where `id` = xxx or | ||||
|                 // find_in_set(xxx, `ancestors`)); | ||||
|                 // 构建子查询 | ||||
|                 SubSelect subSelect = new SubSelect(); | ||||
|                 PlainSelect select = new PlainSelect(); | ||||
|                 select.setSelectItems(Collections.singletonList(new SelectExpressionItem(new Column(id)))); | ||||
|                 select.setFromItem(new Table(dataPermission.deptTableAlias())); | ||||
|                 EqualsTo equalsTo = new EqualsTo(); | ||||
|                 equalsTo.setLeftExpression(new Column(id)); | ||||
|                 equalsTo.setRightExpression(new LongValue(currentUser.getDeptId())); | ||||
|                 Function function = new Function(); | ||||
|                 function.setName("find_in_set"); | ||||
|                 function.setParameters(new ExpressionList(new LongValue(currentUser.getDeptId()), new Column("ancestors"))); | ||||
|                 select.setWhere(new OrExpression(equalsTo, function)); | ||||
|                 subSelect.setSelectBody(select); | ||||
|                 // 构建父查询 | ||||
|                 InExpression inExpression = new InExpression(); | ||||
|                 inExpression.setLeftExpression(this.buildColumn(tableAlias, deptId)); | ||||
|                 inExpression.setRightExpression(subSelect); | ||||
|                 expression = null != expression ? new OrExpression(expression, inExpression) : inExpression; | ||||
|             } else if (DataScope.DEPT.equals(dataScope)) { | ||||
|                 // select t1.* from table as t1 where t1.`dept_id` = xxx; | ||||
|                 EqualsTo equalsTo = new EqualsTo(); | ||||
|                 equalsTo.setLeftExpression(this.buildColumn(tableAlias, deptId)); | ||||
|                 equalsTo.setRightExpression(new LongValue(currentUser.getDeptId())); | ||||
|                 expression = null != expression ? new OrExpression(expression, equalsTo) : equalsTo; | ||||
|             } else if (DataScope.SELF.equals(dataScope)) { | ||||
|                 // select t1.* from table as t1 where t1.`create_user` = xxx; | ||||
|                 EqualsTo equalsTo = new EqualsTo(); | ||||
|                 equalsTo.setLeftExpression(this.buildColumn(tableAlias, dataPermission.userId())); | ||||
|                 equalsTo.setRightExpression(new LongValue(currentUser.getUserId())); | ||||
|                 expression = null != expression ? new OrExpression(expression, equalsTo) : equalsTo; | ||||
|             } else if (DataScope.CUSTOM.equals(dataScope)) { | ||||
|                 // select t1.* from table as t1 where t1.`dept_id` in (select `dept_id` from `sys_role_dept` where | ||||
|                 // `role_id` = xxx); | ||||
|                 // 构建子查询 | ||||
|                 SubSelect subSelect = new SubSelect(); | ||||
|                 PlainSelect select = new PlainSelect(); | ||||
|                 select.setSelectItems(Collections.singletonList(new SelectExpressionItem(new Column(deptId)))); | ||||
|                 select.setFromItem(new Table(dataPermission.roleDeptTableAlias())); | ||||
|                 EqualsTo equalsTo = new EqualsTo(); | ||||
|                 equalsTo.setLeftExpression(new Column(dataPermission.roleId())); | ||||
|                 equalsTo.setRightExpression(new LongValue(role.getRoleId())); | ||||
|                 select.setWhere(equalsTo); | ||||
|                 subSelect.setSelectBody(select); | ||||
|                 // 构建父查询 | ||||
|                 InExpression inExpression = new InExpression(); | ||||
|                 inExpression.setLeftExpression(this.buildColumn(tableAlias, deptId)); | ||||
|                 inExpression.setRightExpression(subSelect); | ||||
|                 expression = null != expression ? new OrExpression(expression, inExpression) : inExpression; | ||||
|             } | ||||
|         } | ||||
|         return null != where ? new AndExpression(where, new Parenthesis(expression)) : expression; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 构建 Column | ||||
|      * | ||||
|      * @param tableAlias | ||||
|      *            表别名 | ||||
|      * @param columnName | ||||
|      *            字段名称 | ||||
|      * @return 带表别名字段 | ||||
|      */ | ||||
|     private Column buildColumn(String tableAlias, String columnName) { | ||||
|         if (StringUtils.isNotEmpty(tableAlias)) { | ||||
|             columnName = String.format("%s.%s", tableAlias, columnName); | ||||
|         } | ||||
|         return new Column(columnName); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.datapermission; | ||||
|  | ||||
| /** | ||||
|  * 数据权限枚举 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| public enum DataScope { | ||||
|  | ||||
|     /** | ||||
|      * 全部数据权限 | ||||
|      */ | ||||
|     ALL, | ||||
|  | ||||
|     /** | ||||
|      * 本部门及以下数据权限 | ||||
|      */ | ||||
|     DEPT_AND_CHILD, | ||||
|  | ||||
|     /** | ||||
|      * 本部门数据权限 | ||||
|      */ | ||||
|     DEPT, | ||||
|  | ||||
|     /** | ||||
|      * 仅本人数据权限 | ||||
|      */ | ||||
|     SELF, | ||||
|  | ||||
|     /** | ||||
|      * 自定义数据权限 | ||||
|      */ | ||||
|     CUSTOM, | ||||
| } | ||||
| @@ -14,9 +14,7 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.annotation; | ||||
| 
 | ||||
| import top.charles7c.continew.starter.data.mybatis.plus.enums.QueryType; | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.query; | ||||
| 
 | ||||
| import java.lang.annotation.*; | ||||
| 
 | ||||
| @@ -14,7 +14,7 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.util; | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.query; | ||||
| 
 | ||||
| import cn.hutool.core.util.ArrayUtil; | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
| @@ -26,8 +26,6 @@ import lombok.extern.slf4j.Slf4j; | ||||
| import top.charles7c.continew.starter.core.exception.BadRequestException; | ||||
| import top.charles7c.continew.starter.core.util.ReflectUtils; | ||||
| import top.charles7c.continew.starter.core.util.validate.ValidationUtils; | ||||
| import top.charles7c.continew.starter.data.mybatis.plus.annotation.Query; | ||||
| import top.charles7c.continew.starter.data.mybatis.plus.enums.QueryType; | ||||
| 
 | ||||
| import java.lang.reflect.Field; | ||||
| import java.util.ArrayList; | ||||
| @@ -14,7 +14,7 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.enums; | ||||
| package top.charles7c.continew.starter.data.mybatis.plus.query; | ||||
| 
 | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
		Reference in New Issue
	
	Block a user