From b35f603399d6f1cd12d66aaa26ad7ee1ceaf454a Mon Sep 17 00:00:00 2001 From: DSQ Date: Wed, 11 Mar 2026 15:46:21 +0800 Subject: [PATCH 1/4] [0.2.7.2][ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7e48f4..56e8d8b 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -python manage.py shell -c "from elastic.es_connect import create_index_with_mapping; create_index_with_mapping()" \ No newline at end of file +python manage.py shell -c "from elastic.es_connect import create_index_with_mapping; create_index_with_mapping()" From ebe88d93c9a6095fa5fe944ffe9e78ba78784f3d Mon Sep 17 00:00:00 2001 From: spdis Date: Thu, 12 Mar 2026 21:21:30 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E4=BA=8E?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6=E7=B3=BB=E7=BB=9F=E7=9A=84?= =?UTF-8?q?=E8=A7=A3=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/README.md b/README.md index 56e8d8b..5f31582 100644 --- a/README.md +++ b/README.md @@ -1 +1,196 @@ +# 多级权限控制数据结构说明 + +## 核心概念 + +该设计通过 **关键字匹配(Keyword Matching)** 实现数据行级权限控制,适用于学校、企业等层级组织架构场景。 + +### 字段定义 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `key` | `KeywordField(multi=True)` | **身份标识关键字** - 表示用户所属的层级/组织,用于匹配"自己的数据" | +| `manage_key` | `KeywordField(multi=True)` | **管理范围关键字** - 表示用户能管理的数据范围,用于匹配"管辖范围内的数据" | + +--- + +## 权限模型图解 + +``` +数据权限 = (数据.key ∩ 用户.key) ∪ (数据.key ∩ 用户.manage_key) + +解释: +- 用户能看到的数据 = 自己的数据 OR 管辖范围内的数据 +- 两者都满足"用户权限"(非管理员),只是数据范围不同 +``` + +--- + +## 具体场景示例 + +### 场景1:学生视角 + +**用户:学生A(2024届人工智能1班)** + +```json +{ + "name": "张三", + "role": "学生", + "key": [ + "2024届人工智能1班", // 班级(最细粒度) + "2024届", // 年级 + "计算机与人工智能学院" // 学院 + ], + "manage_key": [] // 学生没有管理权限 +} +``` + +**数据匹配逻辑:** +- 查询获奖数据时,系统查找 `key` 包含 `"2024届人工智能1班"` 的数据 +- 结果:只能看到自己的获奖记录 + +--- + +### 场景2:班导师视角 + +**用户:班导师B(负责2024届人工智能1班)** + +```json +{ + "name": "李老师", + "role": "班导师", + "key": [ + "计算机与人工智能学院" // 所属学院 + ], + "manage_key": [ + "2024届人工智能1班" // 管理的班级 + ] +} +``` + +**数据匹配逻辑:** +- 查询时匹配:`key` 包含 `"计算机与人工智能学院"` **OR** `key` 包含 `"2024届人工智能1班"` +- 结果:可以看到 + 1. 学院层级的公共数据(通过 `key` 匹配) + 2. 人工智能1班所有学生的获奖数据(通过 `manage_key` 匹配) + +--- + +### 场景3:扩展案例 - 多级管理员 + +**用户:学院教务C(管理学院所有班级)** + +```json +{ + "name": "王教务", + "role": "教务", + "key": [ + "计算机与人工智能学院" + ], + "manage_key": [ + "2024届人工智能1班", + "2024届人工智能2班", + "2023届软件工程1班", + "计算机与人工智能学院" // 管理整个学院 + ] +} +``` + +**权限效果:** +- 可以查看学院内所有班级的获奖数据 +- 仍然只是"用户权限",只是管理范围更大 + +--- + +### 场景4:跨角色对比 + +| 角色 | key | manage_key | 可见数据范围 | +|------|-----|------------|-------------| +| **学生A** | 班级、年级、学院 | - | 仅自己的记录 | +| **班导师B** | 学院 | 班级 | 所带班级的全部记录 | +| **辅导员** | 学院 | 年级 | 整个年级的全部记录 | +| **院领导** | 学院 | 学院 | 整个学院的全部记录 | +| **校管理员** | 学校 | 学校 | 全校数据(真正的admin) | + +--- + +## 数据结构存储示例 + +### 用户表(User Index) + +```json +{ + "user_id": "stu_2024001", + "name": "张三", + "key": ["2024届人工智能1班", "2024届", "计算机与人工智能学院"], + "manage_key": [], + "role": "student" +} +``` + +```json +{ + "user_id": "tch_10086", + "name": "李老师", + "key": ["计算机与人工智能学院"], + "manage_key": ["2024届人工智能1班"], + "role": "advisor" +} +``` + +### 数据表(Award Index) + +```json +{ + "award_id": "awd_001", + "title": "校级编程大赛一等奖", + "student_name": "张三", + "key": ["2024届人工智能1班", "2024届", "计算机与人工智能学院"], // 所属层级 + "created_by": "stu_2024001" +} +``` + +--- + +## 查询逻辑伪代码 + +```python +def get_visible_data(current_user): + """ + 获取当前用户可见的数据 + """ + query = { + "bool": { + "should": [ + # 条件1:数据的关键字与用户的key有交集(自己的数据) + { + "terms": { + "key": current_user.key + } + }, + # 条件2:数据的关键字与用户的manage_key有交集(管辖的数据) + { + "terms": { + "key": current_user.manage_key + } + } + ], + "minimum_should_match": 1 + } + } + + return es.search(index="awards", body=query) +``` + +--- + +## 设计优势 + +1. **扁平化权限**:不需要复杂的角色表(RBAC),通过关键字即可控制权限 +2. **灵活扩展**:新增班级/年级只需添加关键字,无需修改权限架构 +3. **层级继承**:数据自带完整层级路径(班级→年级→学院),支持多级查询 +4. **细粒度控制**:可以精确到班级级别,也可以放宽到学院级别 + + + +生产环境用于创建数据库结构的临时命令: python manage.py shell -c "from elastic.es_connect import create_index_with_mapping; create_index_with_mapping()" From 4d83864e9fe8e10bd233fa2a0ecf08d70fe5ec95 Mon Sep 17 00:00:00 2001 From: spdis Date: Thu, 12 Mar 2026 21:28:48 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f31582..3c3acb6 100644 --- a/README.md +++ b/README.md @@ -105,11 +105,11 @@ | 角色 | key | manage_key | 可见数据范围 | |------|-----|------------|-------------| -| **学生A** | 班级、年级、学院 | - | 仅自己的记录 | +| **学生A** | 班级、年级、学院、学校 | - | 仅自己的记录 | | **班导师B** | 学院 | 班级 | 所带班级的全部记录 | | **辅导员** | 学院 | 年级 | 整个年级的全部记录 | | **院领导** | 学院 | 学院 | 整个学院的全部记录 | -| **校管理员** | 学校 | 学校 | 全校数据(真正的admin) | +| **校管理员** | 学校 | 学院 | 全校数据 | --- From e05791e52f718ad2f61b815ce21ddc6a49d6be28 Mon Sep 17 00:00:00 2001 From: spdis Date: Thu, 12 Mar 2026 21:31:59 +0800 Subject: [PATCH 4/4] =?UTF-8?q?Revert=20"=E6=9B=B4=E6=96=B0=20README.md"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4d83864e9fe8e10bd233fa2a0ecf08d70fe5ec95. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c3acb6..5f31582 100644 --- a/README.md +++ b/README.md @@ -105,11 +105,11 @@ | 角色 | key | manage_key | 可见数据范围 | |------|-----|------------|-------------| -| **学生A** | 班级、年级、学院、学校 | - | 仅自己的记录 | +| **学生A** | 班级、年级、学院 | - | 仅自己的记录 | | **班导师B** | 学院 | 班级 | 所带班级的全部记录 | | **辅导员** | 学院 | 年级 | 整个年级的全部记录 | | **院领导** | 学院 | 学院 | 整个学院的全部记录 | -| **校管理员** | 学校 | 学院 | 全校数据 | +| **校管理员** | 学校 | 学校 | 全校数据(真正的admin) | ---