角色权限把控说明
真对不同的管理员给与不同的权限
1、规则管理模块
2、管理员拥有的规则管理
数据库表创建
用户表
CREATE TABLE `manger` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(80) NOT NULL,
`lastlogin` varchar(80) NOT NULL DEFAULT '0',
`num` int(11) DEFAULT '0',
`status` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8;
规则表
CREATE TABLE `auth_rule` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(80) NOT NULL DEFAULT '',
`title` char(20) NOT NULL DEFAULT '',
`type` tinyint(1) NOT NULL DEFAULT '1',
`status` tinyint(1) NOT NULL DEFAULT '1',
`pid` int(11) NOT NULL,
`level` int(11) NOT NULL,
`sort` int(11) NOT NULL,
`condition` int(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
用户组表(说明用户拥有的权限)
CREATE TABLE `auth_group` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`title` char(100) NOT NULL DEFAULT '',
`status` tinyint(1) NOT NULL DEFAULT '1',
`rules` char(80) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
用户组明细表
CREATE TABLE `auth_group_access` (
`uid` mediumint(8) unsigned NOT NULL,
`group_id` mediumint(8) unsigned NOT NULL,
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
规则管理功能实现
这里在权限表加入了level字段来设置偏移量,与之前博客中写的无限分列有点不同之处
添加功能
模型:书写了无限分类展示的列表功能
<?php
namespace app\admin\model;
use think\Model;
class AuthRule extends Model{
protected $resultSetType = 'collection';
// 无限分类展示
public function coltree(){
//第一步:查询所有数据
$col=$this->order('sort desc')->select();
//第二步:调用改造数组方法:参入数组、默认根节点0遍历、默认偏移量0
return $this->sort($col);
}
// 改造数组:参入数组、默认根节点0遍历、默认偏移量0
public function sort($data,$pid=0){
//第三步:定义static静态数组
/*static关键字的作用如下:
1、放在函数内部修饰变量;
2、放在类里修饰属性或方法;
3、放在类的方法里修饰变量;
4、修饰全局作用域的变量;*/
static $arr=array();
//第四步:foreach遍历数组集
foreach ($data as $key => $value) {
//第五步:判断$pid与数组遍历pid是否相等
//从第一次$pid=0开始查找,找到后存入新数组$arr中
if($value['pid']==$pid){
//第五步03:偏移量与分类名连接显示突出显示层级关系
// $value['level']=$level;
// $value['title']= '|-'.str_repeat('-',$level).$value['title'];
//第五步01:从第一次$pid=0开始查找,找到后存入新数组$arr中
$arr[]=$value;
//第五步02:存入新数组后回调函数自己
//思考:回调后$data如果再次循环,会不会把原放入$arr的数组再次放入出现重复?
//答案是不会,解决办法在第二个参数$value['id']
$this->sort($data,$value['id']);
}
}
//第六步:返回改造好的新数组
return $arr;
}
}
控制器:添加数据库
//添加
public function add()
{
if(request()->isPost()){
$data = input('post.');
//偏移量 查询当前数据父级level去添加子类level偏移量,顶级则为0
$plevel = db('auth_rule')->where('id', $data['pid'])->field('level')->find();
if($plevel){
$data['level'] = $plevel['level']+1;
}else{
$data['level'] = 0;
}
$res = db('auth_rule')->insert($data);
if($res){
$this->success('添加成功', url('index'));
}else{
$this->error('添加失败');
}
}else{
$AuthRuleModel = new AuthRuleModel();
$rule = $AuthRuleModel->coltree();
$this->assign('rule', $rule);
return view();
}
}
前端添加模板
{layout name="public/layout" /}
<div class="col-md-10">
<ol class="breadcrumb">
<li><a href="#"><span class="glyphicon glyphicon-home"></span> 首页</a></li>
<li><a href="#">规则管理</a></li>
<li class="active">添加规则</li>
<a href="" style="float:right;height:25px;" class="btn btn-success"><span class="glyphicon glyphicon-refresh"></span></a>
<span style="clear:both"></span>
</ol>
<div class="panel panel-default">
<div class="panel-body">
<form action="" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="">上级权限</label>
<select name="pid" class="form-control">
<option value="0">顶级栏目</option>
{volist name="rule" id="rule"}
<option value="{$rule.id}">
<?php
if($rule['level']!=0){
echo '|';
}
echo str_repeat('--',$rule['level']);
?>
{$rule.title}
</option>
{/volist}
</select>
</div>
<div class="form-group">
<label for="">权限名称</label>
<input type="text" name="title" class="form-control" id="" value="">
</div>
<div class="form-group">
<label for="">控制器/方法</label>
<input type="text" name="name" class="form-control" id="" value="">
</div>
<div class="form-group">
<input value="提交" class="btn btn-success" type="submit">
<input type="reset" value="重置" class="btn btn-danger">
</div>
</form>
</div>
<div class="panel-footer">
</div>
</div>
</div>
效果图
规则管理展示功能
控制器
public function index()
{
$AuthRuleModel = new AuthRuleModel();
$rule = $AuthRuleModel->coltree();
$this->assign('rule', $rule);
return view();
}
前端模板
{layout name="public/layout" /}
<div class="col-md-10">
<ol class="breadcrumb">
<li><a href="#"><span class="glyphicon glyphicon-home"></span> 首页</a></li>
<li><a href="#">规则管理</a></li>
<li class="active">规则列表</li>
<a href="" style="float:right;height:25px;" class="btn btn-success"><span class="glyphicon glyphicon-refresh"></span></a>
<span style="clear:both"></span>
</ol>
<div class="panel panel-default">
<div class="panel-heading">
<button class="btn btn-primary" ><span class="glyphicon glyphicon-plus"></span> <a href="{:url('add')}" style="color:white">添加规则</a></button>
</div>
<div class="panel-body">
<table class="table table-bordered table-hover">
<tr>
<th>ID</th>
<th>权限名称</th>
<th>控制器/方法</th>
<th>级别</th>
<th>操作</th>
</tr>
{volist name="rule" id="rule"}
<tr>
<td>{$rule.id}</td>
<td>
<?php
if($rule['level']!=0){
echo '|';
}
echo str_repeat('--',$rule['level']);
?>
{$rule.title}
</td>
<td>{$rule.name}</td>
<td>{$rule.level}级别</td>
<td>
<a class="glyphicon glyphicon-trash" href="{:url('del',array('id'=>$rule.id))}"></a> | <a class="glyphicon glyphicon-tag" href="{:url('update',array('id'=>$rule.id))}"></a>
</td>
</tr>
{/volist}
</table>
</div>
<div class="panel-footer">
</div>
</div>
</div>
效果图
删除功能
必须先删除该id下的所有子孙才能删除本id
控制器代码
//第二步:前置操作beforeActionList为tp5自带方法
//也就是执行del()删除方法前先执行delson()方法
protected $beforeActionList = array(
'delson'=>['only'=>'del']//表示在执行del方法前先执行delson方法
);
//第三步:执行del方法前的方法,用于删除子孙分类id
public function delson()
{
$id = input('id');
//获取所有父id下的所有子孙分类id
$idx = $this->getChildId($id);
//先判断是否存在子孙分类,存在则删除
if($idx){
db('colum')->delete($idx);
}
}
//前置操作执行完成后,删除当前id
public function del($id)
{
$AuthRuleModel = new AuthRuleModel();
if($AuthRuleModel->where('id','=',$id)->delete()){
$this->success("删除成功", url("index"));
}else{
$this->error("删除失败");
}
}
//获取所有父id下的所有子孙分类id
public function getChildId($id)
{
//查询分类表所有数据
$AuthRuleModel = new AuthRuleModel();
$col = $AuthRuleModel->select()->toArray();
//将查询的所有分类数据与删除的栏目$id作为参数传递
return $this->_getChildId($col, $id);
}
//组装子孙分类id
public function _getChildId($col, $id)
{
static $arr = array();
//遍历所有数据,同时判断pid是否存在子孙节点
foreach ($col as $key => $value) {
if($value['pid']==$id){
$arr[] = $value['id'];
//由于可能子类下还有子类,需要递归调用
$this->_getChildId($col,$value['id']);
}
}
//将需要删除的子孙id返回
return $arr;
}
修改功能
控制器
//修改
public function update($id)
{
$AuthRuleModel = new AuthRuleModel();
if(request()->isPost()){
//第二步:接收修改数据
//注意:如果修改后的pid在当前修改数据id的子孙id内或者pid=id则提示错误
$res = $this->descendants($id);
$data = input('post.');
//如果修改后的pid在当前修改数据id的子孙id内或者pid=id则提示错误
if(in_array($data['pid'], $res)|| $id==$data['pid']){
$this->error("能修改到其子孙节点下");die();
}
//偏移量 查询当前数据父级level去添加子类level偏移量,顶级则为0
$plevel = db('auth_rule')->where('id', $data['pid'])->field('level')->find();
if($plevel){
$data['level'] = $plevel['level']+1;
}else{
$data['level'] = 0;
}
//第三步:存入数据库
$res = $AuthRuleModel->save($data, ['id'=>$id]);
if($res){
$this->success("修改成功", url('index'));
}else{
$this->error("修改失败");
}
}else{
//修改前数据
$res = db('auth_rule')->find($id);
$this->assign('res', $res);
//无限分类
$rule = $AuthRuleModel->coltree();
$this->assign('rule', $rule);
return view();
}
}
//遍历该id下所有子孙节点
public function descendants($id)
{
//第一步:查询栏目表所有数据
$AuthRuleModel = new AuthRuleModel();
$all_data = $AuthRuleModel->select()->toArray();
//第二步:获取所有子孙节点,并返回
return $this->get_descendants($all_data, $id);
}
//获取所有子孙节点,并返回
public function get_descendants($all_data, $id)
{
static $arr = array();
foreach ($all_data as $key=>$value){
if($value['pid']==$id){
$arr[] = $value['id'];
$this->get_descendants($all_data, $value['id']);
}
}
return $arr;
}
前端模板
{layout name="public/layout" /}
<div class="col-md-10">
<ol class="breadcrumb">
<li><a href="#"><span class="glyphicon glyphicon-home"></span> 首页</a></li>
<li><a href="#">规则管理</a></li>
<li class="active">修改规则</li>
<a href="" style="float:right;height:25px;" class="btn btn-success"><span class="glyphicon glyphicon-refresh"></span></a>
<span style="clear:both"></span>
</ol>
<div class="panel panel-default">
<div class="panel-body">
<form action="" method="POST" enctype="multipart/form-data">
<div class="form-group">
<input type="hidden" name="id" value="{$res.id}">
<label for="">上级权限</label>
<select name="pid" class="form-control">
<option value="0">顶级栏目</option>
{volist name="rule" id="rule"}
<option value="{$rule.id}" {$res.pid==$rule.id?'selected':''}>
<?php
if($rule['level']!=0){
echo '|';
}
echo str_repeat('--',$rule['level']);
?>
{$rule.title}
</option>
{/volist}
</select>
</div>
<div class="form-group">
<label for="">权限名称</label>
<input type="text" name="title" class="form-control" id="" value="{$res.title}">
</div>
<div class="form-group">
<label for="">控制器/方法</label>
<input type="text" name="name" class="form-control" id="" value="{$res.name}">
</div>
<div class="form-group">
<input value="提交" class="btn btn-success" type="submit">
<input type="reset" value="重置" class="btn btn-danger">
</div>
</form>
</div>
<div class="panel-footer">
</div>
</div>
</div>
展示页