* 项目地址:
https://gitee.com/wukongcrm/72crm
* 数据库结构:
** 权限规则表
CREATE TABLE `5kcrm_admin_rule` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`types` tinyint(2) NOT NULL DEFAULT '0' COMMENT '0系统设置1工作台2客户管理3项目管理4人力资源5财务管理6商业智能',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '定义',
`level` tinyint(5) NOT NULL DEFAULT '0' COMMENT '级别。1模块,2控制器,3操作',
`pid` int(11) DEFAULT '0' COMMENT '父id,默认0',
`status` tinyint(3) DEFAULT '1' COMMENT '状态,1启用,0禁用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=97 DEFAULT CHARSET=utf8 COMMENT='权限规则表';
INSERT INTO `zkt_crm`.`5kcrm_admin_rule` (`id`, `types`, `title`, `name`, `level`, `pid`, `status`) VALUES (‘1’, ‘2’, ‘全部’, ‘crm’, ‘1’, ‘0’, ‘1’);
id type title name level pid status
根据模块名(level=1),控制器名(level=2),方法名(level=3)
用户组表:
CREATE TABLE `5kcrm_admin_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` tinyint(4) NOT NULL COMMENT '分类1管理角色2客户管理角色3人事角色4财务角色5项目角色0自定义角色',
`title` varchar(100) NOT NULL COMMENT '名称',
`rules` varchar(2000) NOT NULL DEFAULT '' COMMENT '规则',
`remark` varchar(100) NOT NULL DEFAULT '' COMMENT '备注',
`status` tinyint(3) DEFAULT '1' COMMENT '1启用0禁用',
`type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1本人,2本人及下属,3本部门,4本部门及下属部门,5全部 ',
`types` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1超级管理员2系统设置管理员3部门与员工管理员4审批流管理员5工作台管理员6客户管理员7项目管理员8公告管理员',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='角色表';
group表的rules字段关联rule表的自增id
用户所属组:
CREATE TABLE `5kcrm_admin_access` (
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf
user_id group_id
通过group的自增id 就是 access表group_id,查到对应的user_id 就是 用户表的id
对于部门表structure 有 id, name, pid字段
id关联用户表的 structure_id
主要的代码:
application/admin/model/User.php
/**
* [getUserByPer 获取权限范围的user_id]
* @param string $m
* @param string $c
* @param string $a
* @return array|bool
*/
public function getUserByPer($m = 'index', $c = 'index', $a = 'index'){
$request = Request::instance();
$header = $request->header();
$authKey = $header['authkey'];
$m = $m ? strtolower($m) : strtolower($request->module());
$c = $c ? strtolower($c) : strtolower($request->controller());
$a = $a ? strtolower($a) : strtolower($request->action());
$cache = cache('Auth_'.$authKey);
if (!$cache) {
return false;
}
$userInfo = $cache['userInfo'];
//用户所属用户组类别(数组)
$groupTypes = $this->getGroupTypeByAction($userInfo['id'], $m, $c, $a);
//数组去重
$groupTypes = $groupTypes ? array_unique($groupTypes) : [];
//用户组类别(1本人,2本人及下属,3本部门,4本部门及下属部门,5全部)
$adminIds = $this->getAdminId();
$userIds = [];
if (in_array($userInfo['id'],$adminIds)) {
$userIds = getSubUserId(true, 1);
} else {
if (!$groupTypes) {
return [];
}
if (in_array(5, $groupTypes)) {
$userIds = getSubUserId(true, 1);
} else {
foreach ($groupTypes as $v) {
if ($v == 1) {
$userIds = [$userInfo['id']];
} elseif ($v == 2) {
$userIds = getSubUserId();
} elseif ($v == 3) {
$userIds = $this->getSubUserByStr($userInfo['structure_id']);
} elseif ($v == 4) {
$userIds = $this->getSubUserByStr($userInfo['structure_id'], 2);
}
}
}
}
return $userIds ? : [];
}
获取下属的id:
application/common.php
/**
* 获取下属userId
* @author Michael_xu
* @param $self == true 包含自己
* @param $type == 0 下属userid
* @param $type == 1 全部userid
*/
function getSubUserId($self = true, $type = 0)
{
$request = Request::instance();
$header = $request->header();
$authKey = $header['authkey'];
$cache = cache('Auth_'.$authKey);
if (!$cache) {
return false;
}
$userInfo = $cache['userInfo'];
$adminTypes = adminGroupTypes($userInfo['id']);
if (in_array(1,$adminTypes)) {
$type = 1;
}
$belowIds = [];
if (empty($type)) {
$belowIds = getSubUser($userInfo['id']);
} else {
$belowIds = getSubUser(0);
}
if ($self == true) {
$belowIds[] = $userInfo['id'];
} else {
$belowIds = $belowIds ? array_diff($belowIds,array($userInfo['id'])) : [];
}
return array_unique($belowIds);
}
/**
* 获取下属userId
* @author Michael_xu
*/
function getSubUser($userId)
{
$sub_user = db('admin_user')
->where('parent_id', '=', $userId)
->where('status', '<>', 2)
->column('id');
if ($sub_user) {
foreach ($sub_user as $v) {
$son_user = getSubUser($v);
if (!empty($son_user)) {
$sub_user = array_merge($sub_user, $son_user);
}
}
}
return $sub_user;
}
application/bi/common.php
<?php
//权限控制
\think\Hook::add('check_auth','app\\common\\behavior\\AuthenticateBehavior');
application/common/behavior/AuthenticateBehavior.php
<?php
// +---------------------------------------------------------------------+
// | Description: WEB端权限判断 |
// +---------------------------------------------------------------------+
namespace app\common\behavior;
use think\Request;
class AuthenticateBehavior
{
public function run(&$params)
{
/*防止跨域*/
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, authKey, sessionId");
$request = Request::instance();
$m = strtolower($request->module());
$c = strtolower($request->controller());
$a = strtolower($request->action());
//提交方式拦截
$scan = new \com\Scan();
$response = $scan->webscan_Check();
$allow = $params['allow']; //登录用户可访问
$permission = $params['permission']; //无限制
/*获取头部信息*/
$header = $request->header();
$authKey = $header['authkey'];
$cache = cache('Auth_'.$authKey);
$userInfo = $cache['userInfo'];
if (in_array($a, $permission)) {
return true;
}
if (empty($userInfo)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>101,'error'=>'请先登录']));
}
if ($userInfo['id'] == 1) {
return true;
}
if (in_array($a, $allow)) {
return true;
}
//管理员角色
$adminTypes = adminGroupTypes($userInfo['id']);
if (in_array(1,$adminTypes)) {
return true;
}
//操作权限
$res_per = checkPerByAction($m, $c, $a);
if (!$res_per) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
}
在控制器中添加方法 _initialize()
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize() {
// 权限控制忽略大小写 必须全部转换为小写
$action = [
'permission'=>['read', 'index', 'arealist', 'schoollist', 'save', 'update', 'crypt'],
'allow'=>['arealist']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
action指的是 控制器的方法