137 lines
4.0 KiB
Markdown
137 lines
4.0 KiB
Markdown
:::tip 角色管理
|
|
角色是 RBAC 权限模型的核心,连接用户和菜单(权限)。通过为角色分配菜单权限,再将角色分配给用户,实现灵活的权限管理。
|
|
:::
|
|
|
|
## 模块结构
|
|
|
|
```
|
|
application/role/
|
|
├── models.py # 角色模型
|
|
├── forms.py # 表单验证
|
|
├── services.py # 业务逻辑层
|
|
├── views.py # 视图层
|
|
└── urls.py # 路由配置
|
|
|
|
application/role_menu/
|
|
├── models.py # 角色-菜单关联模型
|
|
├── services.py # 关联业务逻辑
|
|
└── urls.py # 路由配置
|
|
```
|
|
|
|
## 角色模型
|
|
|
|
```python
|
|
# application/role/models.py
|
|
from application.models import BaseModel
|
|
|
|
class Role(BaseModel):
|
|
"""角色模型类"""
|
|
class Meta:
|
|
db_table = 'django_role'
|
|
|
|
name = models.CharField(max_length=150, verbose_name='角色名称')
|
|
code = models.CharField(max_length=30, verbose_name='角色编码')
|
|
sort = models.IntegerField(default=0, verbose_name='角色排序')
|
|
note = models.CharField(max_length=255, null=True, blank=True, verbose_name='角色备注')
|
|
```
|
|
|
|
## 角色-菜单关联
|
|
|
|
角色与菜单通过 `django_role_menu` 关联表实现多对多关系:
|
|
|
|
```python
|
|
# application/role_menu/models.py
|
|
class RoleMenu(BaseModel):
|
|
"""角色菜单关联模型类"""
|
|
class Meta:
|
|
db_table = 'django_role_menu'
|
|
|
|
role_id = models.IntegerField(default=0, verbose_name='角色ID')
|
|
menu_id = models.IntegerField(default=0, verbose_name='菜单ID')
|
|
```
|
|
|
|
## 自定义 Service
|
|
|
|
角色模块使用自定义 service 函数,涉及唯一性校验、内置角色保护、关联数据清理等复杂逻辑:
|
|
|
|
```python
|
|
# application/role/services.py
|
|
def add_role(request):
|
|
data = parse_request_body(request)
|
|
form = RoleForm(data)
|
|
|
|
if not form.is_valid():
|
|
return R.failed(msg=regular.get_err(form))
|
|
|
|
# 唯一性校验
|
|
name = data.get('name')
|
|
code = data.get('code')
|
|
|
|
if Role.objects.filter(name=name, is_delete=False).exists():
|
|
return R.failed("角色名称不能重复")
|
|
if Role.objects.filter(code=code, is_delete=False).exists():
|
|
return R.failed("角色编码不能重复")
|
|
|
|
Role.objects.create(
|
|
name=name,
|
|
code=code,
|
|
sort=data.get('sort', 0),
|
|
note=data.get('note', ''),
|
|
create_user=get_realname(request)
|
|
)
|
|
return R.ok(msg="添加成功")
|
|
```
|
|
|
|
## 删除与缓存清理
|
|
|
|
角色删除需清理关联的用户角色和角色菜单数据:
|
|
|
|
```python
|
|
# application/role/services.py
|
|
def delete_role(request):
|
|
data = parse_request_body(request)
|
|
role_id = data.get('id')
|
|
|
|
role = Role.objects.filter(id=role_id, is_delete=False).first()
|
|
if not role:
|
|
return R.failed("记录不存在")
|
|
|
|
# 内置角色禁止删除
|
|
if role_id in BUILTIN_ROLE_IDS:
|
|
return R.failed("内置角色不允许删除")
|
|
|
|
# 软删除角色
|
|
role.is_delete = True
|
|
role.save()
|
|
|
|
# 清理关联数据
|
|
UserRole.objects.filter(role_id=role_id).delete()
|
|
RoleMenu.objects.filter(role_id=role_id).delete()
|
|
|
|
return R.ok(msg="删除成功")
|
|
```
|
|
|
|
## API 接口
|
|
|
|
| 接口 | 方法 | 权限节点 | 说明 |
|
|
|------|------|---------|------|
|
|
| `/role/page` | GET | `sys:role:page` | 角色分页列表 |
|
|
| `/role/list` | GET | `sys:role:list` | 角色列表(无分页) |
|
|
| `/role/detail/<int:role_id>` | GET | `sys:role:detail` | 角色详情 |
|
|
| `/role/add` | POST | `sys:role:add` | 新增角色 |
|
|
| `/role/update` | POST | `sys:role:update` | 编辑角色 |
|
|
| `/role/delete/<int:role_id>` | POST | `sys:role:delete` | 删除角色 |
|
|
| `/role/menu` | POST | `sys:role:auth` | 分配菜单权限 |
|
|
|
|
## 总结
|
|
|
|
角色管理模块具备以下特点:
|
|
|
|
```
|
|
1. RBAC 核心:连接用户和权限的桥梁
|
|
2. 双字段唯一性:name + code 均需唯一性校验
|
|
3. 内置角色保护:BUILTIN_ROLE_IDS 中的角色禁止删除
|
|
4. 级联清理:删除角色时清理 user_role / role_menu 关联
|
|
5. 灵活组合:一个角色可分配多个菜单,一个用户可拥有多个角色
|
|
```
|