【商城后台管理系统】基于TP6开发后台无限极菜单的管理显示与增删改查操作
账号admin 密码123456
权限菜单渲染
数据库后台菜单列表,字段设置,pid 是 菜单列表级别,0代表1级菜单,>0的是二级菜单,并且二级菜单pid字段值需要对应mid字段值,这样才可以相互绑定。每个菜单对应的还有Controller控制器,action方法,都要一一记录,这样才能映射到thinkphp控制器层还有视图层,用来区分每一级菜单的前端视图。从而达到权限控制和权限分配操作,每个控制器和方法都要在数据库表中进行注册绑定分配权限。
新建控制器 Menus.php
<?phpnamespace app\admin\controller;use app\BaseController;use think\facade\Session;use think\facade\View;use think\facade\Db;use think\facade\Cache;use think\facade\Request;use app\admin\controller\Base;/** * 菜单管理 */class Menus extends Base{ // 菜单列表 public function index(){ // 接收查看下级菜单pid 如果不存在默认为0,展示一级菜单 $pid = input('get.pid',0); // 接收返回上一级菜单ppid $ppid = input('get.ppid',0); // 查询上一级菜单,用他的pid查询出所有同级菜单 if($ppid>0){ $pmenu = Db::table('admin_menu')->field('pid')->where('mid',$ppid)->find(); $pid = $pmenu['pid']; } // 根据pid查询出上一级菜单记录 if($pid>0){ $data['menu'] = Db::table('admin_menu')->where('mid',$pid)->find(); }else{ // 否则当前就是顶级菜单,没有点击查询下级菜单 所有当前上级菜单为空 $data['menu'] = []; } // 查询菜单 $data['menuList'] = Db::table('admin_menu')->where('pid',$pid)->select()->toArray(); $data['pid'] = $pid; View::assign($data); return View::fetch('menus/index'); } // 添加菜单 public function add(){ if(Request::isPost()){ $data = Request::post(); // 查询菜单名称是否存在 $menu = Db::table('admin_menu')->where('title',$data['title'])->find(); if(!empty($menu)){ exit(json_encode(array('code'=>1,'msg'=>'菜单名称已存在'))); } // 添加数据 $res = Db::table('admin_menu')->save($data); // 添加成功 if(empty($res)){ exit(json_encode(array('code'=>1,'msg'=>'添加失败'))); } // 清除缓存菜单 Cache::delete('menus'); exit(json_encode(array('code'=>0,'msg'=>'添加成功'))); }else{ // 一级菜单添加pid默认层级为0 下级菜单添加传递上一级的mid作为pid $pid = Request::get('pid',0); $controller = Request::get('controller',''); View::assign([ 'pid'=>$pid, 'controller'=>$controller ]); return view('/menus/add'); } } // 修改菜单 public function edit(){ if(Request::isPost()){ $data = Request::post(); // 查询菜单名称是否存在 $menu = Db::table('admin_menu')->where('title',$data['title'])->where('mid','<>',$data['mid'])->find(); if(!empty($menu)){ exit(json_encode(array('code'=>1,'msg'=>'菜单名称已存在'))); } // 修改数据 $res = Db::table('admin_menu')->save($data); // 修改成功 if(empty($res)){ exit(json_encode(array('code'=>1,'msg'=>'修改失败'))); } // 清除缓存菜单 Cache::delete('menus'); exit(json_encode(array('code'=>0,'msg'=>'修改成功,请刷新浏览器查看'))); }else{ $mid = (int)input('get.mid'); $data['menu'] = Db::table('admin_menu')->where('mid',$mid)->find(); return view('/menus/edit',$data); } } // 删除菜单 public function del(){ $mid = Request::post('mid'); $res = DB::table('admin_menu')->where('mid',$mid)->delete(); if(!$res){ exit(json_encode(array('code'=>1,'msg'=>'删除失败'))); } exit(json_encode(array('code'=>0,'msg'=>'删除成功'))); }}
权限菜单列表 视图 Menus/index.php
<!DOCTYPE html><html><head> <title></title> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <script type="text/javascript" src="/static/layui/layui.js"></script></head><body style="padding: 20px;"> <div class="layui-card"> <div class="layui-card-header"><h3>权限列表</h3></div> <div class="layui-card-body"> <span class="layui-breadcrumb"> <a>权限列表</a> {if $menu} <a href="/admin/menus/index"><cite>{$menu['title']}</cite></a> <a href="javascript:;" onclick="back({$pid})"><span class="layui-badge-dot layui-bg-red"></span><cite>返回上级</cite></a> {else/} <a href="/admin/menus/index"><cite>一级菜单</cite></a> {/if} </span> <button style="float: right;" type="button" class="layui-btn layui-btn-primary layui-border-blue" onclick="add({if $menu}{$menu['mid']},'{$menu['controller']}','{$menu['title']}'{/if})"> <i class="layui-icon layui-icon-add-1"></i>添加 <span class="layui-badge-dot layui-bg-blue"></span> </button> <table class="layui-table" > <thead> <tr> <th>序号</th> <th>ID</th> <th>菜单名称</th> <th>控制器</th> <th>方法名</th> <th>是否隐藏</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> {if $menuList} {foreach $menuList as $k=>$menu} <tr> <td>{$k+1}</td> <td>{$menu['mid']}</td> <td>{$menu['title']}</td> <td> <span class="layui-badge layui-bg-cyan">{$menu['controller']}</span> </td> <td>{$menu['action']}</td> <td> {if($menu['ishidden']==0)} <span class="layui-badge layui-bg-green">显示</span> {else if/} <span class="layui-badge layui-bg-red">隐藏</span> {/if} </td> <td> {if($menu['status']==0)} <span class="layui-badge layui-bg-green">开启</span> {else if/} <span class="layui-badge layui-bg-red">禁用</span> {/if} </td> <td> <button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="child({$menu['mid']})"> <i class="layui-icon layui-icon-list"></i>下级菜单 </button> <button type="button" class="layui-btn layui-btn-xs" onclick="edit({$menu['mid']})"> <i class="layui-icon layui-icon-edit"></i>修改菜单 </button> <button type="button" class="layui-btn layui-btn-xs layui-bg-red" onclick="del({$menu['mid']})"> <i class="layui-icon layui-icon-delete "></i>删除菜单 </button> </td> </tr> {/foreach} {else/} <h3 style="text-align: center;font-size: 18px;color: #eee">占无子菜单,请点击右上角添加按钮……</h3> {/if} </tbody> </table> </div> </div></body></html><script> $ = layui.jquery; // 添加菜单 function add(pid=0,controller='',title="顶级"){ layer.open({ type: 2, title:`添加${title}的菜单`, shadeClose: false, maxmin: true, shade:0.8, area:['480px','450px'], content:`/admin/menus/add?pid=${pid}&controller=${controller}` }); } // 修改菜单 function edit(mid){ layer.full(layer.open({ type: 2, title:'修改菜单', shadeClose: false, maxmin: true, shade:0.8, area:['480px','450px'], content:'/admin/menus/edit?mid='+mid })); } // 删除菜单 function del(mid){ layer.confirm('确定要删除吗?',{ icon:3, btn: ['确定','取消'] },function(){ $.post('/admin/menus/del',{'mid':mid},function(res){ if(res.code>0){ layer.alert(res.msg,{icon:2}); }else{ layer.msg(res.msg); setTimeout(function(){window.location.reload();},1000); } },'json'); }); } // 查看下级菜单 function child(mid){ window.location.href = `/admin/menus/index?pid=${mid}`; } // 返回上级菜单 function back(pid){ window.location.href = `/admin/menus/index?ppid=${pid}`; }</script>
添加视图 add.php
<!DOCTYPE html><html><head> <title></title> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <script type="text/javascript" src="/static/layui/layui.js"></script></head><body> <div class="layui-form" style="padding: 10px;"> <input type="hidden" name="pid" value="{$pid}"> <div class="layui-form-item"> <label class="layui-form-label">菜单名称</label> <div class="layui-input-block"> <input type="text" class="layui-input" name="title" placeholder="请输入菜单名称"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">控制器名称</label> <div class="layui-input-inline"> <input type="text" class="layui-input" name="controller" placeholder="控制名称" value="{$controller}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">方法名称</label> <div class="layui-input-inline"> <input type="text" class="layui-input" name="action" placeholder="{if ($pid==0)}【选填】{/if}方法名称"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">状态</label> <div class="layui-input-block"> <input type="checkbox" lay-skin="primary" name="status" title="禁用"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">是否显示</label> <div class="layui-input-block"> <input type="checkbox" checked name="ishidden" lay-skin="switch" lay-filter="switchTest" lay-text="显示|隐藏"> </div> </div> <div class="layui-input-block"> <button class="layui-btn" onclick="save()">保存</button> </div> </div></body></html><script type="text/javascript"> $ = layui.jquery; // 回车保存 $('input').keydown(function(e){ if(e.keyCode == 13){ save(); } }); // 保存修改 function save(){ var mid = $('input[name="mid"]').val(); var pid = $('input[name="pid"]').val(); var title = $('input[name="title"]').val(); var controller = $('input[name="controller"]').val(); var action = $('input[name="action"]').val(); var status = $('input[name="status"]').is(':checked')?1:0; var ishidden = $('input[name="ishidden"]').is(':checked')?0:1; if(title==''){ return layer.alert('导航菜单名称不能为空',{icon:2}); } if(controller==''){ return layer.alert('控制器名称不能为空',{icon:2}); } if(pid>0){ if(action==''){ return layer.alert('方法名称不能为空',{icon:2}); } } // 提交信息 var data = { mid:mid, pid:pid, title:title, controller:controller, action:action, status:status, ishidden:ishidden }; // 提交修改 $.post('/admin/menus/add',data,function(res){ // 验证返回 if(res.code>0){ return layer.alert(res.msg,{icon:2}); } layer.alert(res.msg,{icon:1}); setTimeout(function(){ parent.window.location.reload(); },1000); },'json'); }</script>
编辑视图
<!DOCTYPE html><html><head> <title></title> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <script type="text/javascript" src="/static/layui/layui.js"></script></head><body> <div class="layui-form" style="padding: 10px;"> <input type="hidden" name="mid" value="{$menu['mid']}"> <div class="layui-form-item"> <label class="layui-form-label">菜单名称</label> <div class="layui-input-block"> <input type="text" class="layui-input" name="title" value="{$menu['title']}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">控制器名称</label> <div class="layui-input-inline"> <input type="text" class="layui-input" name="controller" placeholder="控制名称" value="{$menu['controller']}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">方法名称</label> <div class="layui-input-inline"> <input type="text" class="layui-input" name="action" placeholder="【选填】方法名称" value="{$menu['action']}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">是否显示</label> <div class="layui-input-block"> <input type="checkbox" {$menu['ishidden']==0?'checked':''} name="ishidden" lay-skin="switch" lay-filter="switchTest" lay-text="显示|隐藏"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">状态</label> <div class="layui-input-block"> <input type="checkbox" {$menu['status']==1?'checked':''} lay-skin="primary" name="status" title="禁用"> </div> </div> <div class="layui-input-block"> <button class="layui-btn" onclick="save()">保存</button> </div> </div></body></html><script type="text/javascript"> $ = layui.jquery; // 回车保存 $('input').keydown(function(e){ if(e.keyCode == 13){ save(); } }); // 保存修改 function save(){ var mid = $('input[name="mid"]').val(); var title = $('input[name="title"]').val(); var controller = $('input[name="controller"]').val(); var action = $('input[name="action"]').val(); var status = $('input[name="status"]').is(':checked')?1:0; var ishidden = $('input[name="ishidden"]').is(':checked')?0:1; // 提交信息 var data = { mid:mid, title:title, controller:controller, action:action, status:status, ishidden:ishidden }; // 提交修改 $.post('/admin/menus/edit',data,function(res){ // 验证返回 if(res.code>0){ return layer.alert(res.msg,{icon:2}); } layer.alert(res.msg,{icon:1}); setTimeout(function(){ parent.window.location.reload(); },1000); },'json'); }</script>
权限菜单的一般数据结构如下:
array (size=35) 0 => array (size=9) 'id' => int 21 'pid' => int 0 'name' => string 'Admin/ShowNav/rule' (length=18) 'title' => string '权限控制' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 0 1 => array (size=9) 'id' => int 7 'pid' => int 21 'name' => string 'Admin/Rule/index' (length=16) 'title' => string '权限管理' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 2 => array (size=9) 'id' => int 8 'pid' => int 7 'name' => string 'Admin/Rule/add' (length=14) 'title' => string '添加权限' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 3 => array (size=9) 'id' => int 9 'pid' => int 7 'name' => string 'Admin/Rule/edit' (length=15) 'title' => string '修改权限' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 4 => array (size=9) 'id' => int 10 'pid' => int 7 'name' => string 'Admin/Rule/delete' (length=17) 'title' => string '删除权限' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 5 => array (size=9) 'id' => int 11 'pid' => int 21 'name' => string 'Admin/Rule/group' (length=16) 'title' => string '用户组管理' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 6 => array (size=9) 'id' => int 12 'pid' => int 11 'name' => string 'Admin/Rule/add_group' (length=20) 'title' => string '添加用户组' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 7 => array (size=9) 'id' => int 13 'pid' => int 11 'name' => string 'Admin/Rule/edit_group' (length=21) 'title' => string '修改用户组' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 8 => array (size=9) 'id' => int 14 'pid' => int 11 'name' => string 'Admin/Rule/delete_group' (length=23) 'title' => string '删除用户组' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 9 => array (size=9) 'id' => int 15 'pid' => int 11 'name' => string 'Admin/Rule/rule_group' (length=21) 'title' => string '分配权限' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 10 => array (size=9) 'id' => int 16 'pid' => int 11 'name' => string 'Admin/Rule/check_user' (length=21) 'title' => string '添加成员' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 11 => array (size=9) 'id' => int 123 'pid' => int 11 'name' => string 'Admin/Rule/add_user_to_group' (length=28) 'title' => string '设置为管理员' (length=18) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 12 => array (size=9) 'id' => int 124 'pid' => int 11 'name' => string 'Admin/Rule/add_admin' (length=20) 'title' => string '添加管理员' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 13 => array (size=9) 'id' => int 125 'pid' => int 11 'name' => string 'Admin/Rule/edit_admin' (length=21) 'title' => string '修改管理员' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 14 => array (size=9) 'id' => int 19 'pid' => int 21 'name' => string 'Admin/Rule/admin_user_list' (length=26) 'title' => string '管理员列表' (length=15) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 15 => array (size=9) 'id' => int 20 'pid' => int 0 'name' => string 'Admin/ShowNav/config' (length=20) 'title' => string '系统设置' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 0 16 => array (size=9) 'id' => int 1 'pid' => int 20 'name' => string 'Admin/ShowNav/nav' (length=17) 'title' => string '菜单管理' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 17 => array (size=9) 'id' => int 2 'pid' => int 1 'name' => string 'Admin/Nav/index' (length=15) 'title' => string '菜单列表' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 18 => array (size=9) 'id' => int 3 'pid' => int 1 'name' => string 'Admin/Nav/add' (length=13) 'title' => string '添加菜单' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 19 => array (size=9) 'id' => int 4 'pid' => int 1 'name' => string 'Admin/Nav/edit' (length=14) 'title' => string '修改菜单' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 20 => array (size=9) 'id' => int 5 'pid' => int 1 'name' => string 'Admin/Nav/delete' (length=16) 'title' => string '删除菜单' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 21 => array (size=9) 'id' => int 64 'pid' => int 1 'name' => string 'Admin/Nav/order' (length=15) 'title' => string '菜单排序' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 22 => array (size=9) 'id' => int 6 'pid' => int 0 'name' => string 'Admin/Index/index' (length=17) 'title' => string '后台首页' (length=12) 'status' => int 1 'display' => int 0 'type' => int 1 'condition' => string '' (length=0) 'level' => int 0 23 => array (size=9) 'id' => int 96 'pid' => int 6 'name' => string 'Admin/Index/welcome' (length=19) 'title' => string '欢迎界面' (length=12) 'status' => int 1 'display' => int 0 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 24 => array (size=9) 'id' => int 104 'pid' => int 0 'name' => string 'Admin/ShowNav/posts' (length=19) 'title' => string '文章管理' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 0 25 => array (size=9) 'id' => int 105 'pid' => int 104 'name' => string 'Admin/Posts/index' (length=17) 'title' => string '文章列表' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 26 => array (size=9) 'id' => int 106 'pid' => int 105 'name' => string 'Admin/Posts/add_posts' (length=21) 'title' => string '添加文章' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 27 => array (size=9) 'id' => int 107 'pid' => int 105 'name' => string 'Admin/Posts/edit_posts' (length=22) 'title' => string '修改文章' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 28 => array (size=9) 'id' => int 108 'pid' => int 105 'name' => string 'Admin/Posts/delete_posts' (length=24) 'title' => string '删除文章' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 29 => array (size=9) 'id' => int 118 'pid' => int 105 'name' => string 'Admin/Posts/order_posts' (length=23) 'title' => string '文章排序' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 30 => array (size=9) 'id' => int 109 'pid' => int 104 'name' => string 'Admin/Posts/category_list' (length=25) 'title' => string '分类列表' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 1 31 => array (size=9) 'id' => int 110 'pid' => int 109 'name' => string 'Admin/Posts/add_category' (length=24) 'title' => string '添加分类' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 32 => array (size=9) 'id' => int 111 'pid' => int 109 'name' => string 'Admin/Posts/edit_category' (length=25) 'title' => string '修改分类' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 33 => array (size=9) 'id' => int 112 'pid' => int 109 'name' => string 'Admin/Posts/delete_category' (length=27) 'title' => string '删除分类' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2 34 => array (size=9) 'id' => int 117 'pid' => int 109 'name' => string 'Admin/Posts/order_category' (length=26) 'title' => string '分类排序' (length=12) 'status' => int 1 'display' => int 1 'type' => int 1 'condition' => string '' (length=0) 'level' => int 2