otifsolutions / aclmenu
一个包含用户角色、权限、基于数据库的菜单项、权利和基于权限的菜单项的ACL菜单包
README
需求
PHP 5 > 5.3.0
Laravel > 5.0
如何安装库
通过Composer安装
使用Composer(推荐)
在项目的根目录中运行以下命令
composer require otifsolutions/aclmenu
使用方法
-
创建用户角色(通过 Seeder)
UserRole::updateOrCreate( ['id' => 1],[ 'name' => 'ADMIN' ]);
-
为创建的
UserRole
创建菜单项。$id = UserRole::Where(['name' => 'ADMIN'])->get('id'); MenuItem::updateOrCreate( ['id' => 1], [ 'order_number'=> 1, 'parent_id' => null, 'icon' => 'feather icon-home', 'name' => 'dashboard', 'route' => '/dashboard', 'generate_permission' => 'ALL' ]) ->user_roles() ->sync($id);
$id
是管理员用户角色的id。generate_permission
是授予用户角色的权限的ENUM
类型,可以是 'ALL'、'MANAGE_ONLY' 或 'READ_ONLY'。
-
- 用户角色和权限已创建。
- 同步权限与菜单项,以便用户可以访问菜单项。
{ $userRole = UserRole::where(['name' => 'ADMIN'])->first(); $permissions = Permission::whereIn('menu_item_id',$userRole->menu_items()->pluck('id'))->pluck('id'); $userRole->permissions()->sync($permissions); }
-
在 App/Database/Seeder/DatabaseSeeder.php 中将 artisan 命令注册到数据库 Seeder 中;
Artisan::call('aclmenu:refresh');
Seeder 运行顺序。
$this->call(UserRolesTableSeeder::class); $this->call(MenuItemsTableSeeder::class); $this->call(UserTableSeeder::class); $this->call(TeamsTableSeeder::class); Artisan::call('aclmenu:refresh'); $this->call(DefaultUserPermissionsSync::class);
-
运行 Seeder 以实现更改
php artisan db:seed
aclmenu:refresh
- 此命令在检查
MeuItem
模型中的权限后,在Permission
模型中播种数据。 - 可能的权限是 'All'、"READ" 和 "MANAGE_ONLY"。
- 默认权限是
READ
。
ACLUserTrait
-
在
User
模型中使用OTIFSolutions\ACLMenu\Traits\ACLUserTrait
-
在此 trait 中使用了以下方法
-
team
此方法返回创建团队或父团队的用户。
-
hasPermission
此方法检查用户是否有权限访问页面。
if (!Auth::user()->hasPermission('READ', '/dashboard')) return 'error'; return view('dashboard');
- 如果条件为真,则返回
True
,否则返回false
。 - 调用方法时传递了两个属性。
- 一个是
permissionTypeString
,可能的值是 READ、CREATE、UPDATE 或 DELETE。 - 如果没有传递 permissionTypeString,则默认为 READ。
- 另一个属性是
permission
,它是页面的路由。 - 如果没有传递权限,则将当前权限存储在会话中。
- 如果条件为真,则返回
-
hasPermissionMenuItem
- 此方法检查用户是否有权限访问菜单项。
- 传递菜单项的id
menu_item_id
。 - 返回布尔值。可能的值是 true 或 false。
-
getTeamOwnerAttribute
此方法从团队中返回团队所有者。返回
$this['team']['owner']
配置
-
如果用户未经授权,则返回
redirect_url
,例如/
。if ($request->user() == null) return redirect(config('laravelacl.redirect_url'));
-
它具有 laravel
config.php
的路径,该路径返回模型中的用户。'models' => [ 'user' => config('auth.providers.users.model') ]
-
使用此代码使用配置。
config('laravelacl.models.user')
中间件
-
中间件处理传入的请求。
-
中间件设置在路由上。例如
Route::get('/dashboard', [DashboardController::class, 'dashboard'])->middleware('role:dashboard');
-
如果路由有权限,则返回预期页面,否则用户将被重定向。
中间件的工作方式
-
如果未找到
Auth::User
,则返回主页。例如/
。 -
如果权限为空
-
获取请求的当前路径信息。
$permission = $request->path();
-
使用当前路径将当前权限存储在会话中。
\Session::put('current_permission', $permission);
-
模型
-
MenuItem
-
Permission
-
PermissionType
- 通过 Seeder 创建了权限类型。
- 这些类型是 "READ"、"CREATE"、"UPDATE"、"DELETE" 和 "MANAGE"。
-
Team
-
User Role
-
UserRoleGroup
Teams
步骤. 1
-
使用
user_id
创建团队。Team::updateOrCreate(['user_id' => 1]);
步骤. 2
- 团队所有者创建用户角色。
步骤. 3
-
所有者将权限分配给创建的用户角色。
-
所有者可以分配他可以访问的权限。
-
权限
从权限
模型中获取以分配权限, -
当所有者分配权限时,这些权限将使用以下代码进行同步。
$userRole->permissions()->sync($request['permissions']);
步骤. 4
- 可以使用创建的用户角色添加团队成员。
侧边栏创建
- 使用以下类创建侧边栏。
<aside class="sidenav bg-white navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-4 " id="sidenav-main"> <div class="sidenav-header"> <div class="main-menu menu-fixed menu-dark menu-accordion menu-shadow" data-scroll-to-active="true"> <div class="navbar-header bg-white"> <ul class="nav navbar-nav flex-row"> <li class="nav-item mr-auto"> <a class="navbar-brand" href="{{ url('/dashboard') }}"> <div class="brand-logo"></div> <h2 class="brand-text mb-0">Your Project Name</h2> </a> </li> <li class="nav-item nav-toggle"> <a class="nav-link modern-nav-toggle pr-0" data-toggle="collapse" id="sidebar_collapse"><i class="feather icon-x d-block d-xl-none font-medium-4 black toggle-icon"></i><i class="toggle-icon feather icon-disc font-medium-4 d-none d-xl-block collapse-toggle-icon black" data-ticon="icon-disc"></i></a> </li> </ul> </div> <div class="main-menu-content mt-2"> Content of sidebar </div> </div> </div> </aside>
侧边栏内容
-
侧边栏是使用分配的权限创建的。
-
如果用户角色经过认证。
- 循环开始并检查用户是否有权限访问菜单项。
- 菜单项名称出现在侧边栏上。
-
Request::is
检查传入的请求是否与菜单项路由匹配,然后项目变为活动状态。Request::is(strtolower(str_replace('/','',$menuItem['route'])))
-
如果有任何菜单项有子菜单项,匹配请求后会打开。
-
如果用户有权限访问菜单项,则循环开始,匹配的子菜单项变为活动状态。
<ul class="navigation navigation-main" id="main-menu-navigation" data-menu="menu-navigation"> @if(Auth::user()['user_role']) @foreach(Auth::user()['user_role']->menu_items()->orderBy('order_number', 'ASC')->get() as $menuItem) @if (Auth::user()->hasPermissionMenuItem($menuItem['id'])) @if ($menuItem['show_on_sidebar']) @if($menuItem['heading']) <li class="navigation-header"> {{$menuItem['heading']}} </li> @endif @if (count($menuItem['children']) == 0) @if($menuItem['parent_id'] === 0) <li class="nav-item {{ Request::is(strtolower(str_replace('/','',$menuItem['route']))) || Request::is(strtolower(str_replace('/','',$menuItem['route'])).'/*')?'active':'' }}"> <a href="{{ url($menuItem['route']) }}"> <i class="{{ $menuItem['icon'] }}"></i> <span class="menu-title" data-i18n="{{ $menuItem['name'] }}">{{ $menuItem['name'] }}</span> </a> </li> @endif @else <li class="nav-item has-sub {{ Request::is(strtolower(str_replace(' ','_',str_replace('/','',$menuItem['route']))).'/*') && (Auth::user()->sidebar_collapse == 0)? 'open' :'' }}"> <a href="#"><i class="{{ $menuItem['icon'] }}"></i> <span class="menu-title" data-i18n="{{ $menuItem['name'] }}">{{ $menuItem['name'] }}</span> </a> <ul class="menu-content"> @foreach($menuItem['children'] as $child) @if (Auth::user()->hasPermissionMenuItem($child['id'])) <li class="nav-item {{ Request::is(strtolower(str_replace(' ','_',$child['name']))) || Request::is('*/'.strtolower(str_replace(' ','_',$child['name'])))?'active':'' }}"> <a href="{{ url($child['route']) }}"><i class="{{ $child['icon'] }}"></i><span class="menu-item" data-i18n="{{ $child['name'] }}">{{ $child['name'] }}</span></a> </li> @endif @endforeach </ul> </li> @endif @endif @endif @endforeach @endif </ul>