最近项目中要用到菜单的开启与关闭,自己研究了一下,项目使用的框架分别是ThinkPHP5 和 H-ui.admin,因为一开始做了权限,使用的是ThinkPHP5定义过的Auth.php,在tb_auth_group.sql数据表中添加module字段,存储方式:一级菜单键值加“-”链接二级菜单键值。如下:
这里随便例举,不是完整的哈,在common.php中菜单函数封装如下:
/*
* 菜单数组
* module
* 后台角色组菜单分配
*/
function menuRoleAdmin()
{
$array = array(
array(
'id' => 'menu-system',
'icon' => 'xe61d',
'name' => '平台信息',
'info' => array(
array('urls' => 'Index/systemSettings','data' => '','names' => '平台信息设置'),
),
),
array(
'id' => 'menu-user',
'icon' => 'xe62b',
'name' => '用户管理',
'info' => array(
array('urls' => 'Role/usersList','data' => '','names' => '用户列表'),
array('urls' => 'Agent/agentList','data' => '','names' => '代理商名单'),
array('urls' => 'Agent/offlineList','data' => '','names' => '线下人员名单'),
array('urls' => 'Role/roleList','data' => '','names' => '角色列表'),
array('urls' => 'Role/permList','data' => '','names' => '权限列表'),
),
),
array(
'id' => 'menu-personal',
'icon' => 'xe62d',
'name' => '个人详情',
'info' => array(
array('urls' => 'Agent/editAgent','data' => ['uid' => 2,'type' => 2],'names' => '个人详情'),
),
),
array(
'id' => 'menu-log',
'icon' => 'xe623',
'name' => '操作日志',
'info' => array(
array('urls' => 'Log/logList','data' => '','names' => '操作日志'),
),
)
);
return $array;
}
在模板页输出的时候类似于下图:
以下是在后台首页输出的html
<aside class="Hui-aside">
<div class="menu_dropdown bk_2">
{volist name="menuInfo" id="v1"}
<dl id="{$v1.id}">
<dt><i class="Hui-iconfont">&#{$v1.icon};</i> {$v1.name}<i class="Hui-iconfont menu_dropdown-arrow"></i></dt>
<dd>
<ul>
{volist name="v1.info" id="v2"}
{if condition="($v2['data'] neq '')"}
<li><a data-href="{:url($v2['urls'],$v2['data'])}" data-title="{$v2.names}" href="javascript:;">{$v2.names}</a></li>
{else /}
<li><a data-href="{:url($v2['urls'])}" data-title="{$v2.names}" href="javascript:;">{$v2.names}</a></li>
{/if}
{/volist}
</ul>
</dd>
</dl>
{/volist}
</div>
</aside>
灰色部分就是一级菜单,白色部分就是二级菜单,在页面可以进行勾选,复选框的value我定义成的(一级菜单键值-二级菜单键值),提交后的数据使用英文逗号连接 implode('module/a')组成数组:
//$arr = ['0-0','1-0','1-1','1-2','1-3','2-0','3-0']; //数组本来模样
$arr = ['1-0','1-1','1-3','3-0']; //移除部分菜单后菜单,1-0是键值
foreach($arr as $k => $v){ //封装一级菜单
$strs = explode('-',$v);
$arrs[$k] = $strs[0];
}
$arrs = array_unique($arrs); //一级菜单去重
foreach($arrs as $k1 => $v1){
foreach($arr as $k2 => $v2){
$str = explode('-',$v2);
if($v1 == $str[0]){
$iskey = array_key_exists(1, $str); //判断数组是否有当前下标
$module[$v1][] = empty($iskey) ? '' : $str[1]; //按照一级菜单键值,封装整个菜单组
}
}
}
//var_dump($array);
//打印后格式如下,这里需要注意,数组的第一个[1] 为一级菜单的键值,而二级菜单的键值实际应该是[0] => 0,对应的这个0,是值,不是键值了
Array
(
[1] => Array
(
[0] => 0
[1] => 1
[2] => 3 //这里可以看出区别
)
[3] => Array
(
[0] => 0
)
)
//数据在数据表中的格式 1-0,1-1,1-3,3-0 ,怎样根据这个格式来删除禁用的菜单呢
//需要用到一些函数在下一篇博客中会强调
$menuInfo = menuRoleAdmin(); //调用菜单函数,获取菜单
$arrKey1 = array_keys($menuInfo); //获取菜单父级键值
$arrKey2 = array_keys($arr); //获取模块父级键值
$arrKey3 = array_diff($arrKey1,$arrKey2); //按照值删除数组
$menuInfo = array_diff_key($menuInfo,$arrKey3); //去除非选中的父级菜单
foreach($arr as $kk1 => $vv1){
//判断管理员是否分配权限
if(empty($menuInfo)){
layui_back("管理员未分配菜单模块管理权限!",5);
}
$arrKey4 = array_keys($menuInfo[$kk1]['info']); //获取菜单子级键值
$arrKey5 = array_values($arr[$kk1]); //获取菜单子级(键值 => 值)
$arrKey6 = array_diff($arrKey4,$arrKey5); //按照值删除数组
//去除非选中的子级菜单
$menuInfo[$kk1]['info'] = array_diff_key($menuInfo[$kk1]['info'],$arrKey6);
}
//var_dump($menuInfo)
Array
(
[1] => Array
(
[id] => menu-user
[icon] => xe62b
[name] => 用户管理
[info] => Array
(
[0] => Array
(
[urls] => Role/usersList
[data] =>
[names] => 用户列表
)
[1] => Array
(
[urls] => Agent/agentList
[data] =>
[names] => 代理商名单
)
[3] => Array
(
[urls] => Role/roleList
[data] =>
[names] => 角色列表
)
)
)
[3] => Array
(
[id] => menu-log
[icon] => xe623
[name] => 操作日志
[info] => Array
(
[0] => Array
(
[urls] => Log/logList
[data] =>
[names] => 操作日志
)
)
)
)