rbac权限控制,基于无线分类

2018年9月18日11:21:28

 数据库结构

CREATE TABLE `admin` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间',
  `remark` varchar(200) DEFAULT NULL COMMENT '备注',
  `is_delete` tinyint(1) NOT NULL DEFAULT '10' COMMENT '10默认99删除',
  `shop_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '店铺ID',
  `admin_login_name` varchar(20) NOT NULL COMMENT '登录名称',
  `admin_password` varchar(32) DEFAULT NULL COMMENT '登录密码',
  `admin_phone` varchar(11) DEFAULT NULL COMMENT '手机号码',
  `admin_email` varchar(20) DEFAULT NULL COMMENT '邮箱',
  `real_name` varchar(20) DEFAULT NULL COMMENT '真实姓名',
  `admin_avatar` varchar(100) DEFAULT NULL COMMENT '管理员头像',
  `admin_qq` varchar(20) DEFAULT NULL COMMENT '管理员qq',
  `admin_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建者管理员ID',
  `manage_product` varchar(200) DEFAULT NULL COMMENT '管理的商品属性分类',
  `admin_status` tinyint(1) unsigned NOT NULL DEFAULT '10' COMMENT '默认10通过20不通过99',
  `session_id` varchar(50) DEFAULT NULL COMMENT 'session_id',
  `admin_group_ids` varchar(500) DEFAULT NULL COMMENT '用户权限组ID集合',
  `is_admin` tinyint(1) unsigned NOT NULL DEFAULT '10' COMMENT '系统超级管理员10默认20是',
  `is_shop_admin` tinyint(1) unsigned NOT NULL DEFAULT '10' COMMENT '店铺管理员10默认20是',
  `token` varchar(32) DEFAULT NULL COMMENT 'token字符串',
  `token_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'token创建时间',
  `status` tinyint(1) NOT NULL DEFAULT '10' COMMENT '默认10锁定20',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='管理员表'

admin_group

CREATE TABLE `admin_group` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间',
  `remark` varchar(200) DEFAULT NULL COMMENT '备注',
  `is_delete` tinyint(1) NOT NULL DEFAULT '10' COMMENT '10默认99删除',
  `parent_group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID 0是顶级',
  `group_name` varchar(50) NOT NULL COMMENT '分组名称',
  `permission_ids` text COMMENT 'permission_id集合',
  `tag` varchar(50) DEFAULT NULL COMMENT '标签',
  `sort` tinyint(1) unsigned NOT NULL DEFAULT '255' COMMENT '排序',
  `shop_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '店铺ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='admin权限组'

 

admin_permission
CREATE TABLE `admin_permission` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间',
  `remark` varchar(200) DEFAULT NULL COMMENT '备注',
  `is_delete` tinyint(1) NOT NULL DEFAULT '10' COMMENT '10默认99删除',
  `parent_permission_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID 0是顶级',
  `permission_name` varchar(50) NOT NULL COMMENT '控制名称',
  `permission_url` varchar(100) NOT NULL DEFAULT '' COMMENT '控制器URL',
  `tag` varchar(50) NOT NULL DEFAULT '' COMMENT '标签,标志',
  `is_menu` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '作为菜单显示,1是,2不是',
  `small_icon_name` varchar(50) DEFAULT NULL COMMENT '小图标名称',
  `shop_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '店铺ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COMMENT='管理员权限表'

 

一些逻辑代码

//获取菜单数据
    public static function get_menu($admin_id = null, $is_shop_admin = 10, $is_admin = 10) {
        if (empty($admin_id)) {
            throw new \Exception('管理员ID为空');
        }
        $field = array('id', 'parent_permission_id', 'permission_name', 'permission_url', 'small_icon_name');
        $result = AdminPermission::where('is_menu', 1)->orderBy('id', 'asc')->get($field)->toArray();
        if (empty($result)) {
            throw new \Exception('权限表为空');
        }
        //获取菜单树数组
        $menu = self::tree_menu($result);
        //店铺管理员或者超级管理员都有全部权限
        if ($is_shop_admin == 20 || $is_admin == 20) {
            return $menu;
        } else {
            return self::filter_menu($menu, $admin_id);
        }
    }

    //过滤菜单,只做到3层过滤,超过4层不支持,第三层作为具体菜单层
    public static function filter_menu($menu = null, $admin_id = null) {

        $permission = self::get_current_admin_permission($admin_id);
        if (empty($permission)) {
            //如果在 admin_group  admin_permission  admin 三表关系有问题查询会有问题,就会返回false,就直接返回空,没有菜单
            throw new \Exception('未获得当前用户权限菜单');
        }

        //先测试使用,可能存在bug
        foreach ($menu as $k => &$v) {
            foreach ($v['child'] as $kk => &$vv) {
                foreach ($vv['child'] as $kkk => &$vvv) {
                    if (!in_array($vvv['id'], $permission)) {
                        unset($menu[$k]['child'][$kk]['child'][$kkk]);
                    }
                }
                if (empty($vv['child'])) {
                    unset($menu[$k]['child'][$kk]);
                }
            }
            if (empty($v['child'])) {
                unset($menu[$k]);
            }
        }
        return $menu;
    }

    //获取当前用户的权限ID集合数组
    public static function get_current_admin_permission($admin_id = null) {
        $result = Admin::where('id', $admin_id)->first(['admin_group_ids']);
        $result_new = $result->toArray();
        if (empty($result_new['admin_group_ids'])) {
            throw new \Exception('该用户未设置权限');
        }
        $admin_group_ids = explode(',', $result_new['admin_group_ids']);

        $results = AdminGroup::whereIn('id', $admin_group_ids)->get(['permission_ids'])->toArray();
        if (empty($results)) {
            throw new \Exception('系统权限组设置有问题');
        }
        //合并 permission_ids 在做查询,减少查询,提高性能
        $permission_ids = [];
        foreach ($results as $k => &$v) {
            //空,unset防止出错
            if (empty($v['permission_ids'])) {
                unset($v);
            } else {
                $v = explode(',', trim($v['permission_ids'], ','));
                foreach ($v as $kk => $vv) {
                    $permission_ids[] = $vv;
                }
            }
        }
        $permission_ids_array = array_unique($permission_ids);

        //防止数据出错
        $result_2 = AdminPermission::wherein('id', $permission_ids_array)->get(['id'])->toArray();
        if (empty($result_2)) {
            throw new \Exception('未获得权限数据');
        }
        $return_array = array();
        foreach ($result_2 as $key => $value) {
            $return_array[] = $value['id'];
        }
        return $return_array;
    }

    //递归数据
    public static function tree_menu($menu = null, $parent = 0) {
        $tree = array();
        foreach ($menu as $v) {
            if ($v['parent_permission_id'] == $parent) {
                $v['child'] = self::tree_menu($menu, $v['id']);
                if (empty($v['child'])) {
                    unset($v['child']);
                }
                $tree[] = $v;
            }
        }
        return $tree;
    }

 显示配合的是 bootstrap-treeview 做的无线递归树

https://www.cnblogs.com/zx-admin/p/8021734.html 实际效果这可以看到

posted on 2018-09-18 14:31  zh7314  阅读(286)  评论(0编辑  收藏  举报