yii-admin,rbac权限

首先需要安装yii-admin

composer require mdmsoft/yii2-admin "~2.0"

 然后配置yii-admin

'modules' => [
        'admin' => [
            'class' => 'mdm\admin\Module',
            'controllerMap' => [
                'assignment' => [
                    'class' => 'mdm\admin\controllers\AssignmentController',
                    'userClassName' => 'common\models\Admin',
                ],
            ],
            //'layout' => 'left-menu',
            //'layout' => '@backend/views/layouts/main.php',
            'menus' => [
                'assignment' => [
                    'label' => 'Grand Access', // change label
                ],
                //'route' => null, // disable menu route
            ],
        ]
    ],
    'as access' => [
        'class' => 'mdm\admin\components\AccessControl',
        'allowActions' => [
            'site/*',
            'admin/*',
        ]
    ],

创建相关表

php yii migrate --migrationPath=@mdm/admin/migrations
php yii migrate --migrationPath=@yii/rbac/migrations

访问地址 xxx.com/admin/route/index

相关表说明

menu  // 菜单表,对应后台左侧菜单
auth_rule            //规则,规则类名
auth_item_child    //角色对应的权限,parent角色,child权限名
auth_item            //角色|权限表,type=1角色,type=2权限
auth_assignment    //角色与用户对应关系表

 

到这里权限基本可以用了,但是这个只有开发人员可以看懂,普通操作人员是没法操作的,所以我们需要优化,让普通操作人员也能操作。

首先,在auth_item表添加3个字段

title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `sort` int(11) DEFAULT '0' COMMENT '排序',
  `auth_parent` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `is_permission` tinyint(4) DEFAULT '0' COMMENT '0:表示参与权限管理,1:表示默认给与权限,比如一些Ajax,4:表示只有超级管理员才有的权限',

title表示前端页面显示标题

sort表示排序

