DcatAdmin 根据菜单数据自动填充权限信息 (Artisan命令)

写这个的原因: 使用Dcat时配一遍菜单还得再去配一遍权限, 感觉比较麻烦主要是懒就自己写了一个命令来生成基本的权限信息, 也可以用来同步不同环境的菜单信息

实现

app/Console/Commands下新建文件DcatMenuCommand.php贴入如下内容
编写Artisan命令 - 文档

<?php

namespace App\Console\Commands;

use Dcat\Admin\Models\Menu;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Dcat\Admin\Models\Permission;
use Illuminate\Support\Facades\DB;

class DcatMenuCommand extends Command
{
    protected $signature = 'admin:menu';

    protected $description = 'backup or populate menu data';

    private $backupPath = '';

    public function handle()
    {
        $type = $this->ask(<<<TEXT
Please select an action type:
1: backup only
2: fill only
3: backup and fill
TEXT
        );

        $this->backupPath = storage_path('menu-backup.bak');

        switch ($type) {
            case 1: // backup only
                $this->backupMenu();
                break;
            case 2: // fill only
                $this->fillMenu();
                break;
            case 3: // backup and fill
                $this->backupAndFillMenu();
                break;
            default:
                echo 'Please enter the correct action type';
                break;
        }
    }

    /**
     * backup menu
     */
    private function backupMenu()
    {
        $res = file_put_contents($this->backupPath, serialize(optional(Menu::get())->toArray()));

        echo $res ? 'Backup succeeded' : 'Backup failed';
    }

    /**
     * fill menu
     */
    private function fillMenu()
    {
        $menu = unserialize(file_get_contents($this->backupPath));

        $permission = $this->generatePermissions($menu);

        Menu::truncate();
        Menu::insert($menu);

        Permission::truncate();
        Permission::insert($permission);

        DB::table('admin_permission_menu')->truncate();
        foreach ($permission as $item) {
            $query = DB::table('admin_permission_menu');
            $query->insert([
                'permission_id' => $item['id'],
                'menu_id'       => $item['id'],
            ]);
            if ($item['parent_id'] != 0) {
                $query->insert([
                    'permission_id' => $item['id'],
                    'menu_id'       => $item['parent_id'],
                ]);
            }
        }

        echo 'Filled successfully';
    }

    /**
     * Back up and populate the menu
     */
    private function backupAndFillMenu()
    {
        $this->backupMenu();
        $this->fillMenu();
    }

    /**
     * Generate permission data
     *
     * @param $menu
     *
     * @return array
     */
    private function generatePermissions($menu)
    {
        $permissions = [];
        foreach ($menu as $item) {
            $temp = [];

            $temp['id']         = $item['id'];
            $temp['name']       = $item['title'];
            $temp['slug']       = (string)Str::uuid();
            $temp['http_path']  = $this->getHttpPath($item['uri']);
            $temp['order']      = $item['order'];
            $temp['parent_id']  = $item['parent_id'];
            $temp['created_at'] = $item['created_at'];
            $temp['updated_at'] = $item['updated_at'];

            $permissions[] = $temp;
            unset($temp);
        }

        return $permissions;
    }

    /**
     * Get http path according to menu uri
     *
     * @param $uri
     *
     * @return string
     */
    private function getHttpPath($uri)
    {
        if ($uri == '/') {
            return '';
        }

        if ($uri == '') {
            return '';
        }

        if (strpos($uri, '/') !== 0) {
            $uri = '/' . $uri;
        }

        return $uri . '*';
    }
}

使用方式

在项目根目录执行命令php artisan admin:menu会得到如下提示 (然后输入1/2/3执行对应操作)

Please select an action type:
1: backup only
2: fill only
3: backup and fill:
 >

1: 备份菜单-查询出所有菜单数据序列化后写入storage/menu-backup.bak文件中
2: 填充菜单-读出storage/menu-backup.bak中的内容并写入数据库
3: 备份并填充-依次执行1~2的操作

!! 填充操作会 清空 truncate 原有的菜单表 admin_menu、权限表 admin_permissions、权限菜单关联表 admin_permission_menu 然后再写入数据

! 该命令只是把菜单一一对应的搬到权限表中, 更细致的权限控制还是得自己动手添加

本作品采用《CC 协议》,转载必须注明作者和本文链接
海到无涯天作案,山登绝顶我为峰
slowlyo
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 2

我也写了一个根据路由生成权限的命令,因为一开始没有按照一定规则去命名,导致做了很多兼容,浪费了一下午 :joy:

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!