十四、根据权限定制菜单显示

Shiro根据权限过滤用户对系统模块URL的非法访问,系统主页面的功能菜单也需要根据不同权限显示不同的功能菜单,无权访问的功能模块,其对应的菜单就不需要显示系统主页面上,Shiro的权限授权和菜单授权可以统一配置,但统一设计比较复杂,故分为两个模块完成。
在这里插入图片描述
菜单与功能表 gf_function
角色表 gf_role
菜单角色中间表 gf_menu2role
菜单与角色构成多对多关系

SQL

create table gf_menu2role(id varchar(32),
	funcid varchar(32),
	roleid varchar(32));

Mapper SQL

	<!-- 
	菜单角色授权表,哪些角色具有哪些菜单权限配置,此表主要定制界面上的菜单显示
	-->
	<insert id="saveMenuRole" parameterType="com.gf.statusflow.def.Menu2RoleInfo">
		insert into gf_menu2role(id,funcid,roleid)
		values(#{id},#{funcId},#{roleId})
	</insert>
	<update id="updateMenuRole" parameterType="com.gf.statusflow.def.Menu2RoleInfo">
		update gf_menu2role set funcid=#{funcId},roleid=#{roleId}
			where id=#{id}
	</update>
	<delete id="deleteMenuRoleById" parameterType="String">
		delete from gf_menu2role where id=#{id}
	</delete>
	<delete id="deleteMenuRoleByRoleId" parameterType="String">
		delete from gf_menu2role where roleid=#{roleId}
	</delete>
	<delete id="deleteMenuRoleByFuncId" parameterType="String">
		delete from gf_menu2role where funcid=#{funcId}
	</delete>
	<select id="getMenuRoleById" resultType="com.gf.statusflow.def.Menu2RoleInfo">
		select * from gf_menu2role where id=#{id}
	</select>
	<select id="getMenuRoleByRoleId" resultType="com.gf.statusflow.def.Menu2RoleInfo">
		select * from gf_menu2role where roleid=#{roleId}
	</select>
	<select id="getMenuRoleByFuncId" resultType="com.gf.statusflow.def.Menu2RoleInfo">
		select * from gf_menu2role where funcid=#{funcId}
	</select>
	<select id="getFuncListByUserId" resultType="com.gf.model.FunctionInfo">
		select f.* from gf_function f,gf_menu2role m2r,gf_role r,gf_orguserrole our
			where f.id=m2r.funcid and m2r.roleid=r.id and r.id=our.roleid
			and our.entityid=#{userId}
	</select>
	<select id="getAclMenu" resultType="com.gf.statusflow.def.Menu2RoleInfo">
		select m2r.id,r.name roleName,f.name funcName 
		from gf_function f,gf_role r,gf_menu2role m2r
		where f.id=m2r.funcid and r.id=m2r.roleid
			and (m2r.funcid like '%${funcId}%' and m2r.roleid like '%${roleId}%')
	</select>

Mapper接口

	/**
	 * 菜单角色相关Mybatis方法
	 */
	public void saveMenuRole(Menu2RoleInfo m2r);
	public void updateMenuRole(Menu2RoleInfo m2r);
	public void deleteMenuRoleById(@Param("id") String id);
	public void deleteMenuRoleByRoleId(@Param("roleId") String roleId);
	public void deleteMenuRoleByFuncId(@Param("funcId") String funcId);
	public Menu2RoleInfo getMenuRoleById(@Param("id") String id);
	public List<Menu2RoleInfo> getMenuRoleByRoleId(@Param("roleId") String roleId);
	public List<Menu2RoleInfo> getMenuRoleByFuncId(@Param("funcId") String funcId);
	public List<FunctionInfo> getFuncListByUserId(@Param("userId") String userId);
	public List<Menu2RoleInfo> getAclMenu(@Param("funcId") String funcId,
			@Param("roleId") String roleId);

IOrgModel组织机构接口

	/**
	 * 菜单角色相关Mybatis方法
	 */
	public void saveMenuRole(Menu2RoleInfo m2r);
	public void updateMenuRole(Menu2RoleInfo m2r);
	public void deleteMenuRoleById(String id);
	public void deleteMenuRoleByRoleId(String roleId);
	public void deleteMenuRoleByFuncId(String funcId);
	public Menu2RoleInfo getMenuRoleById(String id);
	public List<Menu2RoleInfo> getMenuRoleByRoleId(String roleId);
	public List<Menu2RoleInfo> getMenuRoleByFuncId(String funcId);
	public List<FunctionInfo> getFuncListByUserId(String userId);
	public List<Menu2RoleInfo> getAclMenu(String funcId,String roleId);

组织机构实现类DefaultOrgModel

	/**
	 * 菜单角色相关Mybatis方法
	 */
	public void saveMenuRole(Menu2RoleInfo m2r)
	{
		try
		{
			mapper.saveMenuRole(m2r);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
	}
	
	public void updateMenuRole(Menu2RoleInfo m2r)
	{
		try
		{
			mapper.updateMenuRole(m2r);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
	}
	
	public void deleteMenuRoleById(String id)
	{
		try
		{
			mapper.deleteMenuRoleById(id);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
	}
	
	public void deleteMenuRoleByRoleId(String roleId)
	{
		try
		{
			mapper.deleteMenuRoleByRoleId(roleId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
	}
	
	public void deleteMenuRoleByFuncId(String funcId)
	{
		try
		{
			mapper.deleteMenuRoleByFuncId(funcId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
	}
	
	public Menu2RoleInfo getMenuRoleById(String id)
	{
		try
		{
			return mapper.getMenuRoleById(id);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
		return null;
	}
	
	public List<Menu2RoleInfo> getMenuRoleByRoleId(String roleId)
	{
		try
		{
			return mapper.getMenuRoleByRoleId(roleId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
		return null;
	}
	
	public List<Menu2RoleInfo> getMenuRoleByFuncId(String funcId)
	{
		try
		{
			return mapper.getMenuRoleByFuncId(funcId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
		return null;
	}
	
	public List<FunctionInfo> getFuncListByUserId(String userId)
	{
		try
		{
			return mapper.getFuncListByUserId(userId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
		return null;
	}
	
	public List<Menu2RoleInfo> getAclMenu(String funcId,String roleId)
	{
		try
		{
			return mapper.getAclMenu(funcId,roleId);
		}
		catch(Exception e)
		{
			log.error(e.getMessage());
		}
		return null;
	}

控制层OrgModelCtrl

	@RequestMapping("/menuacl.action")
	public String menuacl()
	{
		return "/orgmodel/menuacl";
	}
	
	@ResponseBody
	@RequestMapping("/menufuncroot.action")
	public List<TreeNode> menufuncroot()
	{
		FunctionInfo rootFi = orgmodel.getRootFunc();
		if(rootFi == null)
		{
			rootFi = orgmodel.initFunc();
		}
		List<TreeNode> trees = new ArrayList<TreeNode>();
		TreeNode rootTree = new TreeNode();
		rootTree.setId(rootFi.getId().toString());
		rootTree.setText(rootFi.getName());
		rootTree.setState("closed");
		Map attributes = new HashMap();
		attributes.put("parentId",rootFi.getParentId());
		attributes.put("path", "/");
		attributes.put("fullName", "/"+rootFi.getName());
		attributes.put("isload", "false");
		rootTree.setAttributes(attributes);
		
		trees.add(rootTree);
		return trees;
	}
	
	@ResponseBody
	@RequestMapping("/menugettreebyid")
	public List<TreeNode> menugettreebyid(String id)
	{
		List<FunctionInfo> funs = orgmodel.getChildFunc(id);
		List<TreeNode> rtn = new ArrayList<TreeNode>();
		if(funs != null && funs.size()>0)
		{
			for(FunctionInfo fi:funs)
			{
				TreeNode ti = new TreeNode();
				ti.setId(fi.getId().toString());
				ti.setText(fi.getName());
				ti.setIconCls(fi.getIcon()!=null?fi.getIcon():"pic_1");
				ti.setUrl(fi.getUrl());
				List<FunctionInfo> chd = orgmodel.getChildFunc(fi.getId());
				if(chd != null && chd.size()>0)
					ti.setState("closed");
				else
				{
					ti.setState("open");
				}
				ti.addAttribute("path",fi.getPath());
				ti.addAttribute("fullName",fi.getFullName());
				ti.addAttribute("isload","false");
				if(fi.getPriority() != null)
					ti.addAttribute("priority",fi.getPriority().toString());
				if(fi.getParentId() != null)
					ti.addAttribute("parentId",fi.getParentId().toString());
				rtn.add(ti);
			}
		}
		return rtn;
	}
	
	@RequestMapping("/menuroleload.action")
	@ResponseBody
	public Map menuroleload(String funcId,String roleId,Integer page,Integer rows)
	{
		PageHelper.startPage(page, rows);
		List<Menu2RoleInfo> lists = orgmodel.getAclMenu(funcId,roleId);
		PageInfo pi = new PageInfo(lists);
		Long total = pi.getTotal();
		List<Menu2RoleInfo> perms = pi.getList();
		Map m = new HashMap();
		m.put("total", total);
		m.put("rows", perms);
		return m;
	}
	
	@RequestMapping("/menurolesave.action")
	@ResponseBody
	public Boolean menurolesave(String[] funcId,String[] roleId)
	{
		if(funcId != null && roleId != null)
		{
			for(String funcId2:funcId)
			{
				orgmodel.deleteMenuRoleByFuncId(funcId2);
				for(String roleId2:roleId)
				{
					if(!"".equals(Util.fmtStr(funcId2)) && !"".equals(Util.fmtStr(roleId2)))
					{
						Menu2RoleInfo m2r = new Menu2RoleInfo();
						m2r.setId(UUID.create("m2r"));
						m2r.setFuncId(funcId2);
						m2r.setRoleId(roleId2);
						orgmodel.saveMenuRole(m2r);
					}
				}
			}
		}
		return true;
	}
	
	@RequestMapping("/menuroledelete.action")
	@ResponseBody
	public Boolean menuroledelete(String[] id)
	{
		if(id != null)
		{
			for(String id2:id)
			{
				orgmodel.deleteMenuRoleById(id2);
			}
		}
		return true;
	}

页面JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String webCtx = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<script type="text/javascript" src="<%=webCtx %>/static/easyui/jquery.min.js"></script>
<script type="text/javascript" src="<%=webCtx %>/static/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="<%=webCtx %>/static/easyui/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" href="<%=webCtx %>/static/easyui/themes/default/easyui.css"/>
<link rel="stylesheet" href="<%=webCtx %>/static/easyui/themes/icon.css"/>
<link rel="stylesheet" href="<%=webCtx %>/static/easyui/myicon.css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script>
	function reloadtree()
	{
		$.get('/menufuncroot.action',function(data)
			{
				$('#tree').tree({
					data: data
				});
			}
		)
	}
	function reloadroletree()
	{
		$.get('/roleroot.action',function(data)
			{
				$('#roletree').tree({
					data: data
				});
			}
		)
	}
	function addmenurole()
	{
		var nodes = $('#tree').tree('getChecked');
		if(nodes.length == 0)
		{
			$.messager.alert('提示','请选择模块或者权限节点,选择模块节点时将授权此模块下所有权限');
			return;
		}
		var funcId = '';
		for(var i=0;i<nodes.length;i++)
		{
			funcId = funcId + nodes[i].id + ',';
		}
		var nodes2 = $('#roletree').tree('getChecked');
		if(nodes2.length == 0)
		{
			$.messager.alert('提示','请选择角色节点');
			return;
		}
		var roleId = '';
		for(var i=0;i<nodes2.length;i++)
		{
			roleId = roleId + nodes2[i].id + ',';
		}
		console.log('roleid='+roleId+',funcId='+funcId);
		$.ajax({
			url:'/menurolesave.action?funcId='+funcId+"&roleId="+roleId,
			success:function(data)
			{
				$('#permdg').datagrid('reload');
			}
		})
	}
	function deletemenurole()
	{
		var objs = $('#permdg').datagrid('getChecked');
		var id = '';
		for(i=0;i<objs.length;i++)
			id = id + objs[i].id+ ',';
		console.log('menuroledelete id='+id);
		$.ajax({
			url:'/menuroledelete.action?id='+id,
			success:function(data)
			{
				$('#permdg').datagrid('reload');
			}
		})
	}
	$(document).ready(function()
	{
		reloadtree();
		$('#tree').tree({
			onBeforeExpand:function(node,param)
			{
				if(node.attributes.isload=='false')
				{
					$.ajaxSettings.async = false;
					var url = '/menugettreebyid.action?id='+node.id;
					$.get(url,function(data)
						{
							$('#tree').tree('append', {
								parent: node.target,
								data: data
							});
						}
					)
					$.ajaxSettings.async = true;
					node.attributes.isload = 'true';
				}
			},
			onExpand: function(node){

			},
			onClick: function(node){
				$('#permdg').datagrid({
					url:'/menuroleload.action?funcId='+node.id
				});
			}
		});
		$('#roletree').tree({
			onClick: function(node){
				$('#permdg').datagrid({
					url:'/menuroleload.action?roleId='+node.id
				});
			}
		});
		reloadroletree();
	});
</script>

</head>
<body class="easyui-layout">
	<div data-options="region:'west',title:'菜单导航'" style="width:200px;padding:0px;">
		<ul id="tree" class="easyui-tree" data-options="checkbox:true,cascadeCheck:false,lines:true">   
		</ul> 
	</div>
	<div data-options="region:'center'">
		<div id="p" class="easyui-panel" style="width:100%;height:100%" data-options="iconCls:'icon-save',closable:true">
			<div class="easyui-layout" data-options="fit:true"> 
				<div data-options="region:'west',title:'角色导航'" style="width:200px;padding:0px;">
					<ul id="roletree" class="easyui-tree" data-options="checkbox:true,cascadeCheck:false,lines:true">   
					</ul> 
				</div>
				<div data-options="region:'center',title:'菜单授权'">
					<table id="permdg" class="easyui-datagrid" style="width:100%;height:100%"   
					        data-options="url:'/menuroleload.action',fitColumns:true,pagination:true,
					        pageSize:10,pageList:[10,50,100,200],toolbar:'#tb'">   
					    <thead>   
					        <tr>
					        	<th data-options="field:'id',width:100,checkbox:true">ID</th>   
					            <th data-options="field:'funcName',width:100">模块名称</th>   
					            <th data-options="field:'roleName',width:100">授权角色</th>
					        </tr>   
					    </thead>   
					</table>
					<div id="tb">
						<a id="btn" onclick="addmenurole()" class="easyui-linkbutton" data-options="iconCls:'icon-add'">添加授权</a>
						<a id="btn" onclick="deletemenurole()" class="easyui-linkbutton" data-options="iconCls:'icon-remove'">删除授权</a>
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

界面设计

在这里插入图片描述
菜单"组织机构"与“用户管理”都分配给角色Test,菜单"组织机构"下包含“部门管理”,“用户管理”,“角色管理”,“角色分配”,角色Test具有菜单"组织机构"的权限,也就具有"组织机构"下面的四个子菜单的权限。
角色Test分配给用户Test3
在这里插入图片描述
用户Test3登录后,只能看到菜单"组织机构"其下的四个子菜单

在这里插入图片描述

代码下载

git clone -b day11 https://github.com/qixiangchen/gufang_fisys.git

猜你喜欢

转载自blog.csdn.net/qixiang_chen/article/details/85913510