One , Database table design
1. Permission related table
CREATE TABLE `t_sys_action` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ', `name`
varchar(32) DEFAULT NULL COMMENT ' Operation name ', `code` varchar(32) DEFAULT NULL
COMMENT ' code ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE
TABLE `t_sys_resource` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ', `name`
varchar(64) DEFAULT NULL COMMENT ' Resource name ', `code` varchar(64) DEFAULT NULL
COMMENT ' Resource code ', `level` int(11) DEFAULT NULL COMMENT ' Resource level ', `parent_id`
varchar(32) DEFAULT NULL COMMENT ' Parent id', `rank` int(11) DEFAULT NULL COMMENT
' sort ', `img` varchar(64) DEFAULT NULL COMMENT ' Resource picture ', `url` varchar(126) DEFAULT
NULL COMMENT ' route ', `description` varchar(255) DEFAULT NULL COMMENT ' describe ', `type`
varchar(255) DEFAULT NULL COMMENT ' type ', `isleaf` int(1) DEFAULT NULL COMMENT
' Is it a leaf node 1 yes ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE
TABLE `t_sys_privilege` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ', `name`
varchar(64) DEFAULT NULL COMMENT ' Permission name ', `code` varchar(64) DEFAULT NULL
COMMENT ' code ', `resource_id` varchar(32) DEFAULT NULL COMMENT ' Resource number ',
`action_id` varchar(32) DEFAULT NULL COMMENT ' Operation number ', PRIMARY KEY (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `t_sys_role` ( `id`
varchar(32) NOT NULL COMMENT ' Primary key ', `name` varchar(32) DEFAULT NULL COMMENT
' Role name ', `code` varchar(32) DEFAULT NULL COMMENT ' code ', `rank` varchar(32)
DEFAULT NULL COMMENT ' sort ', `description` varchar(128) DEFAULT NULL COMMENT
' describe ', `enabled` int(1) DEFAULT NULL COMMENT ' state 0 delete 1 Enable 2 Disable ', PRIMARY KEY
(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE
`t_sys_role_privilege` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ', `role_id`
varchar(32) DEFAULT NULL COMMENT ' Role number ', `privilege_id` varchar(32) DEFAULT
NULL COMMENT ' Authority number ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `t_sys_user` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ', `user_name`
varchar(32) DEFAULT NULL COMMENT ' full name ', `password` varchar(32) DEFAULT NULL
COMMENT ' password ', `nick_name` varchar(64) DEFAULT NULL, `true_name` varchar(64)
DEFAULT NULL COMMENT ' Real name ', `salt` varchar(64) DEFAULT NULL COMMENT ' salt ',
`gender` int(11) DEFAULT NULL COMMENT '0 secrecy 1 male 2 female ', `age` int(11) DEFAULT NULL
COMMENT ' Age ', `mobile` varchar(20) DEFAULT NULL COMMENT ' Telephone number ', `email`
varchar(64) DEFAULT NULL COMMENT ' mailbox ', `country` varchar(32) DEFAULT NULL
COMMENT ' nationality ', `province` varchar(32) DEFAULT NULL COMMENT ' province ', `type` int(1)
DEFAULT NULL COMMENT '1, manufactor ,2 mechanism ', `city` varchar(126) DEFAULT NULL COMMENT ' city ',
`avatar_url` varchar(256) DEFAULT NULL COMMENT ' head portrait ', `language` varchar(64)
DEFAULT NULL, `last_login_ip` varchar(32) DEFAULT NULL, `last_login_time`
varchar(32) DEFAULT NULL, `create_time` varchar(32) DEFAULT NULL, `update_time`
varchar(32) DEFAULT NULL, `create_by` varchar(32) DEFAULT NULL, `update_by`
varchar(32) DEFAULT NULL, `enabled` int(1) DEFAULT NULL COMMENT ' state 0 delete 1 Enable
2 Disable ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=' User table ';
CREATE TABLE `t_sys_user_role` ( `id` varchar(32) NOT NULL COMMENT ' Primary key ',
`user_id` varchar(32) DEFAULT NULL COMMENT ' User number ', `role_id` varchar(32)
DEFAULT NULL COMMENT ' Role number ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT
CHARSET=utf8;
Other omissions ...
2. Related views
CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`%` SQL SECURITY DEFINER VIEW
`v_privilege` AS SELECT `t_sys_privilege`.`id` AS `id`,
`t_sys_privilege`.`resource_id` AS `resourceid`, `t_sys_privilege`.`action_id`
AS `actionid`, `t_sys_resource`.`code` AS `resourcecode`,
`t_sys_resource`.`name` AS `resourcename`, `t_sys_resource`.`type` AS
`resourcetype`, `t_sys_resource`.`parent_id` AS `parent_id`,
`t_sys_action`.`name` AS `actionname`, concat( `t_sys_resource`.`code`, ':',
`t_sys_action`.`code` ) AS `privilegecode` FROM ( ( `t_sys_resource` LEFT JOIN
`t_sys_privilege` ON ( ( `t_sys_privilege`.`resource_id` =
`t_sys_resource`.`id` ) ) ) LEFT JOIN `t_sys_action` ON ( (
`t_sys_privilege`.`action_id` = `t_sys_action`.`id` ) ) ) CREATE ALGORITHM =
UNDEFINED DEFINER = `root`@`%` SQL SECURITY DEFINER VIEW `v_user_role` AS
SELECT DISTINCT `usr`.`id` AS `id`, `usrr`.`user_id` AS `userid`,
`usrr`.`role_id` AS `roleid`, `usr`.`user_name` AS `username` FROM (
`t_sys_user` `usr` LEFT JOIN `t_sys_user_role` `usrr` ON ( ( `usrr`.`user_id` =
`usr`.`id` ) ) ) WHERE (`usrr`.`role_id` IS NOT NULL) CREATE ALGORITHM =
UNDEFINED DEFINER = `root`@`%` SQL SECURITY DEFINER VIEW `v_user_privilege` AS
SELECT `rl`.`userid` AS `USERID`, `rl`.`username` AS `USERNAME`, `rl`.`roleid`
AS `ROLEID`, `url`.`name` AS `ROLENAME`, `privilge`.`id` AS `PRIVILEGEID`,
`sr`.`id` AS `RESOURCEID`, `sr`.`code` AS `RESOURCECODE`, `sr`.`name` AS
`RESOURCENAME`, `sr`.`type` AS `RESOURCETYPE`, `sr`.`parent_id` AS `PARENTID`,
`sa`.`id` AS `ACTIONID`, `sa`.`code` AS `ACTIONCODE`, `sa`.`name` AS
`ACTIONNAME`, concat( `sr`.`code`, ':', `sa`.`code` ) AS `PRIVILEGECODE` FROM (
( ( ( ( `v_user_role` `rl` LEFT JOIN `t_sys_role` `url` ON ((`rl`.`roleid` =
`url`.`id`)) ) LEFT JOIN `t_sys_role_privilege` `urp` ON ( (`url`.`id` =
`urp`.`role_id`) ) ) LEFT JOIN `t_sys_privilege` `privilge` ON ( (
`urp`.`privilege_id` = `privilge`.`id` ) ) ) LEFT JOIN `t_sys_resource` `sr` ON
( ( `privilge`.`resource_id` = `sr`.`id` ) ) ) LEFT JOIN `t_sys_action` `sa` ON
( ( `privilge`.`action_id` = `sa`.`id` ) ) )
Two , menu bar , Query according to user permissions
1. Query permission resources related to users ( The lowest child node , Permissions are directly mounted on function points )
<select id="getResourceByUserName" resultMap="BaseResultMap"> SELECT * FROM
t_sys_resource WHERE id IN ( SELECT DISTINCT RESOURCEID FROM `v_user_privilege`
WHERE USERName = #{userName, jdbcType=VARCHAR} ) </select>
2. Recursively find all the parent nodes according to the child nodes , Assemble into tree structure
service layer :
/** * Get all resources related to permissions according to the user name ( Father and son ) * * @return */ public
ServiceResult<List<ResourceAO>> getResource(String userName) { //1. Query all resources
ServiceResult<List<ResourceAO>> listServiceResult = selectByCriteria(null);
List<ResourceAO> allResourceList = null; if (listServiceResult != null &&
listServiceResult.isSucceed() &&
!CollectionUtils.isEmpty(listServiceResult.getData())) { allResourceList =
listServiceResult.getData(); } // Super administrator
if(Constant.SYSTEM_SUPER_ADMIN.equals(userName)){ return
listTreeNodes(allResourceList); } //2. Query the resources associated with user permissions List<ResourceAO>
resourceChildren = getResourceByUserName(userName); //3. Resources associated by permissions ( Children ) Query all parents
List<ResourceAO> parentResourceList = new ArrayList<>(); if
(!CollectionUtils.isEmpty(resourceChildren)) { for (ResourceAO child :
resourceChildren) { getParentResourceList(allResourceList, child.getId(),
parentResourceList); } } // The query resources are assembled into tree nodes return
listTreeNodes(parentResourceList); } /** * Query all parent resources based on children * * @param
allResourceList * @param childId * @param parentResourceList * @return */
private List<ResourceAO> getParentResourceList(List<ResourceAO>
allResourceList, String childId, List<ResourceAO> parentResourceList) { if
(!CollectionUtils.isEmpty(allResourceList)) { for (ResourceAO resource :
allResourceList) { // Determine whether there is a parent node if (resource.getId().equals(childId)) { //
Recursively traverse the upper level getParentResourceList(allResourceList, resource.getParentId(),
parentResourceList); if (!parentResourceList.contains(resource)) {
parentResourceList.add(resource); } } } return parentResourceList; } return
null; } /** * Get tree structure data * * @return */ public ServiceResult<List<ResourceAO>>
listTreeNodes(List<ResourceAO> allList) { ServiceResult<List<ResourceAO>> ret =
new ServiceResult<>(); List<ResourceAO> parentList = new ArrayList<>();// Root node
List<ResourceAO> allResourceList = null; if (!CollectionUtils.isEmpty(allList))
{ allResourceList = allList; for (ResourceAO resource : allList) { if
(StringUtils.isEmpty(resource.getParentId())) { parentList.add(resource); } } }
// Returned tree node data List<ResourceAO> treeNodeList = new ArrayList<>(); if
(!CollectionUtils.isEmpty(parentList)) { for (ResourceAO parent : parentList) {
// Recursively query all child nodes treeNodeList.add(recursiveTree(parent, allResourceList)); } }
ret.setData(treeNodeList); ret.setSucceed(true); return ret; } /** *
Recursive algorithm resolves to tree structure */ public ResourceAO recursiveTree(ResourceAO parentNode,
List<ResourceAO> allResourceList) { List<ResourceAO> childTreeNodes =
getChildTree(parentNode.getId(), allResourceList); if
(!CollectionUtils.isEmpty(childTreeNodes)) { for (ResourceAO child :
childTreeNodes) { ResourceAO n = recursiveTree(child, allResourceList);
parentNode.getChildren().add(n); } } return parentNode; } /** * Based on parent node ID Get all child nodes
*/ public List<ResourceAO> getChildTree(String parentId, List<ResourceAO>
allResourceList) { List<ResourceAO> childNodes = new ArrayList<>(); if
(!CollectionUtils.isEmpty(allResourceList)) { for (ResourceAO resource :
allResourceList) { if (parentId.equals(resource.getParentId())) {
childNodes.add(resource); } } } return childNodes; }
controller layer :
/** * Access to resources . * * @return */ @RequestMapping(value = "/getResource", method =
{RequestMethod.GET, RequestMethod.POST}) @LogOperation(action = " Access to resources ") public
Object getResource(@RequestParam String userName) { return
resourceService.getResource(userName); }
At this point, the home menu is assembled according to the permissions of the tree structure back-end interface .
3.vue The front end obtains the menu tree from the back end interface and displays it on the page
(1)MenuTree.vue Menu tree component
<template> <el-submenu v-if="menu.children && menu.children.length >= 1"
:key="menu.id" :index="menu.name"> <template slot="title"> <i :class="menu.img"
:style="{ marginLeft: asideContainerW }"></i> <span slot="title">{
{menu.name}}</span> </template> <MenuTree v-for="item in menu.children"
:menu="item" :key="item.id"></MenuTree> </el-submenu> <el-menu-item v-else
:index="menu.url" :key="menu.id" @click="handleRoute(menu)"> <i
:class="menu.img" :style="{ marginLeft: asideContainerChildW }"></i> <span
slot="title" style="font-size: 12px">{{menu.name}}</span> </el-menu-item>
</template> <script> export default { name: 'MenuTree', data() { return {
asideContainerW: '2rem', asideContainerChildW: '4rem' } }, props: { menu: {
type: Object, required: true } }, methods: { handleRoute(menu) { //
Through the menu URL Jump to the specified route this.$router.push(menu.url) } } } </script>
(2)vuex and axios Combined with query permission menu data :
(3) Take out the menu data found in the background above and display it :
Three , Role authorization
1. Assembly of resource permission tree structure :
(1) The permissions and resource tables are integrated into the total resources
<select id="getResourceWithPrivilege" resultMap="BaseResultMap"> select
id,name,code,parent_id from t_sys_resource UNION all SELECT privilege.id AS id,
action.name AS name, concat(resource.code,':',action.code) AS code, resource.id
as parent_id FROM t_sys_resource resource LEFT JOIN t_sys_privilege privilege
ON privilege.resource_id = resource.id LEFT JOIN t_sys_action action ON
privilege.action_id = action.id where privilege.id is not null </select>
2. Get resource permission tree
service layer :
/** * Get resource tree * * @return */ public ServiceResult<List<ResourceAO>>
getResourceTreeNode() { // Query all resources List<ResourceAO> allResource =
getResourceWithPrivilege(); return listTreeNodes(allResource); } /** *
The permissions and resource tables are integrated into the total resources * * @return */ @Override public List<ResourceAO>
getResourceWithPrivilege() { return
resourceCustomizedMapper.getResourceWithPrivilege(); }
there listTreeNodes Methods are listed above .
controller layer :
/** * Get resource tree structure . * * @return */ @RequestMapping(value = "/getResourceTreeNode",
method = {RequestMethod.GET, RequestMethod.POST}) @LogOperation(action =
" Get resource tree structure ") public Object getResourceTreeNode() { return
resourceService.getResourceTreeNode(); }
3.vue front end :
<template v-if="privilegeShow"> <el-dialog title=" Role authorization function menu "
:visible.sync="privilegeShow" width="40%"> <el-form :model="privilegeForm"
:inline="true" ref="form" class="demo-form-inline" style="margin-bottom:
5px;text-align: center;margin-top: 0px"> <el-form-item label=" Role name :" required
prop="name"> <el-input v-model="privilegeForm.name"
disabled="disabled"></el-input> </el-form-item> <el-form-item label=" Role coding :">
<el-input v-model="privilegeForm.code" disabled="disabled"></el-input>
</el-form-item> </el-form> <el-tag size="small"> Authorization function menu </el-tag>
<el-divider></el-divider> <template> <el-row> <el-col :span="2" :offset="20">
<div class="grid-content bg-purple-dark"> <el-checkbox v-model="checked"
@change="checkedAll"> Select all </el-checkbox> </div> </el-col> </el-row> </template>
<ul class="infinite-list" style="height:350px;overflow:auto"> <el-tree
:data="resourceTree" show-checkbox node-key="id" ref="privilegeTree"
default-expand-all :default-checked-keys="rolePrivilegeData"
:props="defaultProps" style="margin-left: 10px;"> </el-tree> </ul> <div
slot="footer" class="dialog-footer"> <el-button size="mini"
@click="privilegeShow = false"> cancel </el-button> <el-button size="mini"
type="primary" @click="submitPrivilege" :loading="editLoading"> determine </el-button>
</div> </el-dialog> </template> computed: { ...mapState('role', [ 'dataSource',
'loading', 'editLoading', 'resourceTree', 'rolePrivilegeData' ]), }
Four , Hide and display of authority control button
permission.js:
import Vue from 'vue' /** Authority instruction **/ Vue.directive('has', { inserted: function
(el, binding) { if (!Vue.prototype.$_has(binding.value)) {
el.parentNode.removeChild(el); } } }); // Permission checking method Vue.prototype.$_has = function
(value) { let isExist = false; let user = localStorage.getItem("user"); if
("admin" == user) { return true; } let premissionsStr =
localStorage.getItem("permissions"); if (premissionsStr == undefined ||
premissionsStr == null) { return false; } if (premissionsStr.indexOf(value) >
-1) { isExist = true; } return isExist; };
main.js Introduced in :
import has from './public/permission.js';
page :
<el-button size="mini" @click="addDialog" type="primary"
v-has="'roleManage:manage'"> newly added </el-button>
Technology