白狼栈 2016-04-28 09:17:45 18788次浏览 8条评论 12 3 0

作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。原文带图片参考。
先认个错,罪过了,你将要看的这篇教程是菜单权限的扩展,如果你的菜单出不来,很是建议你参考 yii2 rbac权限控制详细操作步骤.
前面我们在博文 yii2搭建完美后台并实现rbac权限控制实例教程中完美实现了yii2的后台搭建和rbac权限控制,如果你还没有实现,请先看上文再回来参考本文,因为本文是在上文的基础上进行完善和补充。

部分小伙们纷纷反映,最后菜单menu怎么控制权限呀,看不懂,搞不定,而且你那貌似没搞完,瞎忽悠!确实没那么全,今天看我们如何实现菜单完美权限化。先罗列下主要讲的内容,不需要的没必要看下去,只为分享给有需要的人。

  1. 利用menu表添加菜单
  2. 左侧菜单结果adminlte完美呈现
  3. 菜单前面自定义icon小图标并呈现
  4. 如何控制菜单的显示或者隐藏
  5. 页面操作按钮没权限的不做显示
  6. gridview中也只显示有操作权限的按钮
    嗯,差不多就这么多,如果你还有其他的有关权限控制菜单的需求,请下方留言,咱们共同切磋交流。

先看图预览下大致效果,不然怎么激起你们好学的心。

首先我们先访问路由页面 /dmin/route/index ,尽可能的把左侧的全部选中,然后移动到右侧,,然后记得给当前用户分配相关的可访问权限哦。

接下来访问菜单列表 /admin/menu/index 点击添加菜单,如果这个时候你没有权限访问了,请你在配置文件的 as access文件内暂时允许当前用户访问任意权限,并在我们添加完权限的时候去掉as access的设置,一定要记得哦,不然权限失效了可别回来找我。

这里我们先填写上图中标红的四个字段

举个例子:我们要添加一级菜单"权限管理"

名称请填写"权限管理",因为是一级菜单,父级名称请留空,路由我们这里选择"/admin/default/index",注意了,如果匹配到任何路由,请访问路由页面把左侧的选中移动到右侧。

映射,其实就是排序高低的问题,比如说我添加了两个菜单,映射值为1的就在上面 值为2的就在1的下面,我们这里填写数字1。

"数据"这一项我们后面再说。

按照刚刚介绍的这种方式添加吧,举一个添加二级菜单"权限控制"的例子

只需要把父级名称这里填写我们刚刚添加成功的一级名称"权限管理"即可。其他照旧。不会操作的多看两遍,这里最好把权限管理的几个菜单全部添加完毕,因为接下来我们需要且你可以多练练手嘛。

到此我们已经会添加菜单了。

我们来看下一步,利用我们之前搭建的后台框架进行展现。

use mdm\admin\components\MenuHelper; 
echo dmstr\widgets\Menu::widget( [
     'options' => ['class' => 'sidebar-menu'], 
    'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id), 
] );

是不是很简单,What?我的怎么没有dmstr这玩意,不好意思,已经说的很多遍,需要先看上文再有这个菜单的结合。

ok,刷新页面看看你的菜单,虽然我们还没完全实现我们想要的功能,不过到此你应该能看到你的菜单展现了。

接下来将进入我们的重点以及难点,我们要实现菜单前面的小图标且完成菜单可隐藏控制。

还记得我们一开始创建菜单的时候,唯一没进行填写的选项"数据"吗?为了后续操作方便,我们这里一并把图标和隐藏的选项都填写上。我们以开始截图中的"后台用户管理"这个二级菜单为例进行修改。截图大家先看看我们的菜单目前的状态,

请在其更新页面的“数据”项中务必填写下面的代码,如果你有新的想法,还请先按照我的思路后面再做修改,因为后面我们要进行操作。

{"icon": "fa fa-user", "visible": false}
是的,这个"数据"项我们填写的是一段json代码,接下来我们对展示菜单的代码也做稍微的整改,为了方便大家看代码,这里的$callback直接写在页面上了,回头大家可以继续封装优化。

use mdm\admin\components\MenuHelper; 
<?php 
$callback = function($menu){ 
    $data = json_decode($menu['data'], true); 
    $items = $menu['children']; 
    $return = [ 
        'label' => $menu['name'], 
        'url' => [$menu['route']], 
    ]; 
    //处理我们的配置 
    if ($data) { 
        //visible 
        isset($data['visible']) && $return['visible'] = $data['visible']; 
        //icon 
        isset($data['icon']) && $data['icon'] && $return['icon'] = $data['icon']; 
        //other attribute e.g. class... 
        $return['options'] = $data; 
    } 
    //没配置图标的显示默认图标 
    (!isset($return['icon']) || !$return['icon']) && $return['icon'] = 'fa fa-circle-o'; 
    $items && $return['items'] = $items; 
    return $return; 
}; 
//这里我们对一开始写的菜单menu进行了优化
echo dmstr\widgets\Menu::widget( [ 
    'options' => ['class' => 'sidebar-menu'], 
    'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id, null, $callback), 
] ); ?>

