博客列表 >laravel--通用后台管理系统--添加菜单--角色添加权限--根据用户权限显示菜单

laravel--通用后台管理系统--添加菜单--角色添加权限--根据用户权限显示菜单

王娇
王娇原创
2020年06月22日 17:29:253123浏览

学习总结

1.layui中的form.render()方法在使用过程中,只能渲染2次,问题在角色权限的添加和修改,全选和一级菜单只能选中和取消只能使用一次,第2次点击就不能渲染到复选框上了

2.在权限中间件RightsVerify.php中为Request对象添加rights属性,在Home控制器中使用whereIn()方法查找符合当前用户的权限菜单。

**问题**

使用form.render()方法无法连续渲染复选框,实现复选框菜单联动

**解决方法

不使用layui中的form.render()方法,使用jquery实现渲染$('input[type="checkbox"]~div').addClass('layui-form-checked'); 因为美化后的复选框是一个div,并且和input的checkbox在同一个大的div中,所以使用同级选择器,选中美化后的div,然后添加css样式。

1.菜单控制器Menu.php

  1. <?php
  2. namespace App\Http\Controllers\admins;
  3. use App\Http\Controllers\Controller;
  4. use Illuminate\Support\Facades\Hash;//哈希密码加密
  5. use Illuminate\Http\Request;
  6. //引入数据库查询构造器,链式调用
  7. use Illuminate\Support\Facades\DB;
  8. //后台菜单管理控制器
  9. class Menus extends Controller
  10. {
  11. //菜单列表
  12. public function index(Request $req)
  13. {
  14. $pid =(int)$req->pid;
  15. if($pid):
  16. //找到菜单的上一级菜单
  17. $res['pMenu']=DB::table('admin_menu')->select('mid','pid','title')->where('mid',$pid)->item();
  18. else:
  19. $res['pMenu']['mid']=0;
  20. endif;
  21. $res['menus']=DB::table('admin_menu')->where('pid',$pid)->lists();
  22. return view('/admins/menus/index',$res);
  23. // echo '<pre>';
  24. // print_r($res);
  25. // exit;
  26. }
  27. //添加菜单
  28. public function add(Request $req)
  29. {
  30. $res['pid'] = $req->pid;
  31. return view('/admins/menus/add',$res);
  32. }
  33. //保存菜单
  34. public function save(Request $req)
  35. {
  36. $mid =(int) $req->mid;
  37. //如果mid为0,代表是添加,否则代表是修改
  38. //菜单的pid,上一级菜单的id
  39. $data['pid'] =(int) $req->pid;
  40. //判断菜单名称是否为空
  41. if(trim($req->title)===''):
  42. return json_encode(['status'=>'1','msg'=>'菜单名称不能为空']);
  43. endif;
  44. $data['title'] = trim($req->title);
  45. //如果ishidden='on',正常显示的菜单
  46. if($req->ishidden):
  47. $data['ishidden'] = (int)'0';//代表正常显示菜单
  48. else:
  49. $data['ishidden'] = (int)'1';//代表隐藏菜单
  50. endif;
  51. //排序
  52. $data['ord'] =(int)$req->ord;
  53. //判断是否输入控制器
  54. if(trim($req->controller)===''):
  55. return json_encode(['status'=>'1','msg'=>'控制器名称不能为空']);
  56. endif;
  57. $data['controller'] = trim($req->controller);
  58. //控制器方法
  59. $data['action'] = trim($req->action);
  60. if($mid):
  61. $res = DB::table('admin_menu')->where('mid',$mid)->update($data);
  62. else:
  63. $res = DB::table('admin_menu')->insert($data);
  64. endif;
  65. if($res):
  66. return json_encode(['status'=>'0','msg'=>'保存成功']);
  67. else:
  68. return json_encode(['status'=>'1','msg'=>'保存失败']);
  69. endif;
  70. }
  71. public function del(Request $req)
  72. {
  73. $mid = $req->mid;
  74. $res = DB::table('admin_menu')->where('mid',$mid)->delete();
  75. if($res)
  76. {
  77. return json_encode(['status'=>'0','msg'=>'删除成功']);
  78. }
  79. else
  80. {
  81. return json_encode(['status'=>'1','msg'=>'删除失败']);
  82. }
  83. }
  84. public function edit(Request $req)
  85. {
  86. $mid = $req->mid;
  87. $res['menu'] = DB::table('admin_menu')->where('mid',$mid)->item();
  88. return view('/admins/menus/edit',$res);
  89. }
  90. }

