Yii2框架管理后台权限设置机制
将所有action统一放在配置文件中XXX.php,将返回合并到params中:
return ['params' => ['rules' => [['n' => '权限测试(一级菜单)','i' => 'fa fa-circle-o', 'tree' => ['perm1','perm2'], 's'=>[
['n' => '权限测试(二级菜单)', 'c' => 'perm1','m' => 'index','i' => 'fa fa-circle-o','s'=>[
['n'=>'创建','m'=>'create','i'=>'fa fa-plus'],
['n'=>'查看)','m'=>'view','i'=>'fa fa-eye'],
['n'=>'更新','m'=>'update','i'=>'fa fa-pencil'],
]
],
['n' => '权限测试(二级菜单)', 'c' => 'perm2','m' => 'index','i' => 'fa fa-circle-o','s'=>[
['n'=>'创建','m'=>'create','i'=>'fa fa-plus'],
['n'=>'查看)','m'=>'view','i'=>'fa fa-eye'],
['n'=>'更新','m'=>'update','i'=>'fa fa-pencil'],
]
],
]
],]]];
controller层的action主要处理:
$model = Admin::find()->where(['adminId' => $id])->one();
$post = Yii::$app->request->post();
if ($model->load($post)) {
$ret = [];
if(!empty($post['Admin']['rules'])){
$ret = explode(',',$post['Admin']['rules']);
}
$model->rules = serialize($ret);
if($model->save()){
return $this->redirect(['index']);
}
}
$rules = empty($model->rules)?[]:unserialize($model->rules);
return $this->render('perm', [
'model' => $model,
'rules' => $rules,
]);
视图层文件perm.php
$this->title = '权限设置 '.$model->userName;
$this->params['breadcrumbs'][] = ['label' => '管理员列表', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
$menu = [];
if(isset(Yii::$app->params['rules']) and count(Yii::$app->params['rules'])>0){
foreach(Yii::$app->params['rules'] as $rule){
$menuItems = [
'text' => $rule['n'],
'icon' => $rule['i'],
'id' => "",
'state' => ['opened'=>true],
'children' =>[]
];
$menuItems["children"][] = [
];
foreach($rule['s'] as $child)
{
$children = [];
if(isset($child['tree']))
{
foreach($child["s"] as $second)
{
$secondChild = [];
$url = '/'.$second['c'].'/'.$second['m'];
$secondChild[] = [
'text' => $second['n'],
'icon' => $second['i'],
'id' => 'm_'.$url,
'children' => $secondChild,
'state' =>['checked'=>in_array($url, $rules) ? true : false],
];
// 第二级菜单处理
foreach($second['s'] as $secondSon)
{
$url = "/" . $second['c'] . '/' .$secondSon['m'];
$secondChild[] = [
'text' => $secondSon['n'],
'icon' => $secondSon['i'],
'id' => 'l_'.$url,
'children' => [],
'state' =>['checked'=>in_array($url, $rules) ? true : false],
];
}
$children[] = [
'text' => $second['n'],
'icon' => $second['i'],
'id' => 'm_'.$url,
'children' => $secondChild,
'state' =>['checked'=>in_array($url, $rules) ? true : false],
];
}
}
else
{
// 二级菜单处理
$url = '/'.$child['c'].'/'.$child['m'];
$children[] = [
'text' => $child['n'],
'icon' => $child['i'],
'id' => 'm_'.$url,
'children' => $children,
'state' =>['checked'=>in_array($url, $rules) ? true : false],
];
foreach($child['s'] as $son)
{
$url = "/" . $child['c'] . '/' .$son['m'];
$children[] = [
'text' => $son['n'],
'icon' => $son['i'],
'id' => 'l_'.$url,
'children' => [],
'state' =>['checked'=>in_array($url, $rules) ? true : false],
];
}
}
$menuItems['children'][] = [
'text' => $child['n'],
'icon' => $child['i'],
'id' => 'c_'.$url,
'children' => $children
];
unset($children);
unset($selfItem);
}
$menu[] = $menuItems;
unset($menuItems);
}
}
?>
<div class="row">
<div class="col-md-12">
<?php $form = ActiveForm::begin(['options'=>['class'=>'form-vertical form-perm','id'=>'perm_form']]); ?>
<div class="box-body">
<?=\talma\widgets\JsTree::widget([
'name' => 'jstree',
'core' => ['data'=>$menu,
'theme' => ['responsive'=>false]
],
'checkbox' => [
'tie_selection' => false
],
'plugins' => [ 'checkbox'],
]);
?>
<?= $form->field($model, 'rules')->hiddenInput()->label(false); ?>
</div>
<?php if (!Yii::$app->request->isAjax){ ?>
<div class="box-footer">
<?=Html::a('<i class="fa fa-save"></i> 保存','javascript:submitMe()',['class' => 'btn btn-warning']); ?>
</div>
<?php } ?>
<?php ActiveForm::end(); ?>
</div>
</div>
<script type="text/javascript">
function submitMe() {
var $form = $('#perm_form');
$form.on('submit', function(e) {
return $form.yiiActiveForm('submitForm');
});
$('#admin-rules').val(getJsTreeIds());
$form.submit();
}
var getJsTreeIds = function() {
var list = $.jstree.reference(jsTree_w0).get_checked();
var ids = new Array();
$.each(list, function(idx, val) {
if(val.indexOf('m_') != -1) {
ids.push(val.substring(2));
}
if(val.indexOf('l_') != -1) {
ids.push(val.substring(2));
}
});
return ids.toString();
};
</script>
jsTree版本: "thiagotalma/yii2-jstree": "~1.0.0"
判断权限关键代码,主要是继承yii\web\Controller类,然后重写actions(yii\web\Controller继承了yii\base\Controller)函数:
$pathInfo = Yii::$app->request->pathInfo;
if (!\Yii::$app->user->isGuest)
{
if(用户为非超级管理员)
{
if ($pathInfo !='XXX/logout' && $pathInfo !='XXXX/login')
{
list($rules, $trees) = \common\service\LAdminService::getAdminRules();
if ($pathInfo != "XXXX/denied" && !in_array("/" .$pathInfo, $rules))
{
// 权限不够,则跳转到无权限操作提示页面
return $this->redirect("/XXXXX/denied");
}
}
}
}
else
{
if($pathInfo !='XXXX/login')
{
return $this->redirect("/XXXX/login");
}
}