Write the Code. Change the World.

1月 27

做好之前的功能,现在开始做权限管理以及后台。权限管理这里使用第三方扩展包 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/

  1. 在模型中加入 Spatie\Permission\Traits\HasRoles trait,可以是 User 模型也可以是其他,看你怎么用。
  2. 虽然可以给单独模型赋予权限,不建议这样做。建议通过 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,

发表评论

电子邮件地址不会被公开。 必填项已用*标注