简述:前端
权限是什么?针对咱们后台系统简单说,就是不一样用户登陆后,看到的模块-菜单-功能按钮的维度不一样。本次主要讲权限模块表设计、表关联关系、如何作到权限控制、以及登陆过程后台都发生了什么。咱们的后台涉及到两个权限角色,一个是针对平台管理员、供应商管理员的大权限角色 sys_role;一个是针对平台、供应商普通员工的小权限角色 company_role。管理员涉及到:role.xml功能菜单树、sys_role,sys_admin,customer_info三张表和sysAdiminLogin视图;普通员工涉及到:role.xml功能菜单树、company_role公司角色表,company_dept公司部门表,company_user公司员工三张表和adminLogin视图。这里只讲大权限表关系,小权限表关系相似。角色表sys_role和功能菜单是多对多的关系,一个角色能够有多功能菜单,一个功能菜单也能够对应多个角色;管理员表sys_admin和角色表sys_role是多对一的关系,及一个管理员只能有一个角色,但一个角色可对应多个管理员(其它平台通常设计成多对多的关系,他们的角色表是针对于模块。如商品角色、订单角色等),本质上是同样的,咱们角色可对应多个模块的功能菜单。咱们菜单功能数据使用xml文件管理的,好处的能够下降数据库呀压力;不太方便的是每增长菜单或功能都要从新部署平台模块。登陆发生了什么:根据帐号和密码查询数据库,若验证经过拿到登陆者信息(含拥有的功能权限ID逗号拼接),将该信息放到缓存中并返回token给前端。前端拿着token、sign数据请求用户菜单信息接口,根据返回数据展现对应模块菜单信息。所登陆的用户共4种,1-平台管理员,2-平台员工,3-供应商管理员,4-供应商员工。(其中供应商登陆者最多只能看到平台为该供应商管理员指定的角色权限功能)。redis
一:表设计数据库
sys_role:平台角色权限表,用于管理员(平台-供应商)缓存
CREATE TABLE `sys_role` ( `id` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限值ID:自增', `role_name` varchar(30) NOT NULL COMMENT '角色名称', `description` varchar(100) DEFAULT NULL COMMENT '权限描述', `permission` text COMMENT '权限ID集', `pid` int(2) DEFAULT NULL COMMENT '大类ID 1:平台商-2:采购商-3供应商', `create_time` datetime DEFAULT NULL COMMENT '建立时间', `creator` varchar(30) DEFAULT NULL COMMENT '建立人', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(30) DEFAULT NULL COMMENT '修改人', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8 COMMENT='平台角色权限表
sys_admin:平台管理者表,用于存储平台和供应商管理员,(关联平台角色ID、供应商ID)。平台管理员是预置的,供应商管理员是添加供应商时添加的。微信
CREATE TABLE `sys_admin` ( `id` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限值ID:自增', `sys_admin_name` varchar(30) NOT NULL COMMENT '管理者名称', `sys_admin_pwd` varchar(32) DEFAULT NULL COMMENT '管理者密码', `cid` int(8) DEFAULT NULL COMMENT '公司ID', `sys_role_id` int(8) DEFAULT NULL COMMENT '平台角色ID', `user_type` int(1) DEFAULT NULL COMMENT '用户固定标签 0:管理员', `icon` varchar(100) DEFAULT NULL COMMENT '头像', `token` varchar(32) DEFAULT NULL COMMENT '登陆Token', `login_time` varchar(20) DEFAULT NULL COMMENT '最后登陆时间', `create_time` datetime DEFAULT NULL COMMENT '建立时间', `creator` varchar(30) DEFAULT NULL COMMENT '建立人', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(30) DEFAULT NULL COMMENT '修改人', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=310 DEFAULT CHARSET=utf8 COMMENT='平台管理者表'
sysAdiminLogin:后台管理员登陆视图SQLsession
SELECT (CASE`e`.`pid` WHEN '1' THEN '平台管理员' WHEN '3' THEN '供应商管理员' ELSE '' END) AS `user_name`, `a`.`token` AS `token`, `a`.`sys_admin_name` AS `phone`, #登陆名 `a`.`sys_admin_pwd` AS `passwd`, #登陆密码 `a`.`id` AS `uid`, #管理员ID `a`.`user_type` AS `user_type`, #用户固定标签 0:管理员 1:普通员工 `f`.`customer_name` AS `customer_name`, #公司名称 `f`.`status` AS `status`, #用户状态 0-禁用,1-启用 `f`.`id` AS `cid`, #公司ID `e`.`pid` AS `customer_type`, #大类ID 1-平台商,3-供应商 `e`.`permission` AS `permission`, #权限 `e`.`role_name` AS `role_name` #角色名 FROM `sys_admin` `a` LEFT JOIN `sys_role` `e` ON `a`.`sys_role_id` = `e`.`id` LEFT JOIN `customer_info` `f` ON `a`.`cid` = `f`.`id`
company_role:公司角色权限表,设置公司员工权限 (关联公司ID,该角色属于哪一个公司)架构
CREATE TABLE `company_role` ( `id` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限值ID:自增', `cid` int(8) NOT NULL COMMENT '公司ID', `role_name` varchar(30) NOT NULL COMMENT '权限名称', `description` varchar(100) DEFAULT NULL, `permission` varchar(5000) DEFAULT NULL COMMENT '权限', `create_time` datetime DEFAULT NULL COMMENT '建立时间', `creator` varchar(30) DEFAULT NULL COMMENT '建立人', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(30) DEFAULT NULL COMMENT '修改人', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=179 DEFAULT CHARSET=utf8 COMMENT='公司角色权限表'
company_dept:公司部门表,保存公司部门(关联公司ID,该部门属于哪一个公司)ui
CREATE TABLE `company_dept` ( `id` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '表ID:自增', `dept_name` varchar(30) NOT NULL COMMENT '部门名称', `pid` int(8) DEFAULT NULL COMMENT '父级部门ID', `cid` int(8) NOT NULL COMMENT '公司ID', `create_time` datetime DEFAULT NULL COMMENT '建立时间', `creator` varchar(30) DEFAULT NULL COMMENT '建立者 id', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(30) DEFAULT NULL COMMENT '修改人', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=181231 DEFAULT CHARSET=utf8 COMMENT='公司部门表'
company_user:公司员工表,(关联公司角色ID,有什么权限;关联公司部门ID,属于哪一个部门)加密
CREATE TABLE `company_user` ( `id` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '表ID:自增', `user_name` varchar(30) NOT NULL COMMENT '用户名称', `passwd` varchar(32) NOT NULL COMMENT '登录密码(MD5加密)', `token` varchar(32) DEFAULT NULL COMMENT '登陆Token', `pid` int(8) DEFAULT NULL COMMENT '上级ID', `phone` varchar(30) NOT NULL COMMENT '手机号码', `qq` varchar(20) DEFAULT NULL COMMENT 'qq号', `wechat` varchar(32) DEFAULT NULL COMMENT '微信号', `email` varchar(32) DEFAULT NULL COMMENT '邮箱', `dept_id` int(8) DEFAULT NULL COMMENT '部门ID', `role_id` int(8) NOT NULL COMMENT '角色ID', `user_type` int(1) DEFAULT NULL COMMENT '用户固定标签 1:普通员工', `icon` varchar(100) DEFAULT NULL COMMENT '头像', `view_scope` int(1) DEFAULT '0' COMMENT '查看数据范围(1-本人,2-本部门,3-公司,4,所有)', `status` int(1) DEFAULT NULL COMMENT '员工状态 0-离职,1-在职', `login_time` varchar(20) DEFAULT NULL COMMENT '最新登陆时间', `create_time` datetime DEFAULT NULL COMMENT '建立时间', `creator` varchar(30) DEFAULT NULL COMMENT '建立者 id', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(30) DEFAULT NULL COMMENT '修改人', `token2` varchar(32) DEFAULT NULL COMMENT '渠道部APP登陆token', `remark` varchar(100) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=233 DEFAULT CHARSET=utf8 COMMENT='公司员工表'
adminLogin:公司员工登陆视图url
SELECT `a`.`user_name` AS `user_name`, #员工名 `a`.`token` AS `token`, `a`.`passwd` AS `passwd`, #密码 `a`.`phone` AS `phone`, #登陆名 `a`.`id` AS `uid`, #员工ID `a`.`user_type` AS `user_type`, #用户固定标签 1:普通员工 `a`.`view_scope` AS `view_scope`, #查看数据范围(1-本人,2-本部门,3-公司,4-所有) `b`.`id` AS `did`, #部门ID `b`.`dept_name` AS `dept_name`, #部门名称 `c`.`id` AS `rid`, #角色ID `c`.`role_name` AS `role_name`, #角色名称 `c`.`permission` AS `permission`, #权限ID集 `e`.`role_name` AS `sys_role_name`, #大类权限名称 `f`.`id` AS `cid`, #所公司ID `f`.`customer_name` AS `customer_name`, #所属公司 `f`.`customer_type` AS `customer_type`, #所属公司类型(1-平台商,3-供应商) `f`.`status` AS `status` #所属公司(供应商)状态 0-禁用,1-启用 FROM `company_user` `a` LEFT JOIN `company_dept` `b`ON `a`.`dept_id` = `b`.`id` LEFT JOIN `company_role` `c` ON `c`.`id` = `a`.`role_id` LEFT JOIN `customer_info` `f` ON `c`.`cid` = `f`.`id` LEFT JOIN `sys_role` `e` ON (`e`.`pid` = `f`.`customer_type` AND `e`.`id` = `f`.`category`) WHERE `a`.`status` = 1
三:权限树格式,role.xml文件,菜单作到二级,功能按钮作到一级
<?xml version="1.0" encoding="UTF8"?> <org> <model name="平台" id="10001" url="/platform"> <menu name="员工管理" id="1000101" url="" icon="employee"> <action id="100010101" name="组织架构" url="/platform/index"> <function id="10001010101" name="组织架构列表"></function> <function id="10001010102" name="添加部门"></function> <function id="10001010103" name="编辑部门"></function> <function id="10001010104" name="删除部门"></function> <function id="10001010105" name="添加员工"></function> <function id="10001010106" name="编辑员工"></function> <function id="10001010107" name="重置密码"></function> <function id="10001010108" name="删除员工"></function> </action> </menu> </model> <model name="客户" id="10002" url="/custom"> <menu name="采购商管理" id="1000201" url="" icon="purchase"> <action id="100020101" name="采购商列表" url="/custom/index"> <function id="10002010101" name="采购商列表"></function> <function id="10002010102" name="添加采购商" url="/custom/addPurchase"></function> <function id="10002010103" name="编辑采购商" url="/custom/addPurchase"></function> <function id="10002010104" name="查看采购商" url="/custom/checkPurchase"></function> <function id="10002010105" name="启用/禁用采购商"></function> <function id="10002010106" name="分配采购商" url="/custom/checkPurchase"></function> <function id="10002010107" name="审核采购商" url="/custom/confirmReview"></function> <function id="10002010108" name="复审采购商" url="/custom/confirmReview"> </function> <function id="10002010109" name="重置密码"></function> </action> </menu> </model> </org>
四:角色权限重要实现
(1)登陆接口:localhost:6001/sys/user/adminLogin (参数:手机号,密码)
1.进入滤器,进行签名验证,登陆时不需token验证; 2.经过手机号、MD5(密码)做为参数获取登陆信息,(管理员->sysAdiminLogin视图,普通员工->adminLogin视图); 3.若拿到登陆信息,数据验证(如部门、角色、权限、禁用等),清除缓存老的token; 4.用户名+公司名+手机号+当前时间,MD5双重加密生成新token; 5.改变最新登陆时间,缓存添加新token,设置有效时间为1小时; 6.更新数据库对应登录者的token、最新登陆时间; 7.登陆成功返回token,用户信息(去除密码)。
token验证及redis缓冲延时:
1.根据指定前缀+token做为key,从redis获取登陆信息userInfo;
2.若拿到userIfon,若是缓存有效时间小于10分钟将更新缓存;
3.以relogin为键将userInfo放到session中,而后放行。
(2)获取用户对应菜单信息:localhost:6001/sys/sysRole/getMenuByRoleId
目的:展现对应的模块和菜单
1.从session获取登陆信息,拿到用户角色对应逗号拼接功能权限ids;
2.循环拿到每一个功能id遍历role.xml找到对应元素及全部上级元素封装到List<SysRoleVO> list;
3.上面的list会存在多个重复的功能上级元素,重写SysRoleVO的equals方法(name、id都相同),经过contains方法判断去重;
4.找到全部的一级节点,为一级节点设置子菜单(递归,继续为子菜单添加子菜单)返回。
( 3)平台用户类型、角色管理权限树:localhost:6001/sys/sysRole/getRolePermission ,localhost:6001/sys/role/getRolePermission
目的:为用户类型-角色受权作准备
1.经过角色roleId获取逗号拼接功能权限ids;
2.new SAXReader().read(is)加载role.xml权限树,将全部元素封装到List<RoleVO> list,RoleVO全部auth属性值均为false; 3.循环list,ids改变auth属性值为true或false;4.找到全部的一级节点,为一级节点设置子菜单(递归,继续为子菜单添加子菜单)返回。
( 4)供应商管理员及供应商员工,角色权限树-->localhost:6001/sys/role/getRolePermission 注:最多只能看到平台为该供应商管理员分配的权限菜单
1.从session获取登陆信息,拿到管理员逗号拼接功能权限ids; 2.根据角色ID获取角色对应权限ds2; 3.遍历ids拿到每一个id去匹配role.xml,将部分元素封装到list<RoleVo> list,同时便利ids2比较是否相等,改变auth属性值为true或false; 4.去重,递归分配子菜单。
五:组织架构重要实现
(1)获取组织架构树结构:http://192.168.99.131:6001/sys/dept/findDeptByCid
1.根据公司ID找到全部的部门List<CompanyDeptVo> rootDepartment ;
2.遍历rootDepartment拿到全部的一级部门了,一级菜单没有parentId;
3.为一级菜单递归设置子菜单,同时统计一级菜单所拥有的员工数(含子部门员工);
(3)获取员工列表:http://192.168.99.131:6001/sys/user/findUserByParm
1.经过部门ID参数查询所属部门id集合;2.经过部门Id集合过滤员工;