是的,你没有看错,代码是有点长,我们来简单分析分析。其实我们这里的$callback方法也只是针对上面我们添加菜单的"数据"项进行的分析。不难看出,我们对icon和visible分别进行了判断,并追加到当前menu中。

到此,我们费了一番波折终于实现菜单加icon和设置菜单的隐藏。如果你有其他的属性需要进行配置,此处仍然可以继续单独配置。

现在,我们还有两个任务仍待完成,要完成接下来的两个任务,为了大家的方便,建议你的项目可以自定义配置gii模版,不支持自定义gii模板的可以参考自定义gii模版 当你发现我们后面需要做的功能,我觉得你会赞叹我们这里的操作。

为了方便操作,我们这里增加一个测试表test,我们先用未做修改的gii模版生成一份model+curd。我们先把test/*的所有权限分配给当前登录的用户,并添加一条数据。打开/test我们可以正常看到下面的截图,注意图中的两个标记。

然后我们打开test/index.php文件,对标记的两个地方进行如下修改

use mdm\admin\components\Helper; 
<?php 
//没有创建权限不显示按钮 
if(Helper::checkRoute('create')) { 
    echo Html::a('Create Test', ['create'], ['class' => 'btn btn-success']); 
} ?> 
<?= GridView::widget([ 
    // ...... 
    'columns' => [ 
        // ...... 
        [ 
            'class' => 'yii\grid\ActionColumn', 
            'template' => Helper::filterActionColumn('{view}{update}{delete}'), 
        ], 
    ], 
]); ?>

现在我们刷新下页面/test再看看,好像没什么变化嘛。别急,我们现在撤销当前用户的/test/create 权限和/test/update权限,然后你在刷新下页面看看效果,我们截图看看。

也就是说我们没有权限的按钮消失了,当你手动访问/test/create的时候你会发现也会提醒你没有权限。

如果你的gii模板是自定义的,相信你会迅速在其生成的模板中所有的操作上添加权限控制的,是不是很happy

最后,我们的菜单menu关于权限控制的讲解基本也就结束了,长篇大论,仔细回想起来也没多少东西,倒是希望能帮到你一二

觉得很赞
  • 评论于 2016-04-28 13:03 举报

    这些是代码是代码是代码 是代码

  • 评论于 2016-05-31 10:27 举报

    当有四级菜单的时候,$callback就会报错什么原因?

    3 条回复
    评论于 2016-05-31 10:36 回复

    具体什么错

    评论于 2016-05-31 10:51 回复


    PHP Warning – yii\base\ErrorException

    array_merge(): Argument #2 is not an array

    评论于 2016-05-31 11:02 回复

    不是菜单的问题是数据的问题,添加菜单时候的数据格式不正确

  • 评论于 2016-08-02 10:41 举报

    你好 这个排序应该如何处理 可以自定义吗?

    3 条回复
    评论于 2016-08-02 11:45 回复

    菜单的排序按照【映射】这个字段也就是order字段,自己设置就好了

    评论于 2016-09-20 21:24 回复

    本来很简单的代码!非要搞什么神神秘密的

    评论于 2016-09-20 23:03 回复

    神神秘秘是什么意思?

  • 评论于 2017-07-31 19:02 举报

    狼哥,我按照你那样配置left文件,然后生成的i标签class="fa fa-fa fa-navicon",出现的是白色的旗子,还有什么地方要配置的吗

  • 评论于 2017-12-01 14:09 举报
    你好,菜单Menu的问题:
    比如添加名称为权限管理,父级名称为空,路由是/admin/default/index,规则是1,
    然后添加子菜单他们的父级名称写权限管理,这个我按照你说的ok了。
    感觉把商品管理菜单、订单管理菜单等等都写在权限管理下面不合适,应该和权限管理菜单是一个层级并且带下拉箭头的。
    
    这个是菜单全部在权限管理的子菜单了,父级名称指定为权限管理了:
    

    屏幕快照 2017-12-01 下午2.03.29.png

    这个是想要的效果:就是不知道他的路由填写什么:
    

    屏幕快照 2017-12-01 下午2.01.56.png

  • 评论于 2018-11-12 18:23 举报

    Helper::checkRoute('create'),我设置了checkRoute检查路由,不管有没有分配权限,打印出来的结果都是true,没权限按钮还一直显示,点击按钮提示没有操作权限,隐藏的操作没有起作用,麻烦问一下是什么问题,谢谢

  • 评论于 2018-12-07 15:16 举报

    我的route如果带参数会报找不到这个route这个怎么解决,111.png
    22.png

    1 条回复
    评论于 2018-12-07 15:17 回复

    不带参数的话是可以的

  • 评论于 2019-04-23 14:40 举报

    我的父级菜单一写.提交就是未设置?

您需要登录后才可以评论。登录 | 立即注册