角色权限,我们做任何网站几乎都是需要的,以下是一个简单的案例,大家可以参考下:
思路:
1、创建三张表。
管理员表,角色表(用于记录权限角色值),导航表(用于导航添加及遍历)
2、登录成功之后, session 记录角色 groud_id ;
通过 groud_id 查询 groud 角色表 并session记录该角色权限值
3、公共控制器中用 mysql “ in“函数, 查询角色表,并匹对角色值,有权限的栏目就在导航中显示。
一、tp5权限功能,效果图:
管理员列表:
管理员添加功能:
角色表:
角色添加:
二、创建数据表:
1、管理员表:
CREATE TABLE `tp5_admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(10) DEFAULT NULL COMMENT '账号', `realname` varchar(10) DEFAULT NULL COMMENT '真实姓名', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `password` varchar(35) DEFAULT NULL COMMENT '密码', `img` varchar(255) DEFAULT NULL COMMENT '头像', `addtime` varchar(11) DEFAULT NULL COMMENT '添加时间', `updatetime` varchar(11) DEFAULT NULL COMMENT '修改时间', `stop` int(2) DEFAULT '1' COMMENT '是/否启用(1启用,0不启用)', `login_num` int(11) DEFAULT '0' COMMENT '登录次数', `group_id` int(11) DEFAULT NULL COMMENT '权限组', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2、导航表:
CREATE TABLE `tp5_nav` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL COMMENT '栏目名称', `ac` varchar(255) DEFAULT NULL COMMENT '栏目方法', `co` varchar(255) DEFAULT NULL, `url` varchar(255) DEFAULT NULL COMMENT '栏目地址', `sort` int(11) DEFAULT '0' COMMENT '排序', `stop` int(2) DEFAULT '0' COMMENT '是/否启用', `pid` int(11) DEFAULT NULL COMMENT '父id', `type` int(11) DEFAULT NULL COMMENT '栏目类型', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
3、权限表:用于记录拥有的权限
CREATE TABLE `tp5_group` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL COMMENT '管理员级别', `desc` varchar(255) DEFAULT NULL COMMENT '管理员描述', `rule` varchar(255) DEFAULT NULL COMMENT '拥有权限', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
三、实现代码:
业务逻辑代码:
1、管理员列表
<div class="row"> <div class="col-xs-12 col-md-12"> <div class="widget"> <div class="widget-header "> <span class="widget-caption">管理员管理</span> <div class="widget-buttons"> <a href="#" data-toggle="maximize"> <i class="fa fa-expand"></i> </a> <a href="#" data-toggle="collapse"> <i class="fa fa-minus"></i> </a> </div> </div> <div class="widget-body"> <div class="table-toolbar"> <a id="editabledatatable_new" href="{:url('admin/Sys/magadd')}" class="btn btn-primary"> +添加管理员 </a> </div> <table class="table table-striped table-hover table-bordered" id="editabledatatable"> <thead> <tr role="row"> <th> ID </th> <th> 账号 </th> <th> 真实姓名 </th> <th> 角色 </th> <th> 邮箱 </th> <th> 头像 </th> <th> 登录次数 </th> <th> 添加时间 </th> <th> 最近修改 </th> <th> 状态 </th> <th width="13%"> 操作 </th> </tr> </thead> <tbody> {volist name="maglist" id="vo"} <tr> <td>{$vo.id}</td> <td>{$vo.username}</td> <td>{$vo.realname}</td> <td class="center ">{$vo.name}</td> <td class="center ">{$vo.email}</td> <td class="center "><img src="{$vo.img}" alt="" width="50px;" height="50px;"></td> <td class="center ">{$vo.login_num}</td> <td class="center ">{$vo['addtime']|date='Y-m-d H:i:s',###}</td> <td class="center ">{$vo['updatetime']|date='Y-m-d H:i:s',###}</td> <td class="center "> <label class="qd_btn_{$vo.id}"> {if condition="$vo.stop eq null"} <input class="checkbox-slider slider-icon colored-success" type="checkbox" onclick="qdswt(this,{$vo.id});"> <span class="text"></span> {else/} <input class="checkbox-slider slider-icon colored-success" type="checkbox" checked="checkbox" onclick="reset_qdswt(this,{$vo.id});"> <span class="text"></span> {/if} </label> </td> <td> <a href="{:url('admin/Sys/magedit',array('id'=>$vo.id))}" class="btn btn-info btn-xs edit"><i class="fa fa-edit"></i> 编辑</a> <a href="{:url('admin/Sys/magedel',array('id'=>$vo.id))}" onclick="return confirm('你确定要删除该管理员么?');" class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i> 删除</a> </td> </tr> {/volist} </tbody> </table> <div style="clear:both"></div> <div class="row" style="margin-top:1%;"> <div class="col-md-12"> <ul class="pagination pull-right"> {$maglist->render()} </ul> </div> </div> </div> </div> </div> </div>
PHP代码:
// 管理列表 public function maglist() { // $maglist=db('admin')->order('id desc')->paginate(10); $maglist = \think\Db::name('admin')->alias('a')->join('group b','a.group_id=b.id')->field('a.*,b.name')->order('id desc')->paginate(10); $this->assign('maglist',$maglist); return $this->fetch(); }
2、管理员添加:
<div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-header bordered-bottom bordered-themeprimary"> <span class="widget-caption">管理添加</span> </div> <div class="widget-body"> <div> <form class="form-horizontal form-bordered" role="form" enctype="multipart/form-data" method="post" action=""> <div class="form-group"> <label for="inputusername" class="col-sm-2 control-label no-padding-right">账号</label> <div class="col-sm-4"> <input type="text" class="form-control" id="inputusername" placeholder="账号" name="username"> </div> </div> <div class="form-group"> <label for="inputPassword" class="col-sm-2 control-label no-padding-right">密码</label> <div class="col-sm-4"> <input type="text" class="form-control" id="inputPassword" placeholder="密码" name="password"> </div> </div> <div class="form-group"> <label for="inputrealname" class="col-sm-2 control-label no-padding-right">真实姓名</label> <div class="col-sm-4"> <input type="text" class="form-control" id="inputrealname" placeholder="真实姓名" name="realname"> </div> </div> <div class="form-group"> <label for="inputemail" class="col-sm-2 control-label no-padding-right">邮箱</label> <div class="col-sm-4"> <input type="email" class="form-control" id="inputemail" placeholder="邮箱" name="email"> </div> </div> <div class="form-group"> <label for="inputgroup" class="col-sm-2 control-label no-padding-right">角色</label> <div class="col-sm-4"> <select data-toggle="simplecolorpicker" name="group_id"> {volist name="grouplist" id="vo"} <option value="{$vo.id}">{$vo.name}</option> {/volist} </select> </div> </div> <div class="form-group"> <label for="inputgroup" class="col-sm-2 control-label no-padding-right">头像</label> <div class="col-sm-4"> <input type="file" name="img" id="doc" multiple="multiple" onchange="javascript:setImagePreview();" class="btn btn-primary"> </div> </div> <div class="form-group uplabel" style="display:none"> <label for="inputgroup" class="col-sm-2 control-label no-padding-right">预览</label> <div class="col-sm-4" id="localImag"> <img class="editable img-responsive editable-click editable-empty" id="preview" src="" style="display: block;" /> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary">添加</button> </div> </div> </form> </div> </div> </div> </div> </div>
PHP代码:
public function magadd(){ $username=input('username'); $maglist=\think\Db::name('admin')->where(array('username' =>$username))->find(); // 角色列表 $group_list=db('group')->order('id asc')->select(); $this->assign('group_list',$group_list); if(request()->isPost()){ // halt(input()); $data=[ 'username'=>input('username'), 'password'=>md5(input('password')), 'realname'=>input('realname'), 'email'=>input('email'), 'group_id'=>input('group_id'), 'addtime'=>time(), 'updatetime'=>time(), ]; $validate = \think\Loader::validate('Mag'); if($validate->check($data)){ if($_FILES['img']['tmp_name']){ // 获取表单上传文件 例如上传了001.jpg $file = request()->file('img'); // 移动到框架应用根目录/public/uploads/ 目录下 $info = $file->move(ROOT_PATH . 'public' . DS . '/static/uploads/mag'); if($info){ // 成功上传后 获取上传信息 // 输出 jpg $data['img']='/public/static/uploads/mag/'.date('Ymd').'/'.$info->getFilename(); }else{ // 上传失败获取错误信息 echo $file->getError(); } } $res=\think\Db::name('admin')->insert($data); if($res){ return $this->success('添加成功!','maglist'); } else{ return $this->error('添加失败'); } }else{ return $this->error($validate->getError()); } return; } $grouplist=\think\Db::name('group')->select(); $this->assign('grouplist',$grouplist); return $this->fetch(); }
3、角色权限列表:
<div class="row"> <div class="col-xs-12 col-md-12"> <div class="widget"> <div class="widget-header "> <span class="widget-caption">角色权限</span> <div class="widget-buttons"> <a href="#" data-toggle="maximize"> <i class="fa fa-expand"></i> </a> <a href="#" data-toggle="collapse"> <i class="fa fa-minus"></i> </a> </div> </div> <div class="widget-body"> <div class="table-toolbar"> <a id="editabledatatable_new" href="{:url('admin/Sys/groupadd')}" class="btn btn-primary"> +添加角色 </a> </div> <table class="table table-striped table-hover table-bordered" id="editabledatatable"> <thead> <tr role="row"> <th> ID </th> <th> 角色 </th> <th> 备注 </th> <th width="60%"> 拥有权限 </th> <th width="13%"> 操作 </th> </tr> </thead> <tbody> {volist name="grouplist" id="vo"} <tr> <td>{$vo.id}</td> <td>{$vo.name}</td> <td>{$vo.desc}</td> <td>{$vo.rule}</td> <td> <a href="{:url('admin/Sys/groupedit',array('id'=>$vo.id))}" class="btn btn-info btn-xs edit"><i class="fa fa-edit"></i> 编辑</a> <a href="{:url('admin/Sys/groupdel',array('id'=>$vo.id))}" onclick="return confirm('你确定要删除该管理员么?');" class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i> 删除</a> </td> </tr> {/volist} </tbody> </table> </div> </div> </div> </div>
PHP 代码:
// 角色列表 public function grouplist(){ $grouplist = \think\Db::name('group')->order('id desc')->select(); foreach ($grouplist as $key => $value) { $arr=[]; $value['rule']=explode(',', $value['rule']); foreach ($value['rule'] as $k => $v) { $res=\think\Db::name('nav')->where('`id`="'.$v.'"')->find(); $arr[]=$res['name']; } $grouplist[$key]['rule']=$arr; $grouplist[$key]['rule']=implode(' 、', $grouplist[$key]['rule']); } $this->assign('grouplist', $grouplist); // 渲染模板输出 return $this->fetch(); }
4、角色添加:
<div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-header bordered-bottom bordered-themeprimary"> <span class="widget-caption">角色添加</span> </div> <div class="widget-body"> <form class="form-horizontal form-bordered" role="form" method="post" action="" > <div class="form-group"> <label for="inputusername" class="col-sm-1 control-label no-padding-right">角色</label> <div class="col-sm-4"> <input type="text" class="form-control" name="name" placeholder="角色"> </div> </div> <div class="form-group"> <label for="inputusername" class="col-sm-1 control-label no-padding-right">描述</label> <div class="col-sm-4"> <input type="text" class="form-control" placeholder="描述" name="desc" > </div> </div> <div class="form-group"> <label for="inputusername" class="col-sm-1 control-label no-padding-right">拥有权限</label> <div class="col-sm-4"> <?php foreach($yjmenu as $yjk=>$yjr){ ?> <label> <input name="rule[]" type="checkbox" class="inverted" value="<?php echo $yjr['id'];?>"> <span class="text"> <?php echo $yjr['name'];?></span> </label><br/> <?php if(!empty($yjr['sub'])){?> <?php foreach($yjr["sub"] as $subk=>$subr){ ?> <label> <input name="rule[]" type="checkbox" class="inverted" value="<?php echo $subr['id'];?>"> |- <span class="text"> <?php echo $subr['name'];?></span> </label><br/> <?php }?> <?php }?> <?php }?> </div> </div> <div class="form-group"> <div class="col-sm-offset-1 col-sm-10"> <button type="submit" class="btn btn-primary">添加</button> </div> </div> </form> </div> </div> </div> </div>
PHP 代码:
public function groupadd(){ if(request()->isPost()){ $data=[ 'id'=>input('id'), 'name'=>input('name'), 'desc'=>input('desc'), 'rule'=>implode(',',input('rule/a')), ]; // var_dump($data['rule']);exit(); $validate = \think\Loader::validate('group'); if($validate->check($data)){ $res=\think\Db::name('group')->insert($data); if($res){ return $this->success('添加成功!','grouplist'); } else{ return $this->error('添加失败'); } }else{ return $this->error($validate->getError()); } return; } return $this->fetch(); }
遍历公共头部左侧导航:
<ul class="nav sidebar-menu"> <!--Dashboard--> <li> <a href="/" target="_blank"> <i class="menu-icon glyphicon glyphicon-home"></i> <span class="menu-text"> 访问首页 </span> </a> </li> <li class="active"> <a href="{:url('admin/Index/index')}"> <i class="menu-icon glyphicon glyphicon-tasks"></i> <span class="menu-text"> 控制台 </span> </a> </li> <?php foreach($yjmenu as $yjk=>$yjr){ if(in_array($yjr['id'],$limitarr)){ ?> <li {if condition="($controller_name eq $yjr['co'])"}class="active open"{/if}> <a href="#" class="menu-dropdown"> <i class="menu-icon fa fa-desktop"></i> <span class="menu-text"> <?php echo $yjr["name"];?> </span> <i class="menu-expand"></i> </a> <?php if(!empty($yjr['sub'])){?> <ul class="submenu"> <?php foreach($yjr["sub"] as $subk=>$subr){ if(in_array($subr['id'],$limitarr)){ ?> <li {if condition="($controller_name eq $subr['co']) and ($action_name eq $subr['ac'])"}class="active"{/if}{$subr['co']}{$subr['ac']}> <a href="<?php echo url($subr["url"]);?>"> <span class="menu-text"><?php echo $subr["name"];?></span> </a> </li> <?php } }?> </ul> <?php } ?> </li> <?php } }?> </ul>
PHP代码:见公共控制器 Base.php 文件
三、最后一步:所有控制器都要继承公共控制器。
登录方法:登录成功之后 session 记录用户名,查询数据库,并记录权限值。
public function index(){ if(request()->isPost()){ // 验证码判断 $username=input('username'); $password=input('password'); $map['username'] = $username; $map['stop'] = 1; $user=\think\Db::name('admin')->where($map)->find(); if($user==''){ return $this->error('账号不存在!'); }else{ \think\Session::set('id',$user['id']); \think\Session::set('group_id',$user['group_id']); \think\Session::set('img',$user['img']); // 权限记录 $groupdata=\think\Db::name('group')->where('id','=',session('group_id'))->find(); // halt($groupdata); \think\Session::set('adminrule',$groupdata['rule']); // 登录记录 $data=[ 'login_name'=>session('username'), 'group_id'=>session('group_id'), ]; return $this->success('登录成功,正在跳转!','admin/Index/index'); } } return $this->fetch(); }
创建公共控制器Base.php
<?php namespace app\admin\controller; use think\Controller; use think\Request; class Base extends Controller { public function _initialize(){ if(!session('id')){ $this->error('请先登录系统',url('admin/Login/index')); }else{ $request=Request::instance(); $cn=$request->controller(); $an=$request->action(); $this->assign('action_name',$an); $this->assign('controller_name',$cn); $limitarr=session('adminrule'); // halt(session('adminrule')); $nav= \think\Db::name('nav')->where('`id` in ('.Session('adminrule').')')->select(); // $corule=M("nav")->where('`nav_id` in ('.$_SESSION['adminCount']['rule'].')')->select(); // halt($nav); $arrrule=array(); foreach ($nav as $k => $v) { $arrrule[]=$v["co"]; } // halt($arrrule); if(in_array($cn,$arrrule)){ }else{ if($cn=="Index"){ }else{ return $this->error('你没有权限!!',url('admin/Index/index')); } } } $this->nav(); $this->item(); } public function nav(){ $yjmenu= \think\Db::name('nav')->where('pid=0 AND type=1')->order('sort asc')->select(); foreach ($yjmenu as $mk => $mr) { $submenu= \think\Db::name('nav')->where('pid','=',$mr['id'])->select(); if($submenu){ $yjmenu[$mk]['sub']=$submenu; } } // $limitarr=session('adminrule'); $limitarr=explode(",", session('adminrule')); $this->assign('yjmenu', $yjmenu); $this->assign('submenu', $yjmenu); $this->assign('limitarr', $limitarr); $request=Request::instance(); $cn=$request->controller(); $an=$request->action(); $this->assign('action_name',$an); $this->assign('controller_name',$cn); }