Become a sponsor

菜单管理
菜单管理是 RBAC 权限系统的基础,负责管理系统的导航菜单和权限节点。支持目录/菜单(type=0)和权限按钮节点(type=1)两种类型,通过树形结构组织。
| type | 名称 | 说明 | 用途 |
|---|---|---|---|
0 | 目录/菜单 | 页面路由 | 前端侧边栏分组 + 路由生成 |
1 | 节点 | 权限按钮 | 控制操作权限 |
# application/menu/models.py
from application.models import BaseModel
class Menu(BaseModel):
"""菜单模型类"""
class Meta:
db_table = 'django_menu'
name = models.CharField(max_length=150, verbose_name='菜单名称')
icon = models.CharField(max_length=50, null=True, blank=True, verbose_name='菜单图标')
parent_id = models.IntegerField(default=0, verbose_name='上级ID')
path = models.CharField(max_length=255, null=True, blank=True, verbose_name='菜单路径')
component = models.CharField(max_length=255, null=True, blank=True, verbose_name='菜单组件')
permission = models.CharField(max_length=150, null=True, blank=True, verbose_name='权限节点')
target = models.IntegerField(default=1, verbose_name='打开方式:0-组件 1-内链 2-外链')
type = models.IntegerField(default=0, verbose_name='菜单类型:0-菜单 1-节点')
status = models.IntegerField(default=0, verbose_name='菜单状态:0-正常 1-停用')
hide = models.IntegerField(default=1, verbose_name='是否可见:0-可见 1-不可见')
sort = models.IntegerField(default=0, verbose_name='排序')
note = models.CharField(max_length=255, null=True, blank=True, verbose_name='备注')权限节点采用 sys:module:action 三段式命名:
1 -> 查询(sys:{module}:page)
5 -> 添加(sys:{module}:add)
10 -> 修改(sys:{module}:update)
15 -> 删除(sys:{module}:delete)
20 -> 详情(sys:{module}:detail)
25 -> 设置状态(sys:{module}:status)
30 -> 批量删除(sys:{module}:batchDelete)使用 children_map 字典实现非递归树构建:
# application/menu/services.py
def get_tree(data, parent_id):
"""获取树状结构(非递归,children_map 分组)"""
children_map = {}
for item in data:
pid = item["parentId"]
if pid not in children_map:
children_map[pid] = []
children_map[pid].append(item)
def build(pid):
result = []
for item in children_map.get(pid, []):
item["children"] = build(item["id"])
result.append(item)
return result
return build(parent_id)权限查询通过 ORM 关联实现:
# application/menu/services.py
def get_user_permissions(user_id):
"""获取用户的权限节点列表"""
if user_id == 1:
# 超管拥有全部权限
menu_list = Menu.objects.filter(type=1, is_delete=False)
else:
# 通过 user -> role -> menu 关联查询
menu_list = Menu.objects.filter(
type=1,
is_delete=False,
status=0,
rolemenu__role__userrole__user_id=user_id,
rolemenu__role__is_delete=False,
).distinct()
return [item.permission for item in menu_list]| 接口 | 方法 | 权限节点 | 说明 |
|---|---|---|---|
/menu/list | GET | sys:menu:list | 菜单列表 |
/menu/detail/<int:menu_id> | GET | sys:menu:detail | 菜单详情 |
/menu/add | POST | sys:menu:add | 新增菜单 |
/menu/update | POST | sys:menu:update | 编辑菜单 |
/menu/delete/<int:menu_id> | POST | sys:menu:delete | 删除菜单 |
菜单管理模块具备以下特点:
1. 树形结构:通过 parent_id 形成多级菜单树,非递归构建
2. 权限节点:type=1 按钮节点,sys:module:action 格式
3. 缓存联动:菜单增删改后清理权限缓存
4. 环路防护:编辑时检测父级不能是自身或下级
5. 级联删除:删除菜单时一并清理权限节点和 role_menu 关联