RBAC项目实践【跟着步骤做就可以完成】【资源可以单独在博客中下载】

发布于:2022-11-29 ⋅ 阅读:(397) ⋅ 点赞:(0)

RBAC模型

一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。【今天写其中的一种】
用户=>角色=>权限

1.权限【Authority】

页面示例:

​​​​这里用的无限极
权限数据库字段设计如下【可根据需要自行添加】:

CREATE TABLE `authority` (
  `auth_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限id',
  `auth_name` varchar(20) NOT NULL COMMENT '权限名称',
  `auth_pid` int(10) unsigned NOT NULL COMMENT '权限父级名称',
  `auth_c` varchar(255) NOT NULL COMMENT '控制器名',
  `auth_a` varchar(255) NOT NULL COMMENT '方法名',
  `auth_path` varchar(255) NOT NULL COMMENT '全路径',
  `is_show` tinyint(1) NOT NULL COMMENT '是否显示',
  `auth_ico` varchar(50) NOT NULL,
  `auth_sort` smallint(3) NOT NULL DEFAULT '999' COMMENT '排序',
  `add_time` int(11) DEFAULT NULL,
  `update_time` int(11) DEFAULT NULL,
  PRIMARY KEY (`auth_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='权限表';
PHP代码部分如下:

1.封装一个公共的无限极:

public function getTree($array, $pid=0, $level=0)
    {
        //声明静态数组,避免递归调用时,多次声明导致数组覆盖
        static $list = [];
        foreach ($array as $key => $value){
            //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
            if ($value['mg_pid'] == $pid){
                //父节点为根节点的节点,级别为0,也就是第一级
                $value['level'] = $level;
                //把数组放到list中
                $list[] = $value;
                //把这个节点从数组中移除,减少后续递归消耗
                unset($array[$key]);
                $this->getTree($array, $value['mg_id'], $level+1);
            }
        }
        return $list;
    }
2. 取出所有权限表中所有数据重组
//重组数组加上等级
 public function authorityListApi()
    {
        $common=new Common; //实例化common 控制器
        $list =  \db('authority')->order('auth_path desc')->select();
        $pageList = $common->getTree($list);  //递归调用
        return json_encode(array('code'=>0, 'data' => $pageList));
    }

//渲染视图
 public function showList()
    {
        return $this->fetch('index');
    }

前端代码部分

1.这里用的是layui前端框架

①html部分
<div class="layui-fluid">
    <div class="layui-row layui-col-space15">
        <div class="layui-col-md12">
            <div class="layui-card">

                <div class="layui-card-header"></div>
                <div class="layui-card-body">
                    <script type="text/html" id="test-table-toolbar-toolbarDemo">
                        <div class="layui-btn-container">
                            <button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon">&#xe608;</i>增加权限</button>
                        </div>
                    </script>
                    <table class="layui-hide" id="test-table-page" lay-filter="test-table-page"></table>

                    <script type="text/html" id="authGz">
                        {{ d.auth_c }}/{{ d.auth_a }}
                    </script>

                    <script type="text/html" id="authId">
                        {{ d.auth_path }}
                    </script>
                    <script type="text/html" id="icon">
                        <i class="layui-icon {{ d.auth_ico }}">&nbsp;{{ d.auth_ico }}</i>
                    </script>
                    <script type="text/html" id="test-table-switchTpl">
                        <input type="checkbox" name="type" lay-skin="switch" lay-text="显示|隐藏" lay-filter="test-table-sexDemo"  value="{{ d.auth_id }}" {{ d.is_show == 1 ? 'checked' : '' }}>
                    </script>
                    <script type="text/html" id="table-useradmin-admin">
                        <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit" dataid="{{ d.id }}"></i>编辑</a>
                    </script>
                </div>
            </div>
        </div>
    </div>
</div>
②script部分
table.render({
            elem: '#test-table-page'
            ,url: '/authorityListApi'
            ,toolbar: '#test-table-toolbar-toolbarDemo'
            ,cols: [[
                {field:'auth_id', title:'ID', width:80, sort: true}
                ,{field:'cate_name', title:'权限名称(用于展示左侧栏)'}
                ,{field:'', title:'权限路径',templet:'#authGz'}
                ,{field:'', title:'权限编号',templet:'#authId'}
                ,{field:'', title:'图标',templet:'#icon'}
                ,{field:'is_show', title:'是否显示',templet:'#test-table-switchTpl'}
                ,{title: '操作', width: 80,  fixed: 'right', toolbar: '#table-useradmin-admin'}
            ]],
            done:function (res,curr,count) {
                var data =res.data;
                $("th").css({'color':'black'});
                for (var i in  data) {
                    $("tr[data-index='" + i+ "']").attr('cate-id',data[i].auth_id);
                    $("tr[data-index='" + i+ "']").attr('pid',data[i].auth_pid);
                    $("tr[data-index='" + i+ "']").attr('data-name',data[i].auth_name);
                    $("tr[data-index='" + i+ "']").attr('level',data[i].level);
                    if (data[i].auth_pid==0){
                        $("tr[data-index='" + i+ "']").find("td[data-field='cate_name']").children().html('<i class="layui-icon x-show">&#xe623;</i>' + data[i].auth_name);
                    }
                }
                $("tbody tr[pid!='0']").hide();
            }
        });

角色【Role】

页面示例

列表
添加角色
修改角色

角色数据库字段设计如下【可根据需要自行添加】:

CREATE TABLE `role` (
  `role_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `role_name` varchar(50) NOT NULL COMMENT '角色名称',
  `role_auth_ids` text NOT NULL COMMENT '角色具有权限的id组合,1,2,3',
  `role_auth_ac` text COMMENT '权限的控制器和方法的组合,格式:控制器-方法',
  `role_auth_name` text,
  `role_des` varchar(500) NOT NULL COMMENT '描述',
  `role_status` tinyint(1) DEFAULT '0' COMMENT '0:有效,1:禁用,2:删除',
  `add_time` int(11) DEFAULT NULL,
  `update_time` int(11) DEFAULT NULL,
  PRIMARY KEY (`role_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色表';
PHP代码部分如下:
//渲染视图
 public function showList()
    {
        return $this->fetch('index');
    }

//渲染数据
public function showListApi()
    {
        $roleList = db('sw_role')->field("*,FROM_UNIXTIME(add_time,'%Y-%m-%d %H:%i') as add_time")->select();
         return json_encode(array('code'=>0, 'data' => $roleList));
    }

//添加提交
    public function addRoleApi()
    {
        $data = request()->param();
        $roleIds = implode(',', $data['role_auth_ids']);
        $authList = db('sw_authority')->where("auth_id IN ({$roleIds})")->select(); //所有选中的数据
        $authName = array_column($authList,'auth_name');
        $roleName = db('sw_role')->where("role_name  = '{$data['role_name']}'")->find(); //查询角色名称
        $ownRoleIds = db('sw_role')->where("role_auth_ids  = '{$roleIds}'")->find(); //查询角色已经存在的权限ID
        if ($roleName){
            ajax_return(array('status'=>'error','msg'=>'角色名称已经存在!'));
        }
        if ($ownRoleIds){
            ajax_return(array('status'=>'error','msg'=>'当前权限与“'. $ownRoleIds['role_name'] .'”完全相同'));
        }
        $temp = [];
        foreach ($authList as  $value) {
            //判断选中的pid不等于0的
            if ($value['auth_pid'] != 0) {
                $temp[] = $value['auth_c']. '-' . $value['auth_a']; //拼接控制器+方法名
            }
        }
        $roleAuthAc = implode(',', $temp);
        $roleData = [
            'role_name'         => $data['role_name'],
            'role_auth_ids'     => $roleIds,
            'role_auth_name'    => implode(',', $authName),
            'role_des'          => $data['role_des'],
            'role_auth_ac'      => $roleAuthAc,
            'role_status'       => 0,
            'add_time'          => time()
        ];
        if(db('sw_role')->insert($roleData)) {
            return json_encode(array('status'=>'success','msg'=>'添加成功!', 'url' => 'roleShowList'));
        } else {
            return json_encode(array('status'=>'error','msg'=>'添加失败!'));
        }
    }
//封装一个方法用于无限极角色回显【修改时用】
public function procHtml($menus)
    {
        $newArr = [];
        if(is_array($menus)) {
            $i = 0;
            foreach ($menus as $k => $t) {
                if ($t['auth_pid'] == 0) {
                    if (!empty($t['checked'])){
                        $newArr[$i]['checked'] = 'true';
                    }
                    $newArr[$i]['name'] = $t['auth_name'];
                    $newArr[$i]['value'] = $t['auth_id'];
                    if (!empty(!empty($t['trees']))){
                        if (!empty($t['checked'])){
                            $newArr[$i]['checked'] = 'true';
                        }
                        $newArr[$i]['name'] = $t['auth_name'];
                        $newArr[$i]['value'] = $t['auth_id'];
                        $newArr[$i]['list'] =$this->procHtml($t['trees']);
                    }
                } else {
                    if (!empty($t['trees'])){
                        if (!empty($t['checked'])){
                            $newArr[$i]['checked'] = 'true';
                        }
                        $newArr[$i]['name'] = $t['auth_name'];
                        $newArr[$i]['value'] = $t['auth_id'];
                        $newArr[$i]['list'] =$this->procHtml($t['trees']);
                    }else{
                        if (!empty($t['checked'])){
                            $newArr[$i]['checked'] = 'true';
                        }
                        $newArr[$i]['name'] = $t['auth_name'];
                        $newArr[$i]['value'] = $t['auth_id'];
                    }
                }
                $i++;
            }
        }
        return $newArr;
    }

//修改
public function updateSelectApi()
    {
        $data = request()->param();
        //所有权限
        $allList = db('sw_authority')->order('auth_sort DESC')->select();

        //当前ID拥有权限
        $ownAuthority = \db('sw_role')->where("role_id = {$data['roleId']}")->find();
        $ownAuthorityList = db('sw_authority')->where("auth_id IN ({$ownAuthority['role_auth_ids']})")->order('auth_sort DESC')->select();

        $newList = [];
        foreach ($allList as $key => $value){
            $newList[] = $value;
            foreach ($ownAuthorityList as $k => $v){
                if ($value['auth_id'] == $v['auth_id']){
                    $newList[$key]['checked'] = 'true';
                }
            }
        }
        $menus = $this->getTree($newList,0,1);
        $list = $this->procHtml($menus);
        $newList =[
            'code'  => 0,
            'msg'   =>'获取成功',
            'data'  => [
                'trees' => $list
            ]
        ];
         return json_encode(array('code'=>0,'data'=>$newList,'ownAuthority'=>$ownAuthority));
    }

html部分

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>权限树扩展分享</title>
    {include file="../public/resource/newWebcss.html" /}
    {include file="../public/resource/newWebjs.html" /}
</head>
<body>
<div class="layui-fluid">
    <div class="layui-card">
        <div class="layui-card-body" style="padding: 15px;">

            <form class="layui-form">
                <div class="layui-row">
                    <div class="layui-col-md11 layui-col-md-offset1">
                        <div class="layui-form">
                            <div class="layui-form-item">
                                <div class="layui-form-label">快捷操作</div>
                                <div class="layui-form-block">
                                    <button type="button" class="layui-btn layui-btn-primary" onclick="checkAll('#LAY-auth-tree-index')">全选</button>
                                    <button type="button" class="layui-btn layui-btn-primary" onclick="uncheckAll('#LAY-auth-tree-index')">全不选</button>
                                    <button type="button" class="layui-btn layui-btn-primary" onclick="showAll('#LAY-auth-tree-index')">全部展开</button>
                                    <button type="button" class="layui-btn layui-btn-primary" onclick="closeAll('#LAY-auth-tree-index')">全部隐藏</button>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-col-md6 layui-col-md-offset1">
                        <!-- 此扩展能递归渲染一个权限树,点击深层次节点,父级节点中没有被选中的节点会被自动选中,单独点击父节点,子节点会全部 选中/去选中 -->
                        <form class="layui-form">
                            <div class="layui-form-item">
                                <label class="layui-form-label">角色名称<span style="color: red">*</span></label>
                                <div class="layui-input-block">
                                    <input class="layui-input" type="text" required="" lay-verify="required" name="role_name" placeholder="请输入角色名称" />
                                </div>
                            </div>
                            <div class="layui-form-item">
                                <label class="layui-form-label">选择权限<span style="color: red">*</span></label>
                                <div class="layui-input-block">
                                    <div id="LAY-auth-tree-index"></div>
                                </div>
                            </div>
                            <div class="layui-form-item layui-form-text">
                                <label class="layui-form-label">权限描述<span style="color: red">*</span></label>
                                <div class="layui-input-block">
                                    <textarea placeholder="请输入内容" required="" lay-verify="required" id="role_des" name="role_des" class="layui-textarea"></textarea>
                                </div>
                            </div>
                            <div class="layui-form-item layui-layout-admin">
                                <div class="layui-input-block">
                                    <div class="layui-footer" style="left: 0;">
                                        <input type="hidden" id="roleId" value="{$roleId}">
                                        <button class="layui-btn" type="button" lay-submit lay-filter="LAY-auth-tree-submit">提交</button>
                                        <button class="layui-btn layui-btn-primary" type="reset">重置</button>
                                    </div>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </form>

        </div>
    </div>
</div>
</body>
<script type="text/javascript">
    layui.config({
        base: '__STATIC__/newWeb/layuiadmin/extends/layui_exts/',
    }).extend({
        authtree: 'authtree',
    });
    layui.use(['jquery', 'authtree', 'form', 'layer'], function(){
        var $ = layui.jquery;
        var authtree = layui.authtree;
        var form = layui.form;
        var layer = layui.layer;
        // 初始化
        $.ajax({
            url: '/roleUpdateSelectApi',
            data:{
                'roleId'    : $('#roleId').val()
            },
            dataType: 'json',
            success: function(data){
                var trees = data.data.data.trees;
                console.log(data.ownAuthority.role_name)
                var role_name = data.ownAuthority.role_name;
                var role_des = data.ownAuthority.role_des;
                $('input[name=role_name]').val(role_name)
                $('textarea[name=role_des]').val(role_des)
                // 渲染时传入渲染目标ID,树形结构数据(具体结构看样例,checked表示默认选中),以及input表单的名字
                authtree.render('#LAY-auth-tree-index', trees, {
                    inputname: 'authids[]'
                    ,layfilter: 'lay-check-auth'
                    // ,autoclose: false
                    // ,autochecked: false
                    // ,openchecked: true
                    // ,openall: true
                    ,autowidth: true
                });

                // PS:使用 form.on() 会引起了事件冒泡延迟的BUG,需要 setTimeout(),并且无法监听全选/全不选
                // PS:如果开启双击展开配置,form.on()会记录两次点击事件,authtree.on()不会
                form.on('checkbox(lay-check-auth)', function(data){
                    // 注意这里:需要等待事件冒泡完成,不然获取叶子节点不准确。
                    setTimeout(function(){
                        console.log('监听 form 触发事件数据', data);
                        // 获取选中的叶子节点
                        var leaf = authtree.getLeaf('#LAY-auth-tree-index');
                        console.log('leaf', leaf);
                        // 获取最新选中
                        var lastChecked = authtree.getLastChecked('#LAY-auth-tree-index');
                        console.log('lastChecked', lastChecked);
                        // 获取最新取消
                        var lastNotChecked = authtree.getLastNotChecked('#LAY-auth-tree-index');
                        console.log('lastNotChecked', lastNotChecked);
                    }, 100);
                });
                // 使用 authtree.on() 不会有冒泡延迟
                authtree.on('change(lay-check-auth)', function(data) {
                    console.log('监听 authtree 触发事件数据', data);
                    // 获取所有节点
                    var all = authtree.getAll('#LAY-auth-tree-index');
                    console.log('all', all);
                    // 获取所有已选中节点
                    var checked = authtree.getChecked('#LAY-auth-tree-index');
                    console.log('checked', checked);
                    // 获取所有未选中节点
                    var notchecked = authtree.getNotChecked('#LAY-auth-tree-index');
                    console.log('notchecked', notchecked);
                    // 获取选中的叶子节点
                    var leaf = authtree.getLeaf('#LAY-auth-tree-index');
                    console.log('leaf', leaf);
                    // 获取最新选中
                    var lastChecked = authtree.getLastChecked('#LAY-auth-tree-index');
                    console.log('lastChecked', lastChecked);
                    // 获取最新取消
                    var lastNotChecked = authtree.getLastNotChecked('#LAY-auth-tree-index');
                    console.log('lastNotChecked', lastNotChecked);
                });
                authtree.on('deptChange(lay-check-auth)', function(data) {
                    console.log('监听到显示层数改变',data);
                });
            }
        });
        form.on('submit(LAY-auth-tree-submit)', function(obj){
            var role_name = $('input[name=role_name]').val();
            var role_des = $('#role_des').val();
            var role_id = $('#roleId').val();
            console.log(role_name);
            console.log(role_des);
            var authids = authtree.getChecked('#LAY-auth-tree-index'); //已经选中节点
            var notchecked = authtree.getNotChecked('#LAY-auth-tree-index'); //未选中节点
            console.log('Choosed authids is', authids);
            console.log(notchecked);
            if (role_name == "" || role_name == null) {layer.msg('角色名称不能为空',function () {});return;}
            if (role_name.length <=3) {layer.msg('权限字数不少于4个字');return;}
            if (role_des == "" || role_des == null) {layer.msg('权限描述不能为空');return;}
            if (authids.length < 1) {layer.msg('至少有一个权限',function () {});return;}
            obj.field.authids = authids;
            $.ajax({
                url: '/UpdateRole',
                dataType: 'json',
                data: {
                    role_name       : role_name,
                    role_auth_ids   : authids,
                    id              : role_id,
                    role_des        : role_des
                },
                success: function(res){
                    if (res.status == 'success'){
                        layer.msg(res.msg, {icon: 6});
                        setTimeout(function () {
                            var index = parent.layer.getFrameIndex(window.name);
                            parent.location.href=res.url;  //刷新父级页面
                            parent.layer.close(index);     //关闭当前页面
                        },600)
                    }else {
                        layer.msg(res.msg,function () {});
                    }

                }
            });
            return false;
        });
    });
</script>
<script type="text/javascript">
    // 获取最大深度样例
    function getMaxDept(dst){
        layui.use(['jquery', 'layer', 'authtree'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;

            layer.alert('树'+dst+'的最大深度为:'+authtree.getMaxDept(dst));
        });
    }
    // 全选样例
    function checkAll(dst){
        layui.use(['jquery', 'layer', 'authtree'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;

            authtree.checkAll(dst);
        });
    }
    // 全不选样例
    function uncheckAll(dst){
        layui.use(['jquery', 'layer', 'authtree'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;

            authtree.uncheckAll(dst);
        });
    }
    // 显示全部
    function showAll(dst){
        layui.use(['jquery', 'layer', 'authtree'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;

            authtree.showAll(dst);
        });
    }
    // 隐藏全部
    function closeAll(dst){
        layui.use(['jquery', 'layer', 'authtree'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;

            authtree.closeAll(dst);
        });
    }
    // 获取节点状态
    function getNodeStatus(dst){
        layui.use(['jquery', 'layer', 'authtree', 'laytpl'], function(){
            var layer = layui.layer;
            var authtree = layui.authtree;
            var laytpl = layui.laytpl;

            // 获取所有节点
            var all = authtree.getAll('#LAY-auth-tree-index');
            // 获取所有已选中节点
            var checked = authtree.getChecked('#LAY-auth-tree-index');
            // 获取所有未选中节点
            var notchecked = authtree.getNotChecked('#LAY-auth-tree-index');
            // 获取选中的叶子节点
            var leaf = authtree.getLeaf('#LAY-auth-tree-index');
            // 获取最新选中
            var lastChecked = authtree.getLastChecked('#LAY-auth-tree-index');
            // 获取最新取消
            var lastNotChecked = authtree.getLastNotChecked('#LAY-auth-tree-index');

            var data = [
                {func: 'getAll', desc: '获取所有节点', data: all},
                {func: 'getChecked', desc: '获取所有已选中节点', data: checked},
                {func: 'getNotChecked', desc: '获取所有未选中节点', data: notchecked},
                {func: 'getLeaf', desc: '获取选中的叶子节点', data: leaf},
                {func: 'getLastChecked', desc: '获取最新选中', data: lastChecked},
                {func: 'getLastNotChecked', desc: '获取最新取消', data: lastNotChecked},
            ];

            var string =  laytpl($('#LAY-auth-tree-nodes').html()).render({
                data: data,
            });
            layer.open({
                title: '节点状态'
                ,content: string
                ,area: '800px'
                ,tipsMore: true
            });
            $('body').unbind('click').on('click', '.LAY-auth-tree-show-detail', function(){
                layer.open({
                    type: 1,
                    title: $(this).data('title')+'-节点详情',
                    content: '['+$(this).data('content')+']',
                    tipsMore: true
                });
            });
        });
    }
    // 显示到某层
    function showDept(dst) {
        layui.use(['layer', 'authtree', 'jquery'], function(){
            var jquery = layui.jquery;
            var layer = layui.layer;
            var authtree = layui.authtree;

            layer.prompt({title: '显示到某层'}, function(value, index, elem) {
                authtree.showDept(dst, value);
                layer.close(index);
            });
        });
    }
    // 关闭某层以后的所有层
    function closeDept(dst) {
        layui.use(['layer', 'authtree', 'jquery'], function(){
            var jquery = layui.jquery;
            var layer = layui.layer;
            var authtree = layui.authtree;

            layer.prompt({title: '关闭某层以后的所有层'}, function(value, index, elem) {
                authtree.closeDept(dst, value);
                layer.close(index);
            });
        });
    }
    // 转换列表
    function listConvert(url) {
        layui.use(['layer', 'authtree', 'jquery', 'form', 'code'], function(){
            var jquery = layui.jquery;
            var layer = layui.layer;
            var authtree = layui.authtree;
            var form = layui.form;

            layer.open({
                title: '列表转树演示'
                ,content: '<fieldset class="layui-elem-field layui-field-title"><legend>列表数据转权限树</legend></fieldset><form class="layui-form"> <div class="layui-form-item"> <label class="layui-form-label">多选权限</label> <div class="layui-input-block"> <div id="LAY-auth-tree-convert-index"></div> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" type="submit" lay-submit lay-filter="LAY-auth-tree-submit">提交</button> <button class="layui-btn layui-btn-primary" type="reset">重置</button> </div> </div></form><pre class="layui-code" id="LAY-auth-tree-convert-code"></pre>'
                ,area: ['800px', '400px']
                ,tipsMore: true
                ,success: function() {
                    $.ajax({
                        url: url,
                        dataType: 'json',
                        success: function(res){
                            $('#LAY-auth-tree-convert-code').text(JSON.stringify(res, null, 2));
                            layui.code({
                                title: '返回的列表数据'
                            });
                            // 支持自定义递归字段、数组权限判断等
                            // 深坑注意:如果API返回的数据是字符串,那么 startPid 的数据类型也需要是字符串
                            var trees = authtree.listConvert(res.data.list, {
                                primaryKey: 'alias'
                                ,startPid: '0'
                                ,parentKey: 'palias'
                                ,nameKey: 'name'
                                ,valueKey: 'alias'
                                ,checkedKey: res.data.checkedAlias
                            });
                            // 如果页面中多个树共存,需要注意 layfilter 需要不一样
                            authtree.render('#LAY-auth-tree-convert-index', trees, {
                                inputname: 'authids[]',
                                layfilter: 'lay-check-convert-auth',
                                // openall: true,
                                autowidth: true,
                            });
                        }
                    });
                },
            });
        });
    }
</script>
<!-- 状态模板 -->
<script type="text/html" id="LAY-auth-tree-nodes">
    <style type="text/css">
        .layui-layer-page .layui-layer-content{
            padding: 20px;
            line-height: 22px;
        }
    </style>
    <table class="layui-table">
        <thead>
        <th>方法名</th>
        <th>描述</th>
        <th>节点</th>
        </thead>
        <tbody>
        {{# layui.each(d.data, function(index, item) { }}
        <tr>
            <td>{{item.func}}</td>
            <td>{{item.desc}}</td>
            <td><a class="LAY-auth-tree-show-detail" href="javascript:;" data-title="{{item.desc}}" data-content="{{item.data.join(']<br>[')}}">查看详情</a>({{item.data.length}})</td>
        </tr>
        {{# });}}
        </tbody>
    </table>
</script>
</html>

用户

页面示例

列表

用户数据库字段设计如下【可根据需要自行添加】:

CREATE TABLE sw_manager (
mg_id int(11) NOT NULL AUTO_INCREMENT,
mg_name varchar(32) NOT NULL,
mg_pwd varchar(32) NOT NULL,
mg_time int(11) NOT NULL,
mg_role_id int(11) NOT NULL DEFAULT ‘2’ COMMENT ‘角色id’,
mg_status tinyint(1) NOT NULL DEFAULT ‘0’ COMMENT ‘0:正常,1:禁用’,
mg_remark varchar(20) DEFAULT NULL COMMENT ‘角色备注’,
mg_update_time int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘更新时间’,
mg_pid int(11) NOT NULL DEFAULT ‘0’,
mg_phone varchar(20) DEFAULT NULL COMMENT ‘登录手机号’,
deviceToken varchar(255) DEFAULT NULL COMMENT ‘手机唯一标识’,
type tinyint(1) DEFAULT ‘1’ COMMENT ’ 1 正常 2关闭’,
status tinyint(1) DEFAULT ‘2’ COMMENT ‘1 客服 2 坐席’,
mg_image varchar(255) DEFAULT NULL COMMENT ‘头像’,
online_status varchar(20) DEFAULT NULL COMMENT ‘状态’,
sign varchar(255) DEFAULT NULL COMMENT ‘签名’,
sex tinyint(1) DEFAULT ‘1’ COMMENT ‘1男 2女’,
email varchar(100) DEFAULT NULL COMMENT ‘邮箱’,
online_time int(11) DEFAULT NULL COMMENT ‘登陆时间’,
offline_time int(255) DEFAULT NULL COMMENT ‘离线时间’,
PRIMARY KEY (mg_id) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3410 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT=‘用户表’

本文含有隐藏内容,请 开通VIP 后查看