auth_parent表示层级关系, 如/user/*表示父级, /user/index表示子级

is_permission表示是否参与权限管理

然后就是角色管理。

使用php yii gii/model 命令分别生成4个表的模型,并建立角色控制器,如AuthPermissionController.php

在这个控制器中,我们需要新建角色,并分配权限,新建角色很简单,就是create,update,比较麻烦的是权限。

首先我们需要初始化标题,当然也可以通过create,update手动初始化,这样比较灵活,这里使用自动初始化。

private function makeInfo($items) {
        // 修正auth_parent、 index、rule_name
        foreach($items as $key => $val) {
            if(empty($val->title)) {
                $route = $val->name;
                // 路由格式: /permission/index
                // 路由格式: /permission/index
                $route2 = str_replace('-', '_', $route);
                $routeArr = explode('/', $route2);
                if(count($routeArr) > 1) {
                    $action = $routeArr[2];
                    $controllerName = Yii::t('backend', $routeArr[1]);
                    $parent = '';
                    $title = '';
                    if(isset($routeArr[3])) {
                        $controllerName = Yii::t('backend', $routeArr[1]) . Yii::t('backend', $routeArr[2]);
                        $actionName = Yii::t('backend', 'action_' . $routeArr[3]);
                        $parent = $routeArr[1] . '_' . $routeArr[2];
                        $title = $actionName;
                        if($routeArr[3] == '*') {
                            $actionName = '';
                            $title = $controllerName;
                        }
                    } else {
                        $actionName = Yii::t('backend',  'action_' . $routeArr[2]);
                        $parent = $routeArr[1];
                        $title = $actionName;
                        if($routeArr[2] == '*') {
                            $actionName = '';
                            $parent = '';
                            $title = $controllerName;
                        }
                    }   

                    // 只有超级管理员才能操作的
                    $adminPermission = ['admin', 'manager', 'rule-permission', 'gii', 'debug', 'test'];

                    // 默认给与权限的
                    $allowPermission = ['dashboard', 'uploader'];

                    // is_permission 0:表示参与权限管理,1:表示默认给与权限,比如一些Ajax,4:表示只有超级管理员才有的权限
                    $isPermission = 0;
                    foreach($adminPermission as $ak => $av) {
                        $adminIndex = stripos($route, $av);
                        if($adminIndex !== false) {
                            $isPermission = 4;
                        }
                    }

                    foreach($allowPermission as $ak => $av) {
                        $adminIndex = stripos($route, $av);
                        if($adminIndex !== false) {
                            $isPermission = 1;
                        }
                    }
                    
                    
                    $val->title = $title;
                    $val->index = 1;
                    $val->is_permission = $isPermission;
                    $val->auth_parent = $parent;
                    $val->save();
                }
            }
        }
    }

然后是读取权限列表

private function treelist($items, $parent = '') {
        $list = [];
        foreach($items as $key => $val) {
            if(empty($val->auth_parent)) {
                $data['name'] = $val->name;
                $data['title'] = $val->title;
                $data['index'] = $val->index;
                $data['auth_parent'] = $val->auth_parent;
                $data['children'] = [];
                $route2 = str_replace('-', '_', $val->name);
                $routeArr = explode('/', $route2);
                if(count($routeArr) > 1) {
                    $parent = '';
                    if(isset($routeArr[3])) {
                        $parent = $routeArr[1] . '_' . $routeArr[2];
                    } else {
                        $parent = $routeArr[1];
                    }   
                    if(!empty($parent)) {
                      foreach($items as $k => $v) {
                          if($v->auth_parent == $parent) {
                            $sdata['name'] = $v->name;
                            $sdata['title'] = $v->title;
                            $sdata['index'] = $v->index;
                            $sdata['auth_parent'] = $v->auth_parent;
                            $data['children'][] = $sdata;
                          }
                      }
                    }
                    
                } 
                $list[] = $data;
                
            }
        }
        return $list;
    }

,接下来是保存权限

if(Yii::$app->request->isPost) {
            $permissionsPost = Yii::$app->request->post('permission');
            if(!empty($permissionsPost)) {
                // 如果已经有权限,则不做处理
                // 如果没有则添加
                $newPermission = array_diff($permissionsPost, $permissions);
                if($newPermission) {
                    foreach($newPermission as $key => $val) {
                        $authItemChildModel = new AuthItemChild();
                        $authItemChildModel->parent = $model->name;
                        $authItemChildModel->child = $val;
                        $authItemChildModel->save();
                    } 
    
                }
                
                // 如果已有但传入的数据没有,则删除
                $deletePermission = array_diff($permissions, $permissionsPost);
                if($deletePermission) {
                    foreach($deletePermission as $key => $val) {
                        $authItem = AuthItem::find()->where(['name' => $val])->one();
                        if($authItem->is_permission == 0) {
                            AuthItemChild::deleteAll(['parent' => $model->name, 'child' => $val]);
                        }
                    }
                }

                // 默认给与权限
                $allowPermission = ['/dashboard/*', '/uploader/*'];
                foreach($allowPermission as $key => $val) {
                    $authItemChild = AuthItemChild::find()->where(['parent' => $model->name, 'child' => $val])->one();
                    if(empty($authItemChild)) {
                        $authItemChildModel = new AuthItemChild();
                        $authItemChildModel->parent = $model->name;
                        $authItemChildModel->child = $val;
                        $authItemChildModel->save();
                    }
                }
                return $this->redirect(['view', 'id' => $id]);  
            }
        }

前端页面

<?php $form = ActiveForm::begin(); ?>
    <div class="permission-list">
        <?php 
            foreach($list as $key => $val) { 
                $checked = '';
                if(in_array($val['name'], $permissions)) {
                    $checked = ' checked="checked" ';
                }
        ?>
        <div class="permission-item">
            <div class="row">
                <div class="col-md-2 parent">
                    <input type="checkbox" class="parent-permission" name="permission[]" value="<?= $val['name'] ?>" <?= $checked ?> /> <?= $val['title'] ?>
                </div>
                <div class="col-md-9 children">
                    <?php
                    if(isset($val['children'])) {
                        foreach($val['children'] as $k => $v) {
                            // 如果子路由在权限或者所有子路由(*)在权限,则选中
                            // 最后一个 / 如: /user/create
                            $lastIndex = strripos($v['name'], '/');
                            // 截取路由controller, 如:/user/
                            $controllerPath = substr($v['name'], 0, $lastIndex + 1);
                            // 链接*,表示全部子路由,如:/user/*
                            $controllerPath = $controllerPath . '*';
                            $schecked = '';
                            if(in_array($v['name'], $permissions) || in_array($controllerPath, $permissions)) {
                                $schecked = ' checked="checked" ';
                            }

                    ?>
                    <span><input type="checkbox" class="child-permission" name="permission[]" value="<?= $v['name'] ?>" <?= $schecked ?> /> <?= $v['title'] ?></span>
                   <?php } } ?>
                </div>
            </div>
        </div>
        <?php } ?>
        <div class="permission-submit">
            <?= Html::submitButton(Yii::t('backend', 'save'), ['class' => 'btn btn-success']) ?>
        </div>

    </div>
    <?php ActiveForm::end(); ?>

js

// 点击父权限,子权限全部选中
    $('.permission-list .permission-item .parent-permission').each(function() {
        $(this).on('change', function() {
            $(this).parent().next().find('.child-permission').prop('checked', $(this).prop('checked'));
        })
    }) 
    // 点击子权限,如果有一个没选中,父权限不选中,如果所有都选中,父权限选中
    $('.permission-list .permission-item .child-permission').each(function() {
        $(this).on('change', function() {
            var isChecked = $(this).prop('checked');
            if(isChecked) {
                // 选中
                // 判断是否全部选中
                var isAllChecked = true;
                var allChild = $(this).parent().siblings().find('.child-permission');
                for(var i = 0; i < allChild.length; i++) {
                    if(!$(allChild[i]).prop('checked')) {
                        isAllChecked = false;
                        break;
                    }
                }

                if(isAllChecked) {
                    $(this).parent().parent().prev().find('.parent-permission').prop('checked', true);
                }
            } else {
                // 不选中
                $(this).parent().parent().prev().find('.parent-permission').prop('checked', false);
            }
        })
    }) 

AuthPermissionController.php

use Yii;
use common\models\Auth\AuthRule;
use common\models\Auth\AuthItem;
use common\models\Auth\AuthItemChild;
use common\models\Auth\AuthAssignment;
use yii\data\ActiveDataProvider;
use backend\controllers\BackendController;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
 * PermissionController implements the CRUD actions for Permission model.
 * est_auth_item 表需要添加字段auth_parent:默认0; index: 排序
 */
