zoukankan      html  css  js  c++  java
  • Mybatis-plus 数据权限

    一、MyBatisPlusConfig配置:

    package com.ruoyi.framework.config;
    
    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import com.ruoyi.framework.datascope.DataScopeInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    /**
     * Mybatis Plus 配置
     *
     * @author ruoyi
     */
    @EnableTransactionManagement(proxyTargetClass = true)
    @Configuration
    public class MybatisPlusConfig {
    
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    
            // 数据权限
            interceptor.addInnerInterceptor(dataScopeInterceptor());
            // 分页插件
            interceptor.addInnerInterceptor(paginationInnerInterceptor());
            // 乐观锁插件
            interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
    
            return interceptor;
        }
    
        /**
         * 分页插件,自动识别数据库类型
         */
        public PaginationInnerInterceptor paginationInnerInterceptor() {
            PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
            // 设置数据库类型为mysql
            paginationInnerInterceptor.setDbType(DbType.MYSQL);
            // 设置最大单页限制数量,默认 500 条,-1 不受限制
            paginationInnerInterceptor.setMaxLimit(-1L);
            return paginationInnerInterceptor;
        }
    
        /**
         * 乐观锁插件
         */
        public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
            return new OptimisticLockerInnerInterceptor();
        }
    
        /**
         * 数据权限插件
         *
         * @return DataScopeInterceptor
         */
        public DataScopeInterceptor dataScopeInterceptor() {
            return new DataScopeInterceptor();
        }
    }

     二、DataScopeInnerInterceptor数据权限拦截器配置

    package com.ruoyi.framework.datascope;
    
    import cn.hutool.core.collection.CollectionUtil;
    import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
    import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
    import com.ruoyi.common.Enum.DataScopeTypeEnum;
    import com.ruoyi.common.core.data.DataScope;
    import com.ruoyi.common.core.domain.entity.SysRole;
    import com.ruoyi.common.core.domain.entity.SysUser;
    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.utils.ServletUtils;
    import com.ruoyi.common.utils.StringUtils;
    import com.ruoyi.common.utils.spring.SpringUtils;
    import com.ruoyi.framework.web.service.TokenService;
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.BoundSql;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * 数据权限
     *
     * @author: Fred
     * @email 453086@qq.com
     * @create: 2021-05-25 11:12
     */
    public class DataScopeInterceptor implements InnerInterceptor {
    
        @Override
        public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
                                ResultHandler resultHandler, BoundSql boundSql) {
    
            PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
            String originalSql = boundSql.getSql();
            Object parameterObject = boundSql.getParameterObject();
    
            // 查找参数中包含DataScope类型的参数
            DataScope dataScope = findDataScopeObject(parameterObject);
            if (dataScope == null) {
                return;
            }
    
            LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
            if (StringUtils.isNotNull(loginUser)) {
                SysUser currentUser = loginUser.getUser();
                // 如果是超级管理员,则不过滤数据
                if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
                    String scopeName = dataScope.getScopeName();
                    List<String> deptIds = dataScope.getDeptIds();
    
                    dataScopeFilter(currentUser, deptIds);
                    if (deptIds.isEmpty()) {
                        originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2",
                                dataScope.getFunc().getType(), originalSql);
                    } else {
                        String join = CollectionUtil.join(deptIds, ",");
                        originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)",
                                dataScope.getFunc().getType(), originalSql, scopeName, join);
                    }
                }
            }
            mpBs.sql(originalSql);
        }
    
        /**
         * 查找参数是否包括DataScope对象
         *
         * @param parameterObj 参数列表
         * @return DataScope
         */
        private DataScope findDataScopeObject(Object parameterObj) {
            if (parameterObj instanceof DataScope) {
                return (DataScope) parameterObj;
            } else if (parameterObj instanceof Map) {
                for (Object val : ((Map<?, ?>) parameterObj).values()) {
                    if (val instanceof DataScope) {
                        return (DataScope) val;
                    }
                }
            }
            return null;
        }
    
        /**
         * 数据范围
         *
         * @return
         */
        private void dataScopeFilter(SysUser user, List<String> deptList) {
    
            for (SysRole role : user.getRoles()) {
                String roleScope = role.getDataScope();
                if (DataScopeTypeEnum.ALL.getType().equals(roleScope)) {
                    return;
                }
                if (DataScopeTypeEnum.CUSTOM.getType().equals(roleScope)) {
                    //   获取自定义
                }
                if (DataScopeTypeEnum.OWN_CHILD_LEVEL.getType().equals(roleScope)) {
                    // 获取子集
                }
                if (DataScopeTypeEnum.OWN_LEVEL.getType().equals(roleScope)) {
                    deptList.add(user.getDeptId().toString());
                }
            }
        }
    }
    /*
     *    Copyright (c) 2018-2025, lengleng All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     * Redistributions of source code must retain the above copyright notice,
     * this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
     * notice, this list of conditions and the following disclaimer in the
     * documentation and/or other materials provided with the distribution.
     * Neither the name of the pig4cloud.com developer nor the names of its
     * contributors may be used to endorse or promote products derived from
     * this software without specific prior written permission.
     * Author: lengleng (wangiegie@gmail.com)
     */
    
    package com.ruoyi.common.core.data;
    
    import com.ruoyi.common.Enum.DataScopeFuncEnum;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * @author lengleng
     * @date 2018/8/30
     * 数据权限查询参数
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public class DataScope extends HashMap {
    
        /**
         * 限制范围的字段名称
         */
        private String scopeName = "dept_id";
    
        /**
         * 具体的数据范围
         */
        private List<String> deptIds = new ArrayList<>();
    
        /**
         * 是否只查询本部门
         */
        private Boolean isOnly = false;
    
        /**
         * 函数名称,默认 SELECT * ;
         *
         * <ul>
         * <li>COUNT(1)</li>
         * </ul>
         */
        private DataScopeFuncEnum func = DataScopeFuncEnum.ALL;
    }
    /*
     *    Copyright (c) 2018-2025, lengleng All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     * Redistributions of source code must retain the above copyright notice,
     * this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
     * notice, this list of conditions and the following disclaimer in the
     * documentation and/or other materials provided with the distribution.
     * Neither the name of the pig4cloud.com developer nor the names of its
     * contributors may be used to endorse or promote products derived from
     * this software without specific prior written permission.
     * Author: lengleng (wangiegie@gmail.com)
     */
    
    package com.ruoyi.common.Enum;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    
    /**
     * 数据权限函数类型
     *
     * @author lengleng
     * @date 2020-06-17
     */
    @Getter
    @AllArgsConstructor
    public enum DataScopeFuncEnum {
    
        /**
         * 查询全部数据 SELECT * FROM (originSql) temp_data_scope WHERE temp_data_scope.dept_id IN
         * (1)
         */
        ALL("*", "全部"),
    
        /**
         * 查询函数COUNT SELECT COUNT(1) FROM (originSql) temp_data_scope WHERE
         * temp_data_scope.dept_id IN (1)
         */
        COUNT("COUNT(1)", "自定义");
    
        /**
         * 类型
         */
        private final String type;
    
        /**
         * 描述
         */
        private final String description;
    
    }
  • 相关阅读:
    穿透层的鼠标事件
    深入浅出HTML与XHTML的区别
    JQuery中一个简单的表单验证的实例
    JavaScript window.setTimeout() 的详细用法
    js动态创建及移除div的方法
    js插入节点appendChild和insertBefore
    sublime使用方法
    js移动客户端--触屏滑动事件
    jquery 延迟执行实例介绍
    JS页面延迟执行一些方法(整理)
  • 原文地址:https://www.cnblogs.com/fangts/p/14814355.html
Copyright © 2011-2022 走看看