当前位置: 首页 > 知识库问答 >
问题:

sql - 目录要加权限控制,SQL得怎么写?

程城
2024-07-29

项目有个目录,需要加权限,页面上只渲染当前用户拥有的"巡检方案"所在的目录节点(子节点及它以上的所有父节点)。这是我渲染的目录所有的节点。各位大佬,请问sql该怎么写呀?
注:目录结构是动态的,不是固定的,后面公司的人可能会再加子节点

集团
    潮州
        工厂1
            办公楼
                男洗手间巡检方案
                杂物间巡检方案
            食堂
        工厂2
            技术楼
            食堂
    昆山
        工厂1
            办公楼
            研发楼

现在要加上权限控制,假如我拥有 "潮州 -> 工厂1 -> 办公楼" 下的巡检方案, 那我进来目录只渲染这样就好

集团
    潮州
        工厂1
            办公楼
                男洗手间巡检方案
                杂物间巡检方案

目录表在数据库里结构是
id, parent_id, name

权限表的是
id directory_id(目录的主键) user_id

我程序查出来的数据明细大致是, 然后用递归的方法生成前端目录需要的结构,返回到前端渲染。
1 0 集团
2 1 潮州
3 1 昆山
4 2 工厂1
5 4 办公楼
...

前端我是用element-ui的el-tree,所以结构是这样的。数据库查出来的明细,也希望按这个上面的明细一样。

[
    'label': '集团',
    'id': 0,
    children:[
        ...
    ]
]

共有1个答案

上官自明
2024-07-29

从权限表中找到当前用户拥有权限的所有目录节点及其所有父节点,然后根据这些数据生成前端需要的树状结构。
directory 表结构:

CREATE TABLE directory (
    id INT PRIMARY KEY,
    parent_id INT,
    name VARCHAR(255)
);

permissions 表结构:

CREATE TABLE permissions (
    id INT PRIMARY KEY,
    directory_id INT,
    user_id INT
);

当前用户的 user_id 为 :user_id。首先,我们需要递归地找到当前用户拥有权限的所有目录节点及其所有父节点。

WITH RECURSIVE DirectoryTree AS (
    -- 获取当前用户有权限的目录节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN permissions p ON d.id = p.directory_id
    WHERE p.user_id = :user_id
    UNION ALL
    -- 递归地获取父节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN DirectoryTree dt ON d.id = dt.parent_id
)
SELECT DISTINCT id, parent_id, name
FROM DirectoryTree;

不需要再建一个表。WITH RECURSIVE 是一个CTE(Common Table Expression),用于临时生成一个结果集,这个结果集可以在后续的SELECT查询中使用。

下面是完整的SQL查询语句,适用于SQL Server,来获取当前用户拥有权限的所有目录节点及其所有父节点:

-- 定义用户ID
DECLARE @user_id INT = 123; -- 替换成实际的用户ID

-- 递归CTE,找到所有有权限的节点及其父节点
WITH DirectoryTree AS (
    -- 获取当前用户有权限的目录节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN permissions p ON d.id = p.directory_id
    WHERE p.user_id = @user_id
    UNION ALL
    -- 递归地获取父节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN DirectoryTree dt ON d.id = dt.parent_id
)
-- 获取去重后的结果
SELECT DISTINCT id, parent_id, name
FROM DirectoryTree;

DECLARE @user_id INT = 123;:定义当前用户的ID,你需要将 123 替换为实际的用户ID。
WITH DirectoryTree AS 定义了一个递归CTE,首先从permissions表中获取当前用户有权限的目录节点。
UNION ALL 用于递归地获取这些目录节点的所有父节点。
最终的 SELECT DISTINCT 去重,得到所有相关的目录节点。
这个查询将返回当前用户有权限的所有目录节点及其所有父节点,你可以根据这些数据生成前端需要的树状结构。

在前端使用 element-ui 的 el-tree 组件时,可以将这个查询结果转换成适合 el-tree 组件的格式。

 类似资料:
  • CONTROLLING FILE AND DIRECTORY PERMISSIONS 并非操作系统的每个用户都应具有相同级别的文件和目录访问权限。与任何专业操作系统一样,Linux 具有保护文件和目录访问的方法。系统允许系统管理员(root 用户或文件所有者)通过赋予用户读取,写入或执行文件的权限来保护其文件免受不必要的访问或篡改。对于每个文件和目录,我们可以为文件所有者、特定用户组以及所有其他用

  • 本文向大家介绍vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?相关面试题,主要包含被问及vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?时的应答技巧和注意事项,需要的朋友参考一下 可以通过指令去做 Vue.directive('hasPermission', { bind(el, binding, vnode) { const permissions = vnode.con

  • 本页内容包括: 模块和源文件 访问级别 访问级别的使用原则 默认访问级别 单目标应用程序的访问级别 Framework的访问级别 访问控制语法 自定义类型 元组类型 函数类型 枚举类型 原始值和关联值 嵌套类型 子类 常量、变量、属性、下标 Getter和Setter 初始化 默认初始化方法 结构体的默认成员初始化方法 协议 协议继承 协议一致性 扩展 协议的扩展 泛型 类型别名 访问控制可以限定

  • 数据只能由所属的智能合约读写,智能合约默认无法读写其他智能合约的数据。 为了方便用户操作,使用智能合约的私有对象作为数据对象,系统通过反射,获取私有对象所属的智能合约和对象名。其他智能合约无法创建和获取该智能合约的私有对象,就无法读写对应的数据。 如果智能合约希望自己的数据能够被其他智能合约读写,需要智能合约主动提供数据操作接口,其他智能合约通过引用该合约,调用相应接口,从而操作相应数据。 智能合

  • 本文向大家介绍asp.net core项目mvc权限控制:分配权限,包括了asp.net core项目mvc权限控制:分配权限的使用技巧和注意事项,需要的朋友参考一下 前面的文章介绍了如何进行权限控制,即访问控制器或者方法的时候,要求当前用户必须具备特定的权限,但是如何在程序中进行权限的分配呢?下面就介绍下如何利用Microsoft.AspNetCore.Identity.EntityFramew

  • 这是记录用户下载的表,想统计表内每个文章被下载了几次,也就是需要拿到一个文章ID,然后再求下这个ID出现的次数。