class RulePermissionController extends BackendController
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Lists all Permission models.
     * @return mixed
     */
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => AuthItem::find()->where(['type' => 1]),
        ]);

        $authItems = AuthItem::find()->where(['type' => 2])->orderBy('index DESC')->all();
        // 初始化标题
        $this->makeInfo($authItems);


        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single Order model.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionView($id)
    {
        $model = $this->findModel($id);

        // 获取角色所有权限
        $authItemChild = AuthItemChild::find()->where(['parent' => $model->name])->all();
        $permissions = [];
        if($authItemChild) {
            foreach($authItemChild as $key => $val) {
                $permissions[] = $val->child;
            }
        }

        if(Yii::$app->request->isPost) {
            $permissionsPost = Yii::$app->request->post('permission');
            if(!empty($permissionsPost)) {
                // 如果已经有权限,则不做处理
                // 如果没有则添加
                $newPermission = array_diff($permissionsPost, $permissions);
                if($newPermission) {
                    foreach($newPermission as $key => $val) {
                        $authItemChildModel = new AuthItemChild();
                        $authItemChildModel->parent = $model->name;
                        $authItemChildModel->child = $val;
                        $authItemChildModel->save();
                    } 
    
                }
                
                // 如果已有但传入的数据没有,则删除
                $deletePermission = array_diff($permissions, $permissionsPost);
                if($deletePermission) {
                    foreach($deletePermission as $key => $val) {
                        $authItem = AuthItem::find()->where(['name' => $val])->one();
                        if($authItem->is_permission == 0) {
                            AuthItemChild::deleteAll(['parent' => $model->name, 'child' => $val]);
                        }
                    }
                }

                // 默认给与权限
                $allowPermission = ['/dashboard/*', '/uploader/*'];
                foreach($allowPermission as $key => $val) {
                    $authItemChild = AuthItemChild::find()->where(['parent' => $model->name, 'child' => $val])->one();
                    if(empty($authItemChild)) {
                        $authItemChildModel = new AuthItemChild();
                        $authItemChildModel->parent = $model->name;
                        $authItemChildModel->child = $val;
                        $authItemChildModel->save();
                    }
                }
                return $this->redirect(['view', 'id' => $id]);  
            }
        }
        // 获取所有权限
        // is_permission 0:表示参与权限管理,1:表示默认给与权限,比如一些Ajax,4:表示只有超级管理员才有的权限
        $authItems = AuthItem::find()->where(['type' => 2, 'is_permission' => 0])->orderBy('index DESC')->all();
        
        $list = $this->treelist($authItems);
        
        return $this->render('view', [
            'model'        => $model,
            'list'         => $list,
            'permissions'  => $permissions
        ]);
    }

    /**
     * Creates a new AuthItem model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new AuthItem();

        if ($model->load(Yii::$app->request->post())) {
            $model->type = 1;
            if($model->save()) {
             
                return $this->redirect(['index']);
            }
            
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

    /**
     * Updates an existing Permission model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
           
            return $this->redirect(['index']);
        }

        
        return $this->render('update', [
            'model' => $model,
        ]);
    }

    /**
     * Deletes an existing AuthItem model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionDelete($id)
    {
        $model = $this->findModel($id);
        
        $model->delete();
        return $this->redirect(['index']);
    }

    /**
     * Finds the AuthItem model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return AuthItem the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = AuthItem::findOne($id)) !== null) {
            return $model;
        }

        throw new NotFoundHttpException('The requested page does not exist.');
    }

    private function makeInfo($items) {
        // 修正auth_parent、 index、rule_name
        foreach($items as $key => $val) {
            if(empty($val->title)) {
                $route = $val->name;
                // 路由格式: /permission/index
                // 路由格式: /permission/index
                $route2 = str_replace('-', '_', $route);
                $routeArr = explode('/', $route2);
                if(count($routeArr) > 1) {
                    $action = $routeArr[2];
                    $controllerName = Yii::t('backend', $routeArr[1]);
                    $parent = '';
                    $title = '';
                    if(isset($routeArr[3])) {
                        $controllerName = Yii::t('backend', $routeArr[1]) . Yii::t('backend', $routeArr[2]);
                        $actionName = Yii::t('backend', 'action_' . $routeArr[3]);
                        $parent = $routeArr[1] . '_' . $routeArr[2];
                        $title = $actionName;
                        if($routeArr[3] == '*') {
                            $actionName = '';
                            $title = $controllerName;
                        }
                    } else {
                        $actionName = Yii::t('backend',  'action_' . $routeArr[2]);
                        $parent = $routeArr[1];
                        $title = $actionName;
                        if($routeArr[2] == '*') {
                            $actionName = '';
                            $parent = '';
                            $title = $controllerName;
                        }
                    }   

                    // 只有超级管理员才能操作的
                    $adminPermission = ['admin', 'manager', 'rule-permission', 'gii', 'debug', 'test'];

                    // 默认给与权限的
                    $allowPermission = ['dashboard', 'uploader'];

                    // is_permission 0:表示参与权限管理,1:表示默认给与权限,比如一些Ajax,4:表示只有超级管理员才有的权限
                    $isPermission = 0;
                    foreach($adminPermission as $ak => $av) {
                        $adminIndex = stripos($route, $av);
                        if($adminIndex !== false) {
                            $isPermission = 4;
                        }
                    }

                    foreach($allowPermission as $ak => $av) {
                        $adminIndex = stripos($route, $av);
                        if($adminIndex !== false) {
                            $isPermission = 1;
                        }
                    }
                    
                    
                    $val->title = $title;
                    $val->index = 1;
                    $val->is_permission = $isPermission;
                    $val->auth_parent = $parent;
                    $val->save();
                }
            }
        }
    }

    /**
     * 权限二级管理
     */
    private function treelist($items, $parent = '') {
        $list = [];
        foreach($items as $key => $val) {
            if(empty($val->auth_parent)) {
                $data['name'] = $val->name;
                $data['title'] = $val->title;
                $data['index'] = $val->index;
                $data['auth_parent'] = $val->auth_parent;
                $data['children'] = [];
                $route2 = str_replace('-', '_', $val->name);
                $routeArr = explode('/', $route2);
                if(count($routeArr) > 1) {
                    $parent = '';
                    if(isset($routeArr[3])) {
                        $parent = $routeArr[1] . '_' . $routeArr[2];
                    } else {
                        $parent = $routeArr[1];
                    }   
                    if(!empty($parent)) {
                      foreach($items as $k => $v) {
                          if($v->auth_parent == $parent) {
                            $sdata['name'] = $v->name;
                            $sdata['title'] = $v->title;
                            $sdata['index'] = $v->index;
                            $sdata['auth_parent'] = $v->auth_parent;
                            $data['children'][] = $sdata;
                          }
                      }
                    }
                    
                } 
                $list[] = $data;
                
            }
        }
        return $list;
    }

}

