Laravel-admin可通过扩展角色权限逻辑+菜单动态过滤实现按部门控制菜单可见性:需关联部门与用户/角色、为菜单添加department_scope标识,并重写菜单渲染逻辑过滤非所属部门菜单,同时必须配合后端行级权限校验确保安全。

Laravel-admin 本身不直接支持“按部门控制菜单可见性”,但可以通过扩展角色权限逻辑 + 菜单动态过滤的方式,实现部门级菜单可见范围划分。核心思路是:菜单显示与否,不只看用户是否有某个 permission,还要判断该菜单是否属于用户所在部门(或其可访问的部门)。
部门关联角色或用户
先建立部门(Department)模型,并与用户或角色关联:
- 方式一(推荐):在
User模型中添加department_id字段,同时支持多部门(如通过 pivot 表user_departments) - 方式二:在
Role模型中增加department_id,表示该角色默认只对某部门生效(适合部门职责隔离强的场景) - 确保登录用户能通过
auth()->user()->departments或类似方式获取所属部门集合
菜单注册时注入部门标识
在自定义菜单配置中,为每个菜单项添加 department_scope 字段(字符串或数组),标明适用部门:
'Users' => [
'icon' => 'fa-users',
'route' => 'admin.users.index',
'permission' => 'users.index',
'department_scope' => ['hr', 'it'], // 仅 hr 和 it 部门可见
],
'Finance Reports' => [
'icon' => 'fa-chart-line',
'route' => 'admin.finance.reports',
'permission' => 'finance.reports',
'department_scope' => ['finance'],
],
注意:该字段不参与 Laravel-admin 原生权限校验,仅作为后续过滤依据。
重写菜单渲染逻辑
覆盖默认菜单生成过程,在 app/Admin/Extensions/MenuFilter.php 中编写过滤器:
- 读取当前用户所属部门列表(如
auth()->user()->departmentSlugs()) - 遍历原始菜单结构,跳过
department_scope不为空且当前用户部门不在其中的项 - 保留无
department_scope的全局菜单(如 Dashboard、个人设置) - 将过滤后菜单传给视图,替代原
Admin::menu()输出
可在 app/Admin/bootstrap.php 或中间件中统一拦截并替换菜单数据源。
配合行级权限增强一致性
菜单可见 ≠ 数据可查。需同步控制后端数据访问:
- 在控制器中查询用户数据时,自动追加部门条件,例如:
where('department_id', auth()->user()->department_id) - 对跨部门操作(如 HR 查看全公司员工),通过额外权限标识(如
users.view.all)控制 - 避免仅靠菜单隐藏造成越权访问风险——菜单可见性只是前端体验优化,真实权限必须后端校验
不复杂但容易忽略


















