:::tip 菜单管理 菜单管理是 RBAC 权限系统的基础,负责管理系统的导航菜单和权限节点。支持目录/菜单(type=0)和权限按钮节点(type=1)两种类型,通过树形结构组织。 ::: ## 菜单类型 | type | 名称 | 说明 | 用途 | |------|------|------|------| | `0` | 目录/菜单 | 页面路由 | 前端侧边栏分组 + 路由生成 | | `1` | 节点 | 权限按钮 | 控制操作权限 | ## 菜单模型 ```python # 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 字典实现非递归树构建: ```python # 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 关联实现: ```python # 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] ``` ## API 接口 | 接口 | 方法 | 权限节点 | 说明 | |------|------|---------|------| | `/menu/list` | GET | `sys:menu:list` | 菜单列表 | | `/menu/detail/` | GET | `sys:menu:detail` | 菜单详情 | | `/menu/add` | POST | `sys:menu:add` | 新增菜单 | | `/menu/update` | POST | `sys:menu:update` | 编辑菜单 | | `/menu/delete/` | POST | `sys:menu:delete` | 删除菜单 | ## 总结 菜单管理模块具备以下特点: ``` 1. 树形结构:通过 parent_id 形成多级菜单树,非递归构建 2. 权限节点:type=1 按钮节点,sys:module:action 格式 3. 缓存联动:菜单增删改后清理权限缓存 4. 环路防护:编辑时检测父级不能是自身或下级 5. 级联删除:删除菜单时一并清理权限节点和 role_menu 关联 ```