菜单栏不是超管角色的时候显示有问题
分享
收藏
评论
作者 🐼
gd
-
当不是超管用户的时候显示不出来 我的菜单栏有一级下面有几个二级菜单这样子的
你好!这是一个非常典型的**基于角色/权限控制侧边栏渲染**的问题。通常是因为后端接口过滤逻辑写得太死,或前端二次过滤时漏掉了普通角色的权限匹配。我们可以按以下步骤快速定位并修复:
### 🔍 常见原因
1. **后端查询硬编码**:例如 `WHERE role = 'super_admin'` 或未正确处理角色继承关系
2. **前端逻辑缺陷**:使用了 `v-if="role === 'super_admin' ? menu : []"` 类写法,导致非超管直接清空数据
3. **权限未分配**:普通用户角色没有绑定任何菜单对应的权限标识(permission/role)
4. **父子级联丢失**:二级菜单依赖一级菜单的权限校验,父级不通过导致整个树形结构被隐藏
---
### 🛠️ 排查与修复步骤
#### ✅ 第一步:核对接口返回数据
打开浏览器开发者工具 → `Network` → 筛选菜单请求,对比**超管账号**和**普通账号**返回的 JSON:
- 如果非超管返回 `[]`、`null` 或缺少 `children`,说明是**后端数据层**问题。
- 如果数据正常但前端不显示,说明是**前端渲染/过滤逻辑**问题。
#### ✅ 第二步:修正后端获取逻辑(推荐统一走权限拦截)
不要写 `if ($role === 'super_admin') { return all; } else { return filter; }`,而是**统一查询当前用户有权限的菜单**。以下是 PHP/Laravel 常见实现参考(请按需替换表名/字段名):
```php
// 假设你的菜单表叫 menus,关联权限表 perms 或使用了 spatie/laravel-permission
public function getUserMenus(\App\Models\User $user)
{
$menuQuery = \App\Models\Menu::query()
->where(function ($q) use ($user) {
// 1. 超管直接查全部(性能优化)
if ($user->hasRole('super_admin')) {
$q->whereRaw('1=1');
} else {
// 2. 普通用户:通过角色关联的权限匹配菜单
$q->whereHas('permissions', fn($sub) => $sub->whereIn('name', $user->getAllPermissions()->pluck('name')));
}
})
->with(['children.permissions']) // 加载二级菜单及权限
->orderBy('sort')
->get();
// 清理掉无权限的子菜单(防前端显示乱序)
return $menuQuery->map(function ($menu) use ($user) {
$menu->children = $menu->children->filter(fn($child) => $user->can($child->permission ?? ''));
return $menu;
});
}
```
> 💡 如果你没使用第三方权限包,也可以用自定义中间表:`user_roles`, `role_permissions`, `permissions` 联动查询,核心思想不变:**让数据层自己过滤,前端只负责渲染**。
#### ✅ 第三步:前端改造建议
- ❌ 避免:`const menus = role === 'super_admin' ? allMenus : [];`
- ✅ 推荐:直接接收后端返回的结构化数据,用组件递归渲染:
```vue
<template>
<el-menu v-if="menus.length">
<sidebar-item
v-for="menu in menus"
:key="menu.id"
:item="menu"
/>
</el-menu>
<div v-else class="empty-tip">暂无可用菜单,请联系管理员分配权限</div>
</template>
```
---
### 🐞 快速调试技巧
在后端接口临时加入日志,一眼看清差异:
```php
Log::channel('daily')->info('Menu Filter Diff', [
'user_id' => $user->id,
'roles' => $user->roles->pluck('name')->toArray(),
'perm_count' => $user->getAllPermissions()->count(),
'returned_ids' => $this->getUserMenus($user)->pluck('id')->toArray(),
]);
```
---
📌 **为了给你最精准的代码,请补充:**
1. 你使用的技术栈?(如:Laravel + Vue3 / ThinkPHP / 自研框架)
2. 角色权限是如何设计的?(原生中间表 / 用了 `spatie/laravel-permission` / 其他?)
3. 菜单数据是从哪个 Controller/Service 返回给前端的?
提供后我可以直接给你适配你项目的完整文件代码!祝你顺利解决,随时告诉我进展 🚀