zoukankan      html  css  js  c++  java
  • 按钮级别权限管理数据库设计及后台接口实现

    目的:

      避免反复coding ,将此作为一个 component ,任何项目只需复制起表结构和后台代码即可使用,前端样式可根据项目需求做改动,只需调用后台提供的接口即可。

    语言:java

    数据库:mysql

    数据库设计: 一共 5 张表 ,分别是用户表(t_sec_user),角色表(t_sec_role),菜单表(t_sec_menu),用户角色关系表(t_sec_re_user_role) , 角色菜单关系表(t_sec_re_role_menu)。

    这里的逻辑主要是 :一个用户能够操作哪些菜单 作为一个‘组' ,'组'在这里的定义是 对菜单而言的 。对用户而言,假设 n个的用户都是很奇怪的 ,他们都想拥有不同的操作菜单。作为开发人员的我们,对于这种想法完全可以不用管。在我们心中 不管用户数量再多,我们都能用一个规则去划分用户类别,在同一个类别的用户  所操作的菜单是一样的 。简单理解 就是 菜单是小兵,角色是军队的头衔 ,用户 就是可以赋予这些头衔的人类。用户能够控制哪些小兵,是要看他是怎样的头衔(角色)。

    建表sql 如下:

      1 /*
      2 Navicat MySQL Data Transfer
      3 
      4 Source Server         : 127.0.0.1mysql
      5 Source Server Version : 50519
      6 Source Host           : localhost:3306
      7 Source Database       : pms
      8 
      9 Target Server Type    : MYSQL
     10 Target Server Version : 50519
     11 File Encoding         : 65001
     12 
     13 Date: 2017-08-13 00:23:56
     14 */
     15 
     16 SET FOREIGN_KEY_CHECKS=0;
     17 
     18 -- ----------------------------
     19 -- Table structure for t_sec_menu
     20 -- ----------------------------
     21 DROP TABLE IF EXISTS `t_sec_menu`;
     22 CREATE TABLE `t_sec_menu` (
     23   `id` varchar(128) NOT NULL,
     24   `name` varchar(128) DEFAULT NULL COMMENT '菜单名',
     25   `display_name` varchar(128) DEFAULT NULL COMMENT '菜单展示名',
     26   `router` varchar(1024) DEFAULT NULL COMMENT '前端跳转路由',
     27   `params` varchar(4096) DEFAULT NULL COMMENT '参数',
     28   `active` decimal(1,0) DEFAULT NULL COMMENT '是否启用',
     29   `read_only` decimal(1,0) DEFAULT NULL COMMENT '是否只读 1 只读 ',
     30   `parent` varchar(128) DEFAULT NULL COMMENT '父级id',
     31   `sence` varchar(128) DEFAULT NULL COMMENT '场景',
     32   `m_icon` varchar(128) DEFAULT NULL COMMENT '图标样式',
     33   `note` varchar(1024) DEFAULT NULL COMMENT '备注',
     34   `seq` int(38) DEFAULT NULL COMMENT '序号',
     35   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
     36   `create_user` varchar(128) DEFAULT NULL COMMENT '创建用户',
     37   `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改时间',
     38   `update_user` varchar(128) DEFAULT NULL COMMENT '修改用户',
     39   `delete_flag` decimal(1,0) DEFAULT NULL COMMENT '删除标志',
     40   PRIMARY KEY (`id`)
     41 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单项';
     42 
     43 -- ----------------------------
     44 -- Records of t_sec_menu
     45 -- ----------------------------
     46 
     47 -- ----------------------------
     48 -- Table structure for t_sec_re_role_menu
     49 -- ----------------------------
     50 DROP TABLE IF EXISTS `t_sec_re_role_menu`;
     51 CREATE TABLE `t_sec_re_role_menu` (
     52   `id` varchar(128) NOT NULL,
     53   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
     54   `create_user` varchar(128) DEFAULT NULL COMMENT '创建用户',
     55   `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改时间',
     56   `update_user` varchar(128) DEFAULT NULL COMMENT '修改用户',
     57   `delete_flag` decimal(1,0) DEFAULT NULL COMMENT '删除标志',
     58   `role_id` varchar(128) DEFAULT NULL COMMENT '角色id',
     59   `menu_id` varchar(128) DEFAULT NULL COMMENT '菜单id',
     60   PRIMARY KEY (`id`)
     61 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色菜单关系表';
     62 
     63 -- ----------------------------
     64 -- Records of t_sec_re_role_menu
     65 -- ----------------------------
     66 
     67 -- ----------------------------
     68 -- Table structure for t_sec_re_user_role
     69 -- ----------------------------
     70 DROP TABLE IF EXISTS `t_sec_re_user_role`;
     71 CREATE TABLE `t_sec_re_user_role` (
     72   `id` varchar(128) NOT NULL,
     73   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
     74   `create_user` varchar(128) DEFAULT NULL COMMENT '创建用户',
     75   `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改时间',
     76   `update_user` varchar(128) DEFAULT NULL COMMENT '修改用户',
     77   `delete_flag` decimal(1,0) DEFAULT NULL COMMENT '删除标志',
     78   `role_id` varchar(128) DEFAULT NULL COMMENT '角色 id',
     79   `user_id` varchar(128) DEFAULT NULL COMMENT '用户id',
     80   PRIMARY KEY (`id`)
     81 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色关联表';
     82 
     83 -- ----------------------------
     84 -- Records of t_sec_re_user_role
     85 -- ----------------------------
     86 
     87 -- ----------------------------
     88 -- Table structure for t_sec_role
     89 -- ----------------------------
     90 DROP TABLE IF EXISTS `t_sec_role`;
     91 CREATE TABLE `t_sec_role` (
     92   `id` varchar(128) NOT NULL,
     93   `name` varchar(128) DEFAULT NULL COMMENT '角色名',
     94   `note` varchar(2048) DEFAULT NULL COMMENT '备注信息',
     95   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
     96   `create_user` varchar(128) DEFAULT NULL COMMENT '创建用户',
     97   `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改时间',
     98   `update_user` varchar(128) DEFAULT NULL COMMENT '修改用户',
     99   `delete_flag` decimal(1,0) DEFAULT NULL COMMENT '删除标志',
    100   PRIMARY KEY (`id`)
    101 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';
    102 
    103 -- ----------------------------
    104 -- Records of t_sec_role
    105 -- ----------------------------
    106 
    107 -- ----------------------------
    108 -- Table structure for t_sec_user
    109 -- ----------------------------
    110 DROP TABLE IF EXISTS `t_sec_user`;
    111 CREATE TABLE `t_sec_user` (
    112   `id` varchar(128) NOT NULL,
    113   `name` varchar(128) DEFAULT NULL COMMENT '登陆用户名',
    114   `password` varchar(1024) DEFAULT NULL COMMENT '密码',
    115   `display_name` varchar(128) DEFAULT NULL COMMENT '前台展示名',
    116   `telephone` varchar(64) DEFAULT NULL COMMENT '办公电话',
    117   `mobile` varchar(64) DEFAULT NULL COMMENT '移动电话',
    118   `fax` varchar(64) DEFAULT NULL COMMENT '传真',
    119   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    120   `create_user` varchar(128) DEFAULT NULL COMMENT '创建用户',
    121   `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改时间',
    122   `pwd_update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '最近密码更改时间',
    123   `update_user` varchar(128) DEFAULT NULL COMMENT '修改用户',
    124   `delete_flag` decimal(1,0) DEFAULT NULL COMMENT '删除标志',
    125   PRIMARY KEY (`id`)
    126 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';
    127 
    128 -- ----------------------------
    129 -- Records of t_sec_user
    130 -- ----------------------------

    后台结构 这里 我使用脚手架自动生成,详细代码就不展现了,无非是数据的增删改查,主要结构如下,

    在用户登陆时,将用户信息放入session 中,登陆成功后,发出获取菜单请求,后台取出session 中的用户信息(用到的是 用户id),根据用户的id 关联查询出,该用户能操作的所有菜单项 。这时候需要整合下 菜单项,因为如果是一次性查出所有菜单,结果是一个List ,并不是一个树状菜单 ,因为菜单有一个parent 字段表示该菜单的父级菜单, 如果parent为null 那么这就是一个顶级菜单,不为空则为子菜单, 这里的整合无非就是 将一个数组,整合成一个树,这个算法很简单,

     @Override
        public List<Menu> getAllMenuByUser(String id) {
            String allMenuSql = getAllMenuSql();
            StringBuffer sql = new StringBuffer() ;
            sql.append(allMenuSql) ;
            List params = new ArrayList();
            params.add(id);
            //查询到该用户能操作的菜单项数组
            List<Menu> allMenus = getDataBase().query4Model(sql.toString(),Menu.class ,params.toArray());
            
            List<Menu> tmpMenus = new ArrayList(); //存放菜单树
            if (allMenus != null) {
                for (int i = 0,length = allMenus.size(); i <length; i++) {
                    Menu menu = allMenus.get(i) ;
                    if (StringUtils.isEmpty(menu.getParent())){
                        //如果没有父亲 那自己就是 最上层父级菜单
                        List<Menu> childMenus = findChildren(menu,allMenus);
                        if (childMenus!=null && childMenus.size() >0){
                            menu.setChildren(childMenus);
                        }
                        tmpMenus.add(menu);
                    }
                }
            }
    
    
            return tmpMenus ;
    
        }
    /**
         * 递归找孩子
         * @param menu
         * @param allMenus
         * @return
         */
        private  List<Menu> findChildren(Menu menu, List<Menu> allMenus) {
            if (menu.getChildren() == null) {
                menu.setChildren(new ArrayList<Menu>());
            }
            for (int i = 0,length = allMenus.size(); i < length; i++) {
                Menu child = allMenus.get(i) ;
    
                if (!StringUtils.isEmpty(child.getParent())){
                    if (child.getParent().equals(menu.getId())){
                        List<Menu> childrenMenu = findChildren(child,allMenus);
                        if (childrenMenu!=null && childrenMenu.size() >0){
                            child.setChildren(childrenMenu);
                        }
                        menu.getChildren().add(child);
                    }
                }
            }
            return menu.getChildren();
        }

     黄色部分,根据自己后台架构做更改,主要是查询到该用户能操作的菜单项数组。

  • 相关阅读:
    c++ 指定目录下的文件遍历
    c++ 实现键盘钩子
    c++ 用模板类实现顺序储存的线性表
    c++ 递归算法实现排列组合
    matlab 基础知识
    QT 给工程添加图片
    QT5.9 QString和字符串转换的乱码问题
    【内核】——进程3,内核同步
    Java多线程——Thread的native底层实现
    【内核】——文件和文件系统的内部结构4 系统调用的实现
  • 原文地址:https://www.cnblogs.com/hsc13-lxy14/p/7344479.html
Copyright © 2011-2022 走看看