# 6.3 菜单管理 :::tip 概述 菜单管理负责维护系统的菜单树和权限节点,是 RBAC 权限体系的基础数据。 ::: ## 模块特点 | 特性 | 说明 | |------|------| | 基类 | BaseLogic(系统共享,不隔离) | | 树形结构 | treeParentField='parent_id',支持树形列表 | | 菜单类型 | type: 0=目录/页面(可导航) 1=权限按钮(仅权限校验,不显示在菜单树) | ## API 接口 | 方法 | 路径 | 权限码 | 说明 | |------|------|--------|------| | GET | `/api/menu/list` | sys:menu:page | 树形列表 | | GET | `/api/menu/detail/:id` | sys:menu:detail | 详情 | | POST | `/api/menu/add` | sys:menu:add | 新增 | | PUT | `/api/menu/update` | sys:menu:update | 修改 | | DELETE | `/api/menu/delete/:id` | sys:menu:delete | 删除 | ## 菜单数据结构 ```json { "id": 100, "parentId": 0, "name": "系统管理", "type": 0, "path": "/system", "icon": "SettingOutlined", "sort": 10, "permission": "", "component": "", "target": 0, "hide": false, "children": [ { "id": 101, "parentId": 100, "name": "用户管理", "type": 1, "path": "/user", "component": "system/user/index", "permission": "sys:user:page", "children": [ { "id": 102, "parentId": 101, "name": "添加用户", "type": 2, "permission": "sys:user:add" } ] } ] } ``` ## 字段说明 | 字段 | 说明 | |------|------| | `type` | 0=目录 1=菜单 2=按钮 | | `path` | 路由路径 | | `component` | 前端组件路径(type=1 时必填) | | `permission` | 权限标识(type=1,2 时填写) | | `target` | 打开方式:0=内部 1=iframe 2=外链 | | `hide` | 是否隐藏 | ## 核心代码 ### Controller ```php // app/controller/MenuController.php class MenuController extends BaseController { protected MenuLogic $logic; protected function initialize(): void { $this->logic = new MenuLogic(); } // 树形列表(支持 status 参数过滤) #[Log('菜单管理-查询树形列表', Log::TYPE_QUERY)] #[Permission('sys:menu:page', '菜单列表')] public function list(): Json { $where = []; $status = $this->getParam('status'); if ($status !== null && $status !== '') { $where['status'] = $status; } return parent::_list($this->logic, $where); } #[Log('菜单管理-新增记录', Log::TYPE_ADD, '新增菜单:{name}')] #[Permission('sys:menu:add', '添加菜单')] public function add(): Json { return parent::_add($this->logic, $this->getJsonBody()); } #[Log('菜单管理-修改记录', Log::TYPE_UPDATE, '修改菜单ID:{id}')] #[Permission('sys:menu:update', '修改菜单')] public function update(): Json { $data = $this->getJsonBody(); $id = $data['id'] ?? 0; if (empty($id)) return $this->fail('缺少id参数'); return parent::_edit($this->logic, $id, $data); } #[Log('菜单管理-删除记录', Log::TYPE_DELETE, '删除菜单ID:{id}')] #[Permission('sys:menu:delete', '删除菜单')] public function delete(int $id): Json { return parent::_remove($this->logic, $id); } } ``` :::tip 菜单类型 菜单使用 `_list()` 而非 `_index()`,返回全量树形数据。`type` 字段区分:0=目录、1=菜单、2=按钮。前端只渲染 type=0 和 type=1 的节点。 ::: :::warning 删除前校验 删除菜单时,`MenuLogic::beforeDelete` 会检查是否存在子菜单(`think_menu` 中 `parent_id` 等于当前 ID 且未删除的记录),如有子菜单则抛出异常阻止删除。需先删除子菜单再删除父菜单。 :::