1.1菜单列表的显示index.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>菜单管理</title>
  9. </head>
  10. <style>
  11. .addBtn {
  12. margin-top: 10px;
  13. width: 120px;
  14. margin-left: auto;
  15. margin-right: 50px;
  16. }
  17. .pMenuBtn {
  18. margin-left: 10px;
  19. }
  20. .layui-table {
  21. width: 95%;
  22. margin: 20px;
  23. }
  24. </style>
  25. <body>
  26. <div class="addBtn">
  27. <button class="layui-btn" onclick="add({{$pMenu['mid']}})">添加菜单</button>
  28. </div>
  29. @if($pMenu['mid'])
  30. <div class="pMenuBtn">
  31. <button class="layui-btn layui-btn-primary" onclick="back({{$pMenu['pid']}})">返回『{{$pMenu['title']}}』菜单</button>
  32. </div>
  33. @endif
  34. <table class="layui-table">
  35. <thead>
  36. <tr>
  37. <th>MID</th>
  38. <th>菜单名称</th>
  39. <th>是否隐藏</th>
  40. <th>排序</th>
  41. <th>controller</th>
  42. <th>action</th>
  43. <th>操作</th>
  44. </tr>
  45. </thead>
  46. <tbody>
  47. @foreach($menus as $menu)
  48. <tr>
  49. <td>{{$menu['mid']}}</td>
  50. <td>{{$menu['title']}}</td>
  51. <td>{{$menu['ishidden']?'是':'否'}}</td>
  52. <td>{{$menu['ord']}}</td>
  53. <td>{{$menu['controller']}}</td>
  54. <td>{{$menu['action']}}</td>
  55. <td>
  56. <button class="layui-btn layui-btn-xs layui-btn-primary"
  57. onclick="child({{$menu['mid']}})">下级菜单</button>
  58. <button class="layui-btn layui-btn-xs" onclick="edit({{$menu['mid']}})">修改</button>
  59. <button class="layui-btn layui-btn-xs layui-btn-danger" onclick="del({{$menu['mid']}})">删除</button>
  60. </td>
  61. </tr>
  62. @endforeach
  63. </tbody>
  64. </table>
  65. </body>
  66. <script>
  67. layui.use(['layer'], function() {
  68. layer = layui.layer;
  69. $ = layui.jquery;
  70. });
  71. //显示下级菜单
  72. function child(id) {
  73. window.location.href = '/admins/menus/index?pid=' + id;
  74. }
  75. //返回上级菜单
  76. function back(id) {
  77. window.location.href = '/admins/menus/index?pid=' + id;
  78. }
  79. //添加菜单
  80. function add(pid) {
  81. //iframe层
  82. layer.open({
  83. type: 2,
  84. title: '添加菜单',
  85. shadeClose: true,
  86. shade: 0.8,
  87. area: ['380px', '80%'],
  88. content: '/admins/menus/add?pid=' + pid, //iframe的url
  89. btn: ['保存'],
  90. yes: function(index, layero) {
  91. //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.子页面的方法名称();
  92. var iframeWin = window[layero.find('iframe')[0]['name']];;
  93. iframeWin.save();
  94. }
  95. });
  96. }
  97. //修改菜单
  98. function edit(id) {
  99. //iframe层
  100. layer.open({
  101. type: 2,
  102. title: '修改菜单',
  103. shadeClose: true,
  104. shade: 0.8,
  105. area: ['380px', '80%'],
  106. content: '/admins/menus/edit?mid=' + id, //iframe的url
  107. btn: ['保存'],
  108. yes: function(index, layero) {
  109. //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.子页面的方法名称();
  110. var iframeWin = window[layero.find('iframe')[0]['name']];;
  111. iframeWin.save();
  112. }
  113. });
  114. }
  115. //删除菜单
  116. function del(id) {
  117. layer.confirm('确认要删除菜单吗?', function() {
  118. $.get('/admins/menus/del?mid=' + id, function(res) {
  119. if (res.status > 0) {
  120. layer.alert(res.msg, {
  121. icon: 2
  122. });
  123. } else {
  124. layer.msg(res.msg, {
  125. time: 3000
  126. });
  127. window.location.reload();
  128. }
  129. }, 'json');
  130. });
  131. }
  132. </script>
  133. </html>
  • 一级菜单

  • 一级菜单下的子菜单

