学习笔记018——若依框架数据权限功能的实现

若依框架 使用数据权限功能 低代码开发框架若依,使用数据权限功能。 阅读详情
AI摘要

本文基于若依前后端分离v3.6.0版本,介绍了业务表创建、代码生成、用户权限设置和代码修改的步骤。详细分析了权限控制原理,通过自定义注解和数据切面类,根据用户权限范围生成不同的SQL语句,最终展示了请求执行的SQL语句。

ps:本文所使用的若依是前后端分离的v3.6.0版本。

1、建表

建立业务表的时候,需要在表中添加user_id和dept_id两个字段。(字段一定要一样,下文能体现)

user_id:表中该条记录的创建人id

dept_id:表中该条记录的创建人的部门id

建表SQL:

CREATE TABLE `t_warehouse_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
  `dept_id` bigint(20) DEFAULT NULL COMMENT '部门ID',
  `warehouse_code` varchar(255) DEFAULT NULL COMMENT '地址编码',
  `sort` bigint(20) DEFAULT '1' COMMENT '排序',
  `video_original_name` varchar(500) DEFAULT NULL COMMENT '源视频名',
  `video_name` varchar(500) DEFAULT NULL COMMENT '视频名字',
  `video_url` varchar(500) DEFAULT NULL COMMENT '视频具体地址',
  `original_file_name` varchar(500) DEFAULT NULL COMMENT '源文件名(图片、pdf)',
  `file_name` varchar(500) DEFAULT NULL COMMENT '文件名(图片、pdf)',
  `file_url` varchar(500) DEFAULT NULL COMMENT '文件具体地址(图片、pdf)',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='整体库房介绍';

2、生成代码

本地运行若依管理平台,打开代码生成页面。

点击导入表

选择导入刚刚创建的业务表

点击生成代码

3、设置用户权限

例如本人用超级用户给自己创建了一个用户,用户角色的信息如下:

本人的角色权限是部门及以下的权限

4、代码修改

生成的代码我们是不能直接使用的。需要做一些修改。

首先在controller类的插入记录接口中,为实体类插入用户id和部门id

其次在xml文件中,为select的sql添加  表别名 和  ${params.dataScope}

最后在service的实现类的列表查询方法上添加 注解

@DataScope(deptAlias = "d", userAlias = "d")

注意发现:

deptAlias = "d", userAlias = "d"

中的d就是表的别名。

5、原理分析

ctrl+左键点击我们发现他是一个自定义注解

在数据切面类中,获取了当前用户信息,并且将注解中的表别名一并传入了dataScopeFilter方法中。

我们在点击进入到dataScopeFilter方法中。

瞬间明白了,通过if判断当前用户的权限范围,配合注解中的表别名,生成不同权限的sql语句。

最后将sql放到业务实体类继承的BaseEntity类的params字段中。

xml文件中的${params.dataScope}就是对应了BaseEntity类中的params字段。

/**
 *
 * @param joinPoint 切点
 * @param user      当前用户
 * @param deptAlias 部门表别名
 * @param userAlias 用户表别名
 */
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
{
    StringBuilder sqlString = new StringBuilder();

    for (SysRole role : user.getRoles())
    {
        // 获取当前用户的数据权限范围
        String dataScope = role.getDataScope();
        if (DATA_SCOPE_ALL.equals(dataScope))
        {
            /** 全部数据权限   1 */
            sqlString = new StringBuilder();
            break;
        }
        else if (DATA_SCOPE_CUSTOM.equals(dataScope))
        {
            /** 自定数据权限   2 */
            sqlString.append(StringUtils.format(
                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
                    role.getRoleId()));
        }
        else if (DATA_SCOPE_DEPT.equals(dataScope))
        {
            /** 部门数据权限   3 */
            sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
        }
        else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
        {
            /** 部门及以下数据权限   4 */
            sqlString.append(StringUtils.format(
                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                    deptAlias, user.getDeptId(), user.getDeptId()));
        }
        else if (DATA_SCOPE_SELF.equals(dataScope))
        {
            if (StringUtils.isNotBlank(userAlias))
            {
                /** 仅本人数据权限   5 */
                sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
            }
            else
            {
                // 数据权限为仅本人且没有userAlias别名不查询任何数据
                sqlString.append(" OR 1=0 ");
            }
        }
    }

    if (StringUtils.isNotBlank(sqlString.toString()))
    {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
        }
    }
}

这里权限范围值是存在了dataScope字段中。

通过dataScope字段对比

/**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";

    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";

    /**
     * 部门数据权限
     */
    public static final String DATA_SCOPE_DEPT = "3";

    /**
     * 部门及以下数据权限
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";

    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScope";

例如本人的权限范围是:本部门及以下的权限。则生成的sql语句是:

OR u.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {当前登录用户部门id} or find_in_set( {当前登录用户部门id} , ancestors ) )

最后存在BaseEntity类的params字段中。

/**
 * Entity基类
 *
 * @author ruoyi
 */
public class BaseEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;

    /** 搜索值 */
    private String searchValue;

    /** 创建者 */
    private String createBy;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "时间", dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 100,width = 28)
    private Date createTime;

    /** 更新者 */
    private String updateBy;

    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    /** 备注 */
    private String remark;

    /** 请求参数 */
    private Map<String, Object> params;

}

6、最终请求执行的SQL 语句

14:59:24.942 [http-nio-8080-exec-21] DEBUG c.r.c.m.W.selectWarehouseInfoList - [debug,137] - ==>  Preparing: select id, user_id, dept_id, warehouse_code, sort, video_original_name, video_name, video_url, original_file_name, file_name, file_url, create_time, update_time, remark from t_warehouse_info d WHERE (d.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = 204 or find_in_set( 204 , ancestors ) )) order by sort


# 提取Sql
select id, user_id, dept_id, warehouse_code, sort, video_original_name, video_name, video_url, original_file_name, file_name, file_url, create_time, update_time, remark from t_warehouse_info d WHERE (d.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = 204 or find_in_set( 204 , ancestors ) )) order by sort

LEAF框架实战:如何用J2EE技术栈构建高效社保系统(附避坑指南) 本文详细介绍了如何利用LEAF框架和J2EE技术栈构建高效社保系统,涵盖核心架构解析、业务场景实现、安全合规方案及性能优化实战。特别提供开发中的避坑指南,帮助开发者快速掌握社保平台架构设计,提升系统稳定性和安全性。 阅读详情

相关推荐

A股量化选股实战框架:5个抗扰动因子与本地化回测系统

量化选股本质是构建稳定Alpha来源的信息处理系统,其核心在于因子有效性、数据可靠性与回测真实性。在A股市场,因子失效往往源于滞后性不足、数据口径混乱或中性化缺失;而回测失真则多因未模拟真实交易约束(如涨跌停、停牌、滑点)。本文聚焦可复现的工程实践,详解ROIC、动态PE、240日动量等5个经2018–2023年滚动验证的抗扰动因子设计逻辑,并提供基于聚宽数据源、纯Python本地运行的完整回测框架——涵盖财报截止日对齐、秩次正态化、双重行业市值中性化、可交易股票池过滤等关键细节,助力从pandas入门者到

闲谈 424

若依的权限控制该怎么做(超详细的图文教程)

若依的权限控制

Keep__Me的博客 5万+

Azure Synapse实战指南:湖仓一体、SQL优先与成本可控落地

Azure Synapse Analytics 是微软推出的统一数据分析平台,融合数据湖、数据仓库与大数据计算能力,核心特征是湖仓一体架构与SQL优先设计。其底层基于共享元数据的多引擎协同(SQL池、Spark池、Pipeline),使开发者能用标准T-SQL直接查询Parquet/JSON等湖中数据,大幅降低大数据技术门槛。技术价值在于打破传统ETL瓶颈,转向存储层ELT范式——利用Serverless SQL池实现免运维即查、通过分层生命周期管理(Hot/Cool/Archive)压降云存储成本、依托工

weixin_33885676的博客 354

若依项目中的数据权限管理详解

本部门数据权限只能看到本部门的,下面部门的数据看不到,本部门及以下数据权限可以看到部门以下的数据权限;例如对于销售,财务的数据,它们是非常敏感的,因此要求对数据权限进行控制, 对于基于集团性的应用系统而言,就更多需要控制好各自公司的数据了。如设置只能看本公司、或者本部门的数据,对于特殊的领导,可能需要跨部门的数据, 因此程序不能硬编码那个领导该访问哪些数据,需要进行后台的权限和数据权限的控制。结果很明显,我们多了如下语句。在实际开发中,需要设置用户只能查看哪些部门的数据,这种情况一般称为数据权限。

tigerhhzz的博客 1万+

若依开源框架中数据权限的使用及配置

对于数据隔离问题,也就是不同角色的用户拥有的数据权限问题,虽然文档也有描述,也有一个现成的例子,但是没有结果业务功能,看得有点不太好理解,我这里直接举例业务功能的例子,帮助朋友们根据自己业务去做调整,完成数据权限的使用,能够满足业主的需求...

乘风偷月的博客 2万+

若依笔记(三):用户权限体系与数据隔离

​ 已知若依单体的前端采用vue-element-admin,在前端的专栏系列vue-element-admin的动态路由已详细拆解,其最大特点是使用后端返回数据控制前端菜单,每次接口请求前会有路由拦截来获取权限和菜单列表并重新渲染页面,配合若依后端自己实现的数据权限切面,能够实现很好地的数据隔离和权限隔离,那么现在就从代码层面分析其实现; ​

叶子叶来 6194

中文详细注释的开源项目

????这是一个或许对你有用的开源项目国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:Boot 项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-proCloud 项目地址:https://gitee.c...

weixin_44421461的博客 211

019-JAVA访问权限、封装详细讲解

封装:将成员变量声明为私有的(private),再提供一个或多个公有(public)setXX() 和getXX()方法实现对该成员变量的访问和修改。 类中的私有成员变量/成员方法只能在该类内部调用,不能通过该类的对象调用。 封装的目的 隐藏类的实现细节; 让使用者只能通过指定的方法访问数据,可以方便加入控制逻辑,限制不合理的操作; 便于修改,增强代码可维护性;可进行数据检查。

软件之家的博客 343

基于角色的权限管理系统

我们开发业务系统的时候,基本上都会涉及到权限管理模块,要求不同的人看到不同的菜单,操作不同的按钮,看到不同的数据。很多初学者面对这样的需求不知道如何下手,特别是稍微复杂点的权限,更是找不到方向,为此我们夜鹰教程网特别推出了这套基于角色的权限管理视频教程,通过给用户分配角色,给角色分配权限,来实现权限管理。这样一来,可以实现不同的人管理不同的菜单,操作不同的按钮,看到不同的数据。可以划分权限组,每个...

weixin_33716154的博客 376

实验室信息管理系统需求规格与权限工作流落地

权限模型、状态机与工作流引擎是业务系统设计中的基础构件:前者通过功能权限与数据权限分层控制访问边界,后者以节点、连线、实例和任务描述业务流转,并用状态聚合保证主从数据一致。把这些通用机制落到实验室信息管理系统(LIMS)中,会直接影响需求规格说明书能否拆成可验收条目,也关系到样品登录、结果录入、审核审批、设备物资流程和自动排程的交付质量。围绕群组权限、逻辑删除、编码规则并发安全与需求追溯表开展工程化设计,可减少返工并提升验收可追溯性。

weixin_30047059的博客 249

数据服务共享平台落地实践:目录、权限与限流

在企业数据服务化过程中,如何将散落的表升级为可治理的API服务?数据服务共享平台是连接数据生产与消费的关键基础设施,其核心在于通过服务目录实现元数据注册与发现,并配套完整的发布链路、鉴权策略和审计机制。文章从平台定位出发,讲解服务目录的元数据建模、三种建设模式、血缘登记,以及API发布后如何通过app_key签名、行级权限和脱敏策略保障数据安全。针对多方共享场景,还梳理了限流、缓存与超时调优的工程参数,最后给出向决策者汇报的PPT组织建议。本文结合实践,提供一套从0到1构建数据服务共享平台的落地参考。

weixin_29096377的博客 311

MySQL开发技巧——查询、索引和完整性

在列上创建了索引之后,查找数据是可以直接根据该列上的索引找到对应行的位置,从而快速找到数据。在列上创建了索引之后,查找数据是可以直接根据该列上的索引找到对应行的位置,从而快速找到数据。比如查询每个雇员的薪水情况,但是我们要返回雇员的姓名,而在sal表中没有雇员姓名,这个时候就需要我们通过员工编号连接emp和sal两张表。视图也是为了实现多样地查看表中的数据,比如限制财务部的经理只能看到财务部的信息。经理觉得查找数据的速度偏慢、精度较低,这个时候,你需要创建索引来使查询的速度更快,使用完整性来提高查询精度。

weixin_51970555的博客 1万+

Fine-BI认证考试题库本质:能力边界验证地图

Fine-BI认证考试已从知识记忆转向平台能力实战验证,核心考察在真实约束(界面路径、数据权限、性能阈值)下组合标准功能解决业务分析问题的能力。其底层逻辑基于平台架构、数据建模、仪表板交互、高级计算与系统运维五大能力域,每道题实为一个可验证的功能契约——如字段映射规则、下钻层级限制、连接池参数耦合等。技术价值在于驱动考生建立‘题干→API行为→版本适配→失效场景’的闭环认知,广泛应用于企业BI能力建设、内部培训体系搭建及平台升级健康度自检。本文聚焦Fine-BI考试题库的工程化解读与实操验证方法。

weixin_29056101的博客 221

Flash 会表数据 之oracle 10g

界面开发人员报有很多重复数据在用户权限表。然后我删除了表数据delete 方式,修改了对应的存储过程使之不重复!后来发现 重新拉回的数据没权限。 只好闪回到今天凌晨了!  SQL> ALTER TABLE BA.T_POWER_ADMIN ENABLE ROW MOVEMENT; Table altered SQL> flashback table ba.t_Pow

海鲨数据库架构师 1777

BSW:MemMap模块配置及使用

(内存映射(MemMap)模块用于通过内存映射文件将代码和数据映射到特定的内存部分。MemMap生成特定的头文件,其中包含为MemorySection元素和编译器特定指令定义的内存映射预处理器。上面是比较官方的回答,说人话就是把数据和代码放在ECU内指定的地址。初级应用:软件中的bss,data,rodata,code,text,段需要在memory layout中划分具体的物理地址,对于多核系统,要将执行的数据和代码放在目标核的RAM和ROM。

Forever_Oct的博客 3673

Vivado与Vscode无缝集成:高效Verilog开发环境搭建指南

本文详细介绍了如何将Vivado与Vscode无缝集成,打造高效的Verilog开发环境。通过替换Vivado默认编辑器为Vscode,配置必备插件和语法检查工具,开发者可以大幅提升FPGA项目的编码效率。文章还提供了代码片段、Testbench自动生成等高级技巧,帮助开发者快速上手这一集成方案。

weixin_33737774的博客 493

3大核心赋能:芋道RuoYi-Vue Pro企业级开发平台全栈实施指南

作为基于Spring Boot 2.7与Vue3构建的企业级前后端分离快速开发平台,芋道RuoYi-Vue Pro通过前后端分离架构实现技术解耦,提供微服务部署能力支持业务弹性扩展,并内置成熟的多租户解决方案满足SaaS化需求。本文将从价值定位、环境评估、实施路径、能力拓展、问题解决到实践升华六个维度,全面解析如何通过该平台实现企业应用的高效开发与部署。 ## 一、价值定位:三维价值模型解析

gitblog_01057的博客 1021

ubuntu安装XXX包时出现(= 20.0.8-0ubuntu1~18.04.1) but it is not going to be installed

安装mujoco_py时,最后一步尝试 import mujoco_py 时出现报错 esashim.c:1:10: fatal error: GL/osmesa.h: No such file or directory 1 | #include <GL/osmesa.h> | ^~~~~~~~~~~~~ compilation terminated. 在https://github.com/openai/mujoco-py#ubuntu-ins

dealexce的博客 1793

卖家工具简述

卖家工具 来自http://open.taobao.com/dev/index.php/%E5%8D%96%E5%AE%B6%E5%B7%A5%E5%85%B7 目录 [隐藏] 1 商品管理 1.1 商品管理介绍 1.2 场景描述 1.3 业务规则 1.4 调用API 1.5 一、搜索产品信息 1.6 二、发布产品 1.7 三、发布商品 2 库存管理 ...

renzhelife 147

从基础知识到PCB设计,打造全能硬件工程师

成为一名出色的硬件工程师需要在多个领域建立坚实的基础。从硬件基础知识、元器件学习、模拟电子电路到PCB设计,以及数字电子电路与通信,每个方面都是构建全面硬件工程师技能集的重要组成部分。通过深入学习和实践这些领域,你将能够在硬件工程领域中取得更多的成就。

weixin_46969363的博客 2717

从Datasheet到可用的Verilog模块:手把手教你为N25Q128 SPI Flash写状态机驱动

本文详细介绍了如何从Datasheet到实现可用的Verilog模块,手把手教你为N25Q128 SPI Flash编写状态机驱动。文章涵盖SPI Flash的核心工作机制、数据手册解析方法、Verilog状态机设计实践以及调试与性能优化技巧,特别适合FPGA开发者和硬件设计工程师参考。

weixin_30596023的博客 175

Linux 的用户和权限

这里本人是使用Xshell 登录的  刚开始 使用root 权限登录  登录之后直接 创建账号 密码 1) 直接输入指令  useradd + 用户名  例如  useradd  rhm01 2)  useradd lyz02    我这里是创建了两个账号 3)  passwd lyz01   设置密码   输入第一遍如果简单的话 会提示简单,你不用管 直接在输入一边 第二次就会更新成...

逆流而上Mr李 1087

深入解析fio Benchmark测试:从源码到实践

本文深入解析fio Benchmark测试工具,从入门指南到源码架构分析,详细介绍了其核心模块、关键数据结构和I/O处理机制。通过实战案例展示如何优化存储性能测试,包括内存对齐、多线程调优等技巧,帮助开发者充分利用fio进行精准的存储性能评估。

weixin_42563415的博客 206
上一篇: Python学习002——模拟客服与客户的聊天通讯功能
下一篇: 学习笔记019——Ubuntu部署tomcat
须晴日.
博客等级 码龄5年 595粉丝 103原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值