做好之前的功能,现在开始做权限管理以及后台。权限管理这里使用第三方扩展包 laravel-permission
laravel-permission github
https://docs.spatie.be/laravel-permission/v3/installation-laravel/
按照文档,进行常规操作。
安装使用 laravel-permission
基本步骤如下
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
为了更好的使用权限,在 权限表中加了一些额外的字段
# permissions 迁移中加入下边字段
$table->string('display_name');
$table->string('route')->nullable();
$table->integer('icon_id')->nullable();
$table->integer('parent_id')->default(0);
$table->integer('sort')->default(0);
# roles 迁移中加入下边字段
$table->string('display_name');
因为会用到 icon,所以得额外加一个 icons 表。生成一个额外的迁移文件
php artisan make:migration create_icons_tabel --create=icons
# 填充迁移文件
Schema::create('icons', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('unicode')->nullable();
$table->string('class')->nullable();
$table->string('name')->nullable();
$table->integer('sort')->default(0);
$table->nullableTimestamps();
});
# 执行迁移
php artisan migrate
怎么使用呢,看 wiki https://docs.spatie.be/laravel-permission/v3/basic-usage/basic-usage/
- 在模型中加入 Spatie\Permission\Traits\HasRoles trait,可以是 User 模型也可以是其他,看你怎么用。
- 虽然可以给单独模型赋予权限,不建议这样做。建议通过 role 来实现。先给 role 赋予权限,再给用户赋予角色。这样更好管理和控制权限。
完成了上边的操作,我们还需要做两个数据填充(Seeders),一个 IconSeeder 和 PermissionSeeder 。
php artisan make:seeder IconSeeder
php artisan make:seeder PermissionSeeder
既然要整 icon ,那我们就用阿里的 iconfonts 。去 https://www.iconfont.cn/ 操作一波。
制作好了之后,先创建 json 文件:
vim public/backstage/json/icons.json
# 填充以下内容(以3个icon为例)
[{"unicode": "", "name": "控制台", "class": "icon-kongzhitai"},
{"unicode": "", "name": "权限", "class": "icon-quanxian"},
{"unicode": "", "name": "仪表盘", "class": "icon-yibiaopan"}]
再去编辑 IconSeeder。
# 创建 icon
php artisan make:model Models/Icon
# 白名单
protected $fillable = ['unicode','class','name','sort'];
# IconSeeder
<?php
use Illuminate\Database\Seeder;
use App\Models\Icon;
class IconSeeder extends Seeder
{
public function run()
{
Icon::truncate();
$file = file_get_contents(public_path().'/backstage/json/icons.json');
$icons = json_decode($file, true);
foreach ($icons as $icon){
Icon::create($icon);
}
}
}
PermissionSeeder 的迁移文件可参考: https://docs.spatie.be/laravel-permission/v3/advanced-usage/seeding/
根据需求,先暂时建立几个权限以及角色。迁移文件如下:
php artisan make:model Models/Permission
php artisan make:model Models/Role
# Permission Model
<?php
namespace App\Models;
use Spatie\Permission\Models\Permission as SPermission;
class Permission extends SPermission
{
//菜单图标
public function icon()
{
return $this->belongsTo('App\Models\Icon', 'icon_id', 'id');
}
//子权限
public function childs()
{
return $this->hasMany('App\Models\Permission', 'parent_id', 'id');
}
}
# Role Model
<?php
namespace App\Models;
use Spatie\Permission\Models\Role as SRole;
class Role extends SRole
{
}
然后,permission seeder。
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\PermissionRegistrar;
use App\Models\User;
use App\Models\Permission;
use App\Models\Role;
use DB;
use Hash;
class PermissionSeeder extends Seeder
{
public function run()
{
app(PermissionRegistrar::class)->forgetCachedPermissions();
$tableNames = config('permission.table_names');
Model::unguard();
foreach ($tableNames as $tableName) {
DB::table($tableName)->delete();
}
Model::reguard();
$user = User::where('account', '13671638524')->first();
if (!$user) {
$user = User::create([
'account' => '13671638524',
'password' => Hash::make('w123456'),
'email' => 'lichking_lin86@qq.com',
'phone' => '13671638524'
]);
}
$role = Role::create([
'name' => 'root',
'display_name' => '站长'
]);
$user->assignRole($role);
$permissions = [
[
'name' => 'home.manager',
'display_name' => '主页',
'route' => '',
'icon_id' => '1',
'child' => [
[
'name' => 'home',
'display_name' => '控制台',
'route' => 'admin.home',
'icon_id' => '12',
'child' => []
]
]
],
[
'name' => 'system.manage',
'display_name' => '系统管理',
'route' => '',
'icon_id' => '2',
'child' => [
[
'name' => 'system.permission',
'display_name' => '权限管理',
'route' => 'admin.system.permission',
'icon_id' => '2',
'child' => [
['name' => 'system.permission.create', 'display_name' => '添加权限', 'route' => 'admin.system.permission.create'],
['name' => 'system.permission.edit', 'display_name' => '编辑权限', 'route' => 'admin.system.permission.edit'],
['name' => 'system.permission.destroy', 'display_name' => '删除权限', 'route' => 'admin.system.permission.destroy'],
]
],
[
'name' => 'system.role',
'display_name' => '角色管理',
'route' => 'admin.system.role',
'icon_id' => '3',
'child' => [
['name' => 'system.role.create', 'display_name' => '添加角色', 'route' => 'admin.system.role.create'],
['name' => 'system.role.edit', 'display_name' => '编辑角色', 'route' => 'admin.system.role.edit'],
['name' => 'system.role.destroy', 'display_name' => '删除角色', 'route' => 'admin.system.role.destroy'],
['name' => 'system.role.permission', 'display_name' => '分配权限', 'route' => 'admin.system.role.permission'],
]
],
[
'name' => 'system.manager',
'display_name' => '管理员',
'route' => 'admin.system.manager',
'icon_id' => '123',
'child' => [
['name' => 'system.manager.create', 'display_name' => '添加管理', 'route' => 'admin.system.manager.create'],
['name' => 'system.manager.edit', 'display_name' => '编辑管理', 'route' => 'admin.system.manager.edit'],
['name' => 'system.manager.destroy', 'display_name' => '删除管理', 'route' => 'admin.system.manager.destroy'],
['name' => 'system.manager.role', 'display_name' => '分配角色', 'route' => 'admin.system.manager.role'],
['name' => 'system.manager.permission', 'display_name' => '分配权限', 'route' => 'admin.system.manager.permission'],
]
]
]
]
];
foreach ($permissions as $pem1) {
//生成一级权限
$p1 = Permission::create([
'name' => $pem1['name'],
'display_name' => $pem1['display_name'],
'route' => $pem1['route'] ?? '',
'icon_id' => $pem1['icon_id'] ?? 1,
]);
//为角色添加权限
$role->givePermissionTo($p1);
if (isset($pem1['child'])) {
foreach ($pem1['child'] as $pem2) {
//生成二级权限
$p2 = Permission::create([
'name' => $pem2['name'],
'display_name' => $pem2['display_name'],
'parent_id' => $p1->id,
'route' => $pem2['route'] ?? 1,
'icon_id' => $pem2['icon_id'] ?? 1,
]);
//为角色添加权限
$role->givePermissionTo($p2);
if (isset($pem2['child'])) {
foreach ($pem2['child'] as $pem3) {
//生成三级权限
$p3 = \App\Models\Permission::create([
'name' => $pem3['name'],
'display_name' => $pem3['display_name'],
'parent_id' => $p2->id,
'route' => $pem3['route'] ?? '',
'icon_id' => $pem3['icon_id'] ?? 1,
]);
//为角色添加权限
$role->givePermissionTo($p3);
}
}
}
}
}
//初始化的角色
$roles = [
['name' => 'manager', 'display_name' => '管理员']
];
foreach ($roles as $role) {
Role::create($role);
}
}
}
再在 DatabaseSeeder 中加入:
$this->call(IconSeeder::class);
$this->call(PermissionSeeder::class);
# 然后迁移回滚操作
php artisan migrate:refresh --seed -v
添加中间件。在 app/Http/Kernel.php 中的 routeMiddleware 增加映射
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,