最终页面

 

接下来就是用户与角色,在Manager中新增角色选择

/**
     * 获取到所有角色
     */
    private function getAuthItems() {
        return AuthItem::find()->where(['type' => 1])->all();
    }

    /**
     * 获取当前角色
     */
    private function getAuthAssignment($id) {
        $authAssignment = AuthAssignment::find()->where(['user_id' => $id])->one();
        return empty($authAssignment) ? '' : $authAssignment->item_name;
    }

    /**
     * 保存角色
     */
    private function maekAuthAssignment($id, $name) {
        $authAssignment = AuthAssignment::find()->where(['user_id' => $id])->one();
        if(empty($authAssignment)) {
            $authAssignment = new AuthAssignment();
            $authAssignment->item_name = $name;
            $authAssignment->user_id = strval($id);//因为数据库是存的varchar,所以需要转
            $authAssignment->save();
        } else {
            $authAssignment->item_name = $name;
            $authAssignment->save();
        }
    }
<div class="form-group">
        <div class="row row-box">
            <div class="col-xs-2 col-sm-2 text-right">
                <label class="control-label" for="course-name"><?= Yii::t('backend', 'rule_permission') ?></label>
            </div>
            <div class="col-xs-8 col-sm-8">
                <?= Html::dropDownList('permission', $authAssignment, ArrayHelper::map($authItems, 'name', 'name'), ['class' => 'form-control', 'prompt' => Yii::t('backend', 'please_select')]) ?>
            </div>
        </div>
    </div>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值