2025-11-27 15:26:59 +08:00
|
|
|
|
# 从属关系管理系统能力确认
|
|
|
|
|
|
|
|
|
|
|
|
## 当前系统架构对从属关系管理的支持
|
|
|
|
|
|
|
|
|
|
|
|
### ✅ 已具备的功能
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 树形组织架构存储
|
|
|
|
|
|
```sql
|
|
|
|
|
|
service_departments 表结构:
|
|
|
|
|
|
- id: 部门唯一ID
|
|
|
|
|
|
- name: 部门名称
|
|
|
|
|
|
- parent_id: 上级部门ID (可为空,表示根级)
|
|
|
|
|
|
- grade: 权限等级 (90/80/70/60)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 层级查询功能
|
|
|
|
|
|
- `_get_department_level(department_id)` - 获取部门层级(根节点为0)
|
|
|
|
|
|
- `_calculate_grade_by_parent(parent_id)` - 根据父节点计算权限等级
|
|
|
|
|
|
- 树形结构遍历 (`build_service_department_tree()`)
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 关系映射
|
|
|
|
|
|
- `parentMap[nodeId]` - 记录每个节点的父节点
|
|
|
|
|
|
- `nodeMap[nodeId]` - 记录每个节点的完整信息
|
|
|
|
|
|
- 前端 `flattenTree()` - 递归计算每个节点的层级
|
|
|
|
|
|
|
|
|
|
|
|
### 🔧 实现"看到下级部门文件"功能需要新增的函数
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 获取部门的所有祖先节点 (Ancestors)
|
|
|
|
|
|
```python
|
|
|
|
|
|
def get_department_ancestors(department_id: str) -> List[str]:
|
|
|
|
|
|
"""获取指定部门的所有上级部门ID列表(从当前部门到根级)"""
|
|
|
|
|
|
ancestors = []
|
|
|
|
|
|
current_id = department_id
|
|
|
|
|
|
while current_id:
|
|
|
|
|
|
parent_id = get_parent_department_id(current_id)
|
|
|
|
|
|
if parent_id:
|
|
|
|
|
|
ancestors.append(parent_id)
|
|
|
|
|
|
current_id = parent_id
|
|
|
|
|
|
else:
|
|
|
|
|
|
break
|
|
|
|
|
|
return ancestors
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 获取部门的所有子孙节点 (Descendants)
|
|
|
|
|
|
```python
|
|
|
|
|
|
def get_department_descendants(department_id: str) -> List[str]:
|
|
|
|
|
|
"""获取指定部门的所有下级部门ID列表(包括所有层级的子部门)"""
|
|
|
|
|
|
descendants = []
|
|
|
|
|
|
|
|
|
|
|
|
def collect_descendants(dept_id: str):
|
|
|
|
|
|
children = get_child_departments(dept_id)
|
|
|
|
|
|
for child in children:
|
|
|
|
|
|
descendants.append(child['id'])
|
|
|
|
|
|
collect_descendants(child['id'])
|
|
|
|
|
|
|
|
|
|
|
|
collect_descendants(department_id)
|
|
|
|
|
|
return descendants
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 权限检查函数
|
|
|
|
|
|
```python
|
|
|
|
|
|
def can_access_department(current_user_dept_id: str, target_dept_id: str, user_grade: int) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
检查当前用户是否可以访问目标部门的文件
|
|
|
|
|
|
|
|
|
|
|
|
规则:
|
|
|
|
|
|
- 超管 (grade >= 90) 可以访问所有部门
|
|
|
|
|
|
- 普通用户只能访问下级部门(不能访问同级部门)
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
current_user_dept_id: 当前用户的部门ID
|
|
|
|
|
|
target_dept_id: 目标部门ID(文件所属部门)
|
|
|
|
|
|
user_grade: 当前用户的权限等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: True=可以访问, False=不能访问
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 超管可以访问所有部门
|
|
|
|
|
|
if user_grade >= 90:
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
# 如果是同一个部门,可以访问
|
|
|
|
|
|
if current_user_dept_id == target_dept_id:
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
# 获取当前用户部门的所有下级部门
|
|
|
|
|
|
accessible_depts = get_department_descendants(current_user_dept_id)
|
|
|
|
|
|
|
|
|
|
|
|
# 检查目标部门是否在下级部门列表中
|
|
|
|
|
|
return target_dept_id in accessible_depts
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 数据库表结构建议
|
|
|
|
|
|
|
|
|
|
|
|
### 文档/文件表设计
|
|
|
|
|
|
```sql
|
|
|
|
|
|
CREATE TABLE documents (
|
|
|
|
|
|
id UUID PRIMARY KEY,
|
|
|
|
|
|
title VARCHAR NOT NULL,
|
|
|
|
|
|
content TEXT,
|
|
|
|
|
|
department_id UUID REFERENCES service_departments(id), -- 文档所属部门
|
|
|
|
|
|
created_by UUID REFERENCES service_departments(id), -- 创建人部门
|
|
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- 部门ID索引
|
|
|
|
|
|
CREATE INDEX idx_documents_department ON documents(department_id);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 查询示例
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- 获取当前用户可访问的所有文档
|
|
|
|
|
|
SELECT d.*
|
|
|
|
|
|
FROM documents d
|
|
|
|
|
|
WHERE can_access_department(:current_user_dept_id, d.department_id, :user_grade)
|
|
|
|
|
|
ORDER BY d.created_at DESC;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 实现步骤
|
|
|
|
|
|
|
|
|
|
|
|
### 第一阶段:后端函数实现
|
|
|
|
|
|
1. ✅ 完成:`get_department_level()` - 获取部门层级
|
|
|
|
|
|
2. ✅ 完成:`build_service_department_tree()` - 构建树形结构
|
|
|
|
|
|
3. 🔄 新增:`get_department_ancestors()` - 获取祖先节点
|
|
|
|
|
|
4. 🔄 新增:`get_department_descendants()` - 获取子孙节点
|
|
|
|
|
|
5. 🔄 新增:`can_access_department()` - 权限检查
|
|
|
|
|
|
|
|
|
|
|
|
### 第二阶段:文档管理API
|
|
|
|
|
|
1. 🔄 新增:`POST /api/documents` - 创建文档(自动关联部门)
|
|
|
|
|
|
2. 🔄 新增:`GET /api/documents` - 查询可访问的文档(带权限过滤)
|
|
|
|
|
|
3. 🔄 新增:`GET /api/documents/{id}` - 获取单个文档(权限检查)
|
|
|
|
|
|
4. 🔄 新增:`PUT /api/documents/{id}` - 更新文档(权限检查)
|
|
|
|
|
|
5. 🔄 新增:`DELETE /api/documents/{id}` - 删除文档(权限检查)
|
|
|
|
|
|
|
|
|
|
|
|
### 第三阶段:前端界面
|
|
|
|
|
|
1. 🔄 新增:文档列表页面(只显示可访问的文档)
|
|
|
|
|
|
2. 🔄 新增:文档上传/创建页面
|
|
|
|
|
|
3. 🔄 新增:文档查看/编辑页面
|
|
|
|
|
|
4. 🔄 新增:部门文档统计展示
|
|
|
|
|
|
|
|
|
|
|
|
## 权限示例场景
|
|
|
|
|
|
|
|
|
|
|
|
### 场景1:超管访问
|
|
|
|
|
|
- 用户:A市服务部门(grade=90)
|
|
|
|
|
|
- 可访问:A市、禅城区、南海区...所有部门的文件
|
|
|
|
|
|
- 结果:✅ 可以
|
|
|
|
|
|
|
|
|
|
|
|
### 场景2:二级部门访问下级
|
|
|
|
|
|
- 用户:禅城区服务部门(grade=80)
|
|
|
|
|
|
- 目标文件:禅城区下级部门(如:张槎分局)
|
|
|
|
|
|
- 可访问:禅城区 + 所有下级部门
|
|
|
|
|
|
- 结果:✅ 可以
|
|
|
|
|
|
|
|
|
|
|
|
### 场景3:二级部门访问同级
|
|
|
|
|
|
- 用户:禅城区服务部门(grade=80)
|
|
|
|
|
|
- 目标文件:南海区服务部门(同级)
|
|
|
|
|
|
- 可访问:禅城区 + 所有下级部门
|
|
|
|
|
|
- 结果:❌ 不可以(同级部门)
|
|
|
|
|
|
|
|
|
|
|
|
### 场景4:三级部门访问
|
|
|
|
|
|
- 用户:禅城区张槎分局(grade=70)
|
|
|
|
|
|
- 目标文件:禅城区祖庙分局(同级)
|
|
|
|
|
|
- 可访问:张槎分局 + 所有下级部门
|
|
|
|
|
|
- 结果:❌ 不可以(同级部门)
|
|
|
|
|
|
|
|
|
|
|
|
### 场景5:三级部门访问下级
|
|
|
|
|
|
- 用户:禅城区张槎分局(grade=70)
|
|
|
|
|
|
- 目标文件:张槎分局下级部门
|
|
|
|
|
|
- 可访问:张槎分局 + 所有下级部门
|
|
|
|
|
|
- 结果:✅ 可以
|
|
|
|
|
|
|
|
|
|
|
|
## 总结
|
|
|
|
|
|
|
|
|
|
|
|
### 当前系统已具备的基础设施
|
|
|
|
|
|
✅ 完整的树形组织架构存储
|
|
|
|
|
|
✅ 层级关系查询功能
|
|
|
|
|
|
✅ 权限等级系统
|
|
|
|
|
|
✅ 前后端权限传递机制
|
|
|
|
|
|
|
|
|
|
|
|
### 需要的开发工作
|
|
|
|
|
|
🔄 新增3-4个核心权限检查函数
|
|
|
|
|
|
🔄 实现文档/文件管理API
|
|
|
|
|
|
🔄 前端文档管理界面
|
|
|
|
|
|
|
|
|
|
|
|
### 结论
|
|
|
|
|
|
**当前系统完全支持实现"除了超管,其他人看不到同级部门的文件,能看到下级部门的文件"的功能**。
|
|
|
|
|
|
|
|
|
|
|
|
现有架构提供了从属关系管理的所有基础设施,只需要:
|
|
|
|
|
|
1. 新增获取子孙节点的函数
|
|
|
|
|
|
2. 实现权限检查逻辑
|
|
|
|
|
|
3. 将权限检查集成到文档查询中
|
|
|
|
|
|
|
|
|
|
|
|
整个功能预计需要新增约200-300行Python代码(后端)和相应前端代码。
|