角色权限,我们做任何网站几乎都是需要的,以下是一个简单的案例,大家可以参考下:
思路:
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);
}