1.2 添加菜单add.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>添加菜单</title>
  9. <style>
  10. .layui-form {
  11. margin-top: 20px;
  12. margin-right: 20px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="" class="layui-form">
  18. @csrf
  19. <input type="hidden" name="pid" value="{{$pid}}">
  20. <div class="layui-form-item">
  21. <label for="" class="layui-form-label">菜单名称</label>
  22. <div class="layui-input-inline">
  23. <input type="text" class="layui-input" name="title">
  24. </div>
  25. </div>
  26. <div class="layui-form-item">
  27. <label for="" class="layui-form-label">是否隐藏</label>
  28. <div class="layui-input-inline">
  29. <input type="checkbox" name="ishidden" lay-skin='switch' lay-text='正常|隐藏'>
  30. </div>
  31. </div>
  32. <div class="layui-form-item">
  33. <label for="" class="layui-form-label">排序</label>
  34. <div class="layui-input-inline">
  35. <input type="number" class="layui-input" name="ord" value="0">
  36. </div>
  37. </div>
  38. <div class="layui-form-item">
  39. <label for="" class="layui-form-label">controller</label>
  40. <div class="layui-input-inline">
  41. <input type="text" class="layui-input" name="controller">
  42. </div>
  43. </div>
  44. <div class="layui-form-item">
  45. <label for="" class="layui-form-label">action</label>
  46. <div class="layui-input-inline">
  47. <input type="text" class="layui-input" name="action">
  48. </div>
  49. </div>
  50. </form>
  51. </body>
  52. <script>
  53. layui.use(['form', 'layer'], function() {
  54. var form = layui.form;
  55. var layer = layui.layer;
  56. $ = layui.jquery;
  57. });
  58. //在父窗口中调用了save方法
  59. function save() {
  60. if ($('input[name="title"]').val().trim() === '') {
  61. error('请输入菜单名称');
  62. return false;
  63. }
  64. if ($('input[name="controller"]').val().trim() === '') {
  65. error('请输入控制器');
  66. return false;
  67. }
  68. //把form表单中的数据序列化后通过post提交
  69. var form = $('form').serialize();
  70. console.log(form);
  71. $.post('/admins/menus/save',
  72. form,
  73. function(res) {
  74. if (res.status > 0) {
  75. error(res.msg);
  76. } else {
  77. layer.msg(res.msg);
  78. setTimeout(function() {
  79. //假设这是iframe页
  80. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  81. //关闭当前窗口
  82. parent.layer.close(index); //再执行关闭
  83. //刷新父窗口,重新显示账号管理员列表
  84. parent.window.location.reload();
  85. }, 1000);
  86. }
  87. }, 'json');
  88. function error(msg) {
  89. layer.alert(msg, {
  90. icon: 2
  91. });
  92. }
  93. }
  94. </script>
  95. </html>

1.3修改菜单edit.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>添加菜单</title>
  9. <style>
  10. .layui-form {
  11. margin-top: 20px;
  12. margin-right: 20px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="" class="layui-form">
  18. @csrf
  19. <input type="hidden" name="mid" value="{{$menu['mid']}}">
  20. <input type="hidden" name="pid" value="{{$menu['pid']}}">
  21. <div class="layui-form-item">
  22. <label for="" class="layui-form-label">菜单名称</label>
  23. <div class="layui-input-inline">
  24. <input type="text" class="layui-input" name="title" value="{{$menu['title']}}">
  25. </div>
  26. </div>
  27. <div class="layui-form-item">
  28. <label for="" class="layui-form-label">是否隐藏</label>
  29. <div class="layui-input-inline">
  30. <input type="checkbox" name="ishidden" lay-skin='switch' lay-text='正常|隐藏'
  31. {{$menu['ishidden']?'':'checked'}}>
  32. </div>
  33. </div>
  34. <div class="layui-form-item">
  35. <label for="" class="layui-form-label">排序</label>
  36. <div class="layui-input-inline">
  37. <input type="number" class="layui-input" name="ord" value="{{$menu['ord']}}">
  38. </div>
  39. </div>
  40. <div class="layui-form-item">
  41. <label for="" class="layui-form-label">controller</label>
  42. <div class="layui-input-inline">
  43. <input type="text" class="layui-input" name="controller" value="{{$menu['controller']}}">
  44. </div>
  45. </div>
  46. <div class="layui-form-item">
  47. <label for="" class="layui-form-label">action</label>
  48. <div class="layui-input-inline">
  49. <input type="text" class="layui-input" name="action" value="{{$menu['action']}}">
  50. </div>
  51. </div>
  52. </form>
  53. </body>
  54. <script>
  55. layui.use(['form', 'layer'], function() {
  56. var form = layui.form;
  57. var layer = layui.layer;
  58. $ = layui.jquery;
  59. });
  60. //在父窗口中调用了save方法
  61. function save() {
  62. if ($('input[name="title"]').val().trim() === '') {
  63. error('请输入菜单名称');
  64. return false;
  65. }
  66. if ($('input[name="controller"]').val().trim() === '') {
  67. error('请输入控制器');
  68. return false;
  69. }
  70. //把form表单中的数据序列化后通过post提交
  71. var form = $('form').serialize();
  72. console.log(form);
  73. $.post('/admins/menus/save',
  74. form,
  75. function(res) {
  76. if (res.status > 0) {
  77. error(res.msg);
  78. } else {
  79. layer.msg(res.msg);
  80. setTimeout(function() {
  81. //假设这是iframe页
  82. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  83. //关闭当前窗口
  84. parent.layer.close(index); //再执行关闭
  85. //刷新父窗口,重新显示账号管理员列表
  86. parent.window.location.reload();
  87. }, 1000);
  88. }
  89. }, 'json');
  90. function error(msg) {
  91. layer.alert(msg, {
  92. icon: 2
  93. });
  94. }
  95. }
  96. </script>
  97. </html>

2.角色控制器Groups.php

  1. <?php
  2. namespace App\Http\Controllers\admins;
  3. use App\Http\Controllers\Controller;
  4. use Illuminate\Support\Facades\Hash;//哈希密码加密
  5. use Illuminate\Http\Request;
  6. //引入数据库查询构造器,链式调用
  7. use Illuminate\Support\Facades\DB;
  8. //后台角色管理控制器
  9. class Groups extends Controller
  10. {
  11. public function index()
  12. {
  13. $res['groups'] = DB::table('admin_group')->lists();
  14. return view('/admins/groups/index',$res);
  15. }
  16. public function add()
  17. {
  18. //查出所有可用的菜单
  19. $menus = [];
  20. $menus = DB::table('admin_menu')->where('status',0)->lists();
  21. $res['pMenus'] = [];
  22. foreach($menus as $menu):
  23. if($menu['pid']=='0'):
  24. $res['pMenus'][]=$menu;
  25. $res['cMenus'][$menu['mid']]=[];
  26. else:
  27. $res['cMenus'][$menu['pid']][]=$menu;
  28. endif;
  29. endforeach;
  30. // echo '<pre>';
  31. // print_r($res);
  32. // exit;
  33. return view('/admins/groups/add',$res);
  34. }
  35. public function save(Request $req)
  36. {
  37. if(trim($req->title)==""):
  38. return json_encode(['status'=>'1','msg'=>'必须输入角色名称']);
  39. endif;
  40. $data['title'] =trim($req->title) ;
  41. if($req->menus):
  42. $data['rights'] =json_encode(array_keys($req->menus));
  43. else:
  44. $data['rights']='';
  45. endif;
  46. $gid = (int)$req->gid;
  47. if($gid):
  48. $res = DB::table('admin_group')->where('gid',$gid)->update($data);
  49. else:
  50. $res = DB::table('admin_group')->insert($data);
  51. endif;
  52. if($res):
  53. return json_encode(['status'=>'0','msg'=>'保存成功']);
  54. else:
  55. return json_encode(['status'=>'1','msg'=>'保存失败']);
  56. endif;
  57. exit;
  58. }
  59. public function edit(Request $req)
  60. {
  61. $gid = $req->gid;
  62. $res['group'] = DB::table('admin_group')->where('gid',$gid)->item();
  63. $menus = [];
  64. $menus = DB::table('admin_menu')->where('status',0)->lists();
  65. $res['pMenus'] = [];
  66. foreach($menus as $menu):
  67. if($menu['pid']=='0'):
  68. $res['pMenus'][]=$menu;
  69. $res['cMenus'][$menu['mid']]=[];
  70. else:
  71. $res['cMenus'][$menu['pid']][]=$menu;
  72. endif;
  73. endforeach;
  74. $res['group']['rights']=json_decode($res['group']['rights'],true);
  75. // echo '<pre>';
  76. // print_r($res);
  77. // exit;
  78. return view('/admins/groups/edit',$res);
  79. }
  80. public function del(Request $req)
  81. {
  82. $gid = $req->gid;
  83. $res =DB::table('admin_group')->where('gid',$gid)->delete();
  84. if($res)
  85. {
  86. return json_encode(['status'=>'0','msg'=>'删除成功']);
  87. }
  88. else
  89. {
  90. return json_encode(['status'=>'1','msg'=>'删除失败']);
  91. }
  92. }
  93. }

2.1角色列表index.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>角色管理</title>
  9. </head>
  10. <style>
  11. .addBtn {
  12. margin-top: 10px;
  13. width: 120px;
  14. margin-left: auto;
  15. margin-right: 50px;
  16. }
  17. .layui-table {
  18. width: 95%;
  19. margin: 20px;
  20. }
  21. </style>
  22. <body>
  23. <div class="addBtn">
  24. <button class="layui-btn" onclick="add()">添加角色</button>
  25. </div>
  26. <table class="layui-table">
  27. <thead>
  28. <tr>
  29. <th>编号</th>
  30. <th>角色名称</th>
  31. <th>操作</th>
  32. </tr>
  33. </thead>
  34. <tbody>
  35. @foreach($groups as $group)
  36. <tr>
  37. <td>{{$group['gid']}}</td>
  38. <td>{{$group['title']}}</td>
  39. <td>
  40. <button class="layui-btn layui-btn-xs" onclick="edit({{$group['gid']}})">修改</button>
  41. <button class="layui-btn layui-btn-xs layui-btn-danger" onclick="del({{$group['gid']}})">删除</button>
  42. </td>
  43. </tr>
  44. @endforeach
  45. </tbody>
  46. </table>
  47. </body>
  48. <script>
  49. layui.use(['layer'], function() {
  50. layer = layui.layer;
  51. $ = layui.jquery;
  52. });
  53. //添加角色
  54. function add() {
  55. //iframe层
  56. layer.open({
  57. type: 2,
  58. title: '添加角色',
  59. shadeClose: true,
  60. shade: 0.8,
  61. area: ['380px', '80%'],
  62. content: '/admins/groups/add', //iframe的url
  63. btn: ['保存'],
  64. yes: function(index, layero) {
  65. //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.子页面的方法名称();
  66. var iframeWin = window[layero.find('iframe')[0]['name']];;
  67. iframeWin.save();
  68. }
  69. });
  70. }
  71. //修改角色
  72. function edit(id) {
  73. //iframe层
  74. layer.open({
  75. type: 2,
  76. title: '修改角色',
  77. shadeClose: true,
  78. shade: 0.8,
  79. area: ['380px', '80%'],
  80. content: '/admins/groups/edit?gid=' + id, //iframe的url
  81. btn: ['保存'],
  82. yes: function(index, layero) {
  83. //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.子页面的方法名称();
  84. var iframeWin = window[layero.find('iframe')[0]['name']];;
  85. iframeWin.save();
  86. }
  87. });
  88. }
  89. //删除角色
  90. function del(id) {
  91. layer.confirm('确认要删除角色吗?', function() {
  92. $.get('/admins/groups/del?gid=' + id, function(res) {
  93. if (res.status > 0) {
  94. layer.alert(res.msg, {
  95. icon: 2
  96. });
  97. } else {
  98. layer.msg(res.msg, {
  99. time: 3000
  100. });
  101. window.location.reload();
  102. }
  103. }, 'json');
  104. });
  105. }
  106. </script>
  107. </html>

2.2添加角色权限add.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>添加角色</title>
  9. <style>
  10. .layui-form {
  11. margin-top: 20px;
  12. margin-right: 20px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="" class="layui-form" lay-filter='groupForm'>
  18. @csrf
  19. <div class="layui-form-item">
  20. <label for="" class="layui-form-label">角色名称</label>
  21. <div class="layui-input-inline">
  22. <input type="text" class="layui-input" name="title">
  23. </div>
  24. </div>
  25. <div class="layui-form-item">
  26. <div class="layui-input-inline" style="margin-left: 10px;">
  27. <input type="checkbox" title="全选" lay-filter="checkAll">
  28. </div>
  29. </div>
  30. @foreach($pMenus as $pMenu)
  31. <hr>
  32. <div class="layui-form-item">
  33. <div class="layui-input-inline" style="margin-left: 10px;">
  34. <input type="checkbox" title="{{$pMenu['title']}}" value="{{$pMenu['mid']}}"
  35. name="menus[{{$pMenu['mid']}}]" lay-filter="pmenus" group="{{$pMenu['mid']}}">
  36. </div>
  37. </div>
  38. <div class="layui-form-item">
  39. <div class="layui-input-inline" style="margin-left: 50px;">
  40. <?php $childs = $cMenus[$pMenu['mid']]?>
  41. @foreach($childs as $child)
  42. <input type="checkbox" lay-skin="primary" title="{{$child['title']}}" value="{{$child['mid']}}"
  43. name="menus[{{$child['mid']}}]" lay-filter="cmenus-{{$child['pid']}}">
  44. @endforeach()
  45. </div>
  46. </div>
  47. @endforeach
  48. </form>
  49. </body>
  50. <script>
  51. layui.use(['form', 'layer'], function() {
  52. var form = layui.form;
  53. var layer = layui.layer;
  54. $ = layui.jquery;
  55. //全选按钮点击事件
  56. form.on('checkbox(checkAll)', function(data) {
  57. //data.elem.checked检查是否被选中
  58. if (data.elem.checked) {
  59. //全选按钮被选中
  60. $('input[type="checkbox"]').attr('checked', 'true');
  61. //渲染美化后的checkbox
  62. $('input[type="checkbox"]~div').addClass('layui-form-checked');
  63. } else {
  64. $('input[type="checkbox"]').removeAttr('checked');
  65. $('input[type="checkbox"]~div').removeClass('layui-form-checked');
  66. //全选按钮未选中
  67. }
  68. // form.render('checkbox', 'groupForm');
  69. });
  70. //父级菜单选中事件
  71. form.on('checkbox(pmenus)', function(data) {
  72. //data.elem.checked检查是否被选中
  73. var pIndex = $(data.elem).attr('group');
  74. if (data.elem.checked) {
  75. $('input[lay-filter="cmenus-' + pIndex + '"]').attr('checked', 'true');
  76. //渲染美化后的checkbox
  77. $('input[lay-filter="cmenus-' + pIndex + '"]~div').addClass('layui-form-checked');
  78. } else {
  79. $('input[lay-filter="cmenus-' + pIndex + '"]').removeAttr('checked');
  80. $('input[lay-filter="cmenus-' + pIndex + '"]~div').removeClass('layui-form-checked');
  81. }
  82. // form.render('checkbox', 'groupForm');
  83. });
  84. });
  85. //在父窗口中调用了save方法
  86. function save() {
  87. console.log('save');
  88. if ($('input[name="title"]').val().trim() === '') {
  89. error('请输入角色名称');
  90. return false;
  91. }
  92. //把form表单中的数据序列化后通过post提交
  93. var form = $('form').serialize();
  94. $.post('/admins/groups/save',
  95. form,
  96. function(res) {
  97. if (res.status > 0) {
  98. error(res.msg);
  99. } else {
  100. layer.msg(res.msg);
  101. setTimeout(function() {
  102. //假设这是iframe页
  103. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  104. //关闭当前窗口
  105. parent.layer.close(index); //再执行关闭
  106. //刷新父窗口,重新显示账号管理员列表
  107. parent.window.location.reload();
  108. }, 1000);
  109. }
  110. }, 'json');
  111. }
  112. function error(msg) {
  113. layer.alert(msg, {
  114. icon: 2
  115. });
  116. }
  117. </script>
  118. </html>

2.3修改角色权限edit.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  7. <script src="/static/plugins/layui/layui.js"></script>
  8. <title>修改角色</title>
  9. <style>
  10. .layui-form {
  11. margin-top: 20px;
  12. margin-right: 20px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="" class="layui-form" lay-filter='groupForm'>
  18. @csrf
  19. <input type="hidden" name="gid" value="{{$group['gid']}}">
  20. <div class="layui-form-item">
  21. <label for="" class="layui-form-label">角色名称</label>
  22. <div class="layui-input-inline">
  23. <input type="text" class="layui-input" name="title" value="{{$group['title']}}">
  24. </div>
  25. </div>
  26. <div class="layui-form-item">
  27. <div class="layui-input-inline" style="margin-left: 10px;">
  28. <input type="checkbox" title="全选" lay-filter="checkAll">
  29. </div>
  30. </div>
  31. @foreach($pMenus as $pMenu)
  32. <hr>
  33. <div class="layui-form-item">
  34. <div class="layui-input-inline" style="margin-left: 10px;">
  35. <input type="checkbox" title="{{$pMenu['title']}}" value="{{$pMenu['mid']}}"
  36. name="menus[{{$pMenu['mid']}}]" {{in_array($pMenu['mid'],$group['rights'])?'checked':''}}>
  37. </div>
  38. </div>
  39. <div class="layui-form-item">
  40. <div class="layui-input-inline" style="margin-left: 50px;">
  41. <?php $childs = $cMenus[$pMenu['mid']]?>
  42. @foreach($childs as $child)
  43. <input type="checkbox" lay-skin="primary" title="{{$child['title']}}" value="{{$child['mid']}}"
  44. name="menus[{{$child['mid']}}]" {{in_array($child['mid'],$group['rights'])?'checked':''}}>
  45. @endforeach()
  46. </div>
  47. </div>
  48. @endforeach
  49. </form>
  50. </body>
  51. <script>
  52. layui.use(['form', 'layer'], function() {
  53. var form = layui.form;
  54. var layer = layui.layer;
  55. $ = layui.jquery;
  56. //全选按钮点击事件
  57. form.on('checkbox(checkAll)', function(data) {
  58. //data.elem.checked检查是否被选中
  59. if (data.elem.checked) {
  60. //全选按钮被选中
  61. $('input[type="checkbox"]').attr('checked', 'true');
  62. //渲染美化后的checkbox
  63. $('input[type="checkbox"]~div').addClass('layui-form-checked');
  64. } else {
  65. $('input[type="checkbox"]').removeAttr('checked');
  66. $('input[type="checkbox"]~div').removeClass('layui-form-checked');
  67. //全选按钮未选中
  68. }
  69. // form.render('checkbox', 'groupForm');
  70. });
  71. //父级菜单选中事件
  72. form.on('checkbox(pmenus)', function(data) {
  73. //data.elem.checked检查是否被选中
  74. var pIndex = $(data.elem).attr('group');
  75. if (data.elem.checked) {
  76. $('input[lay-filter="cmenus-' + pIndex + '"]').attr('checked', 'true');
  77. //渲染美化后的checkbox
  78. $('input[lay-filter="cmenus-' + pIndex + '"]~div').addClass('layui-form-checked');
  79. } else {
  80. $('input[lay-filter="cmenus-' + pIndex + '"]').removeAttr('checked');
  81. $('input[lay-filter="cmenus-' + pIndex + '"]~div').removeClass('layui-form-checked');
  82. }
  83. // form.render('checkbox', 'groupForm');
  84. });
  85. });
  86. //在父窗口中调用了save方法
  87. function save() {
  88. console.log('save');
  89. if ($('input[name="title"]').val().trim() === '') {
  90. error('请输入角色名称');
  91. return false;
  92. }
  93. //把form表单中的数据序列化后通过post提交
  94. var form = $('form').serialize();
  95. $.post('/admins/groups/save',
  96. form,
  97. function(res) {
  98. if (res.status > 0) {
  99. error(res.msg);
  100. } else {
  101. layer.msg(res.msg);
  102. setTimeout(function() {
  103. //假设这是iframe页
  104. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  105. //关闭当前窗口
  106. parent.layer.close(index); //再执行关闭
  107. //刷新父窗口,重新显示账号管理员列表
  108. parent.window.location.reload();
  109. }, 1000);
  110. }
  111. }, 'json');
  112. }
  113. function error(msg) {
  114. layer.alert(msg, {
  115. icon: 2
  116. });
  117. }
  118. </script>
  119. </html>

3.权限中间件RightsVerify.php

  1. <?php
  2. namespace App\Http\Middleware;
  3. use Closure;
  4. use Hamcrest\Arrays\IsArray;
  5. //引入数据库查询构造器,链式调用
  6. use Illuminate\Support\Facades\DB;
  7. //引入Auth类,获取当前登录的用户
  8. use Illuminate\Support\Facades\Auth;
  9. use function GuzzleHttp\json_decode;
  10. class RightsVerify
  11. {
  12. /**
  13. * Handle an incoming request.
  14. *
  15. * @param \Illuminate\Http\Request $request
  16. * @param \Closure $next
  17. * @return mixed
  18. */
  19. public function handle($request, Closure $next)
  20. {
  21. //获取当前登录用户的用户信息
  22. $user = Auth::user();
  23. //获取当前登录用户的角色id
  24. $gid = $user->gid;
  25. $gInfo = DB::table('admin_group')->where('gid',$gid)->item();
  26. if(!$gInfo):
  27. return response('不存在该角色',200);
  28. endif;
  29. //把所有当前用户可用的菜单保存在数组中
  30. $rights = [];
  31. if($gInfo['rights']):
  32. $rights = json_decode($gInfo['rights'],true);
  33. endif;
  34. //检查当前用户访问的是哪个菜单,是否有权限访问,是否有该菜单
  35. $curUrl = $request->route()->action['controller'];//返回当前访问的路由所对应的控制器和方法
  36. //App\Http\Controllers\admins\Home@index
  37. $pos = strrpos($curUrl,'\\');//从字符串右边开始查找\在字符串中的位置
  38. $curUrl = substr($curUrl,$pos+1);
  39. //Home@index
  40. $pos = strpos($curUrl,'@');//获取分隔符的位置
  41. $con = substr($curUrl,0,$pos);//获取要访问的控制器
  42. $act = substr($curUrl,$pos+1);//获取要访问的方法
  43. //在数据库中查找对应的菜单
  44. $curMenu = DB::table('admin_menu')->where('controller',$con)->where('action',$act)->item();
  45. if(!$curMenu):
  46. return response('不存在此功能',200);
  47. endif;
  48. if($curMenu['status']==1):
  49. return response('此功能已被禁用,请联系管理员开启此功能',200);
  50. endif;
  51. if(!(in_array($curMenu['mid'],$rights))):
  52. return response('没有权限使用此菜单,请更改权限后使用',200);
  53. endif;
  54. // echo '<pre>';
  55. // print_r($curMenu);
  56. // exit;
  57. //把登录用户的权限保存在request中的rights自定义属性中
  58. $request->rights = $rights;
  59. return $next($request);
  60. }
  61. }

4.Home控制器,根据用户权限查找对应菜单Home.php

  1. <?php
  2. namespace App\Http\Controllers\admins;
  3. use App\Http\Controllers\Controller;
  4. use Illuminate\Support\Facades\Auth;
  5. use Illuminate\Http\Request;
  6. //引入数据库查询构造器,链式调用
  7. use Illuminate\Support\Facades\DB;
  8. //后台主页
  9. class Home extends Controller
  10. {
  11. public function index(Request $req)
  12. {
  13. //通过req中的自定义rights属性取得当前用户的权限菜单,rights属性在中间件RightsVerify.php中自定义
  14. $rights = $req->rights;
  15. //然后通过whereIn判断菜单是否在权限菜单中
  16. $menus = DB::table('admin_menu')->whereIn('mid',$rights)->where('status',0)->lists();
  17. $res = [];
  18. foreach($menus as $menu ):
  19. //ishidden为0代表该显示该菜单
  20. //pid等于0的并且的为顶级菜单存储在pmenus中
  21. if($menu['pid']=='0' && $menu['ishidden']=='0'):
  22. $res['pmenus'][] = $menu;
  23. //为每一个一级菜单创建一个数组用来存放二级菜单
  24. $res['cmenus'][$menu['mid']] = [];
  25. endif;
  26. //pid不等于0的为子菜单,按照pid进行分组存储在cmenus中
  27. if(($menu['pid']!='0')&&($menu['ishidden']=='0')):
  28. //把子菜单放在对应的一级菜单的数据中
  29. $res['cmenus'][$menu['pid']][] = $menu;
  30. endif;
  31. endforeach;
  32. $res['username'] = Auth::user()->real_name;
  33. // echo '<pre>';
  34. // print_r($res);
  35. // exit;
  36. return view('/admins/home/index',$res);
  37. }
  38. public function welcome()
  39. {
  40. return view('/admins/home/welcome');
  41. }
  42. public function logout()
  43. {
  44. Auth::logout();
  45. return view('/admins/account/login');
  46. }
  47. }
  48. ?>

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
王娇2020-06-21 20:17:321楼
//全选按钮点击事件 form.on('checkbox(checkAll)', function(data) { //data.elem.checked检查是否被选中 if (data.elem.checked) { //全选按钮被选中 $('input[type="checkbox"]').attr('checked', 'true'); //渲染美化后的checkbox $('input[type="checkbox"]~div').addClass('layui-form-checked'); } else { $('input[type="checkbox"]').removeAttr('checked'); $('input[type="checkbox"]~div').removeClass('