前言
这个也是别人问到我了,就专研了一会,写了这篇博客。
需求
需求就是修改角色对应的权限,点击修改时,系统所有的菜单项要全部出现,角色对应的权限前面自动打勾,方便查看。
解决
肯定需要将角色表和菜单表中主键拿出来重新建一个表,用来表示角色与权限的对应关系。然后点击修改时,需要传过去一个角色的id,新的页面首先查询出该角色的所拥有的所有菜单id(menus表示),然后在加载树形菜单时,判断加载的节点id是否存在于menus对象数组,若存在,则选中该节点。
数据库
role表
menu表
role_menu 表
实现
获取角色的程序代码,注意此处后台获取的过程就不在累赘,如果你不会本文bootstrap获取数据,请告知,我会写一写相关教程。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="${path}/css/bootstrap.min.css">
<link rel="stylesheet" href="${path}/css/bootstrap-table.css">
<link rel="stylesheet" href="${path }/css/font-awesome-4.4.0/css/font-awesome.min.css">
<script type="text/javascript" src="${path}/jq/jquery-3.2.0.min.js"></script>
<script src="${path}/js/bootstrap.min.js"></script>
<script src="${path}/js/bootstrap-table.js"></script>
<script src="${path}/js/bootstrap-table-zh-CN.js"></script> //bootstrap table 需要的各种组件 注意引入顺序
<title>角色管理</title>
</head>
<script >
//设置查询参数
function postQueryParams(params) {
var queryParams= new Object();
queryParams.limit=params.limit;
queryParams.offset=params.offset;
return queryParams;
}
function queryList(){
$('#SysRoleList').bootstrapTable('refresh');
}
function operatorFormatter(value, row, index) {
var operator="";
operator+='<button class="btn btn-warning btn-round btn-xs" οnclick="editById(\''+row.id+'\');"><i class="glyphicon"></i> 修改</button>';
return operator;
}
function editById(id){ //跳转到权限管理
window.location='${path}/jsp/z-tree2.jsp?roleId='+id; //附带角色id
}
</script>
<style type="text/css">
.rightinfo{
margin-top:50px;
}
</style>
<body>
<div class="rightinfo">
<table id="SysRoleList"
data-toggle="table"
data-url="${path}/RoleServlet"
data-pagination="true"
data-side-pagination="server"
data-cache="false"
data-query-params="postQueryParams"
data-page-list="[ 5, 10, 15, 20, 30, 50]"
data-method="post"
data-show-refresh="true"
data-show-toggle="true"
data-show-columns="true"
data-toolbar="#toolbar"
data-click-to-select="true"
data-single-select="false"
data-striped="true"
data-content-type="application/x-www-form-urlencoded">
<thead>
<tr>
<th data-field="" data-checkbox="true"></th>
<th data-field="id">角色ID</th>
<th data-field="name">角色名称</th>
<th data-field="operator" data-formatter="operatorFormatter">操作</th>
</tr>
</thead>
</table>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
String roleId= request.getParameter("roleId");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${path}/jq/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="${path }/Z-Tree/jquery.ztree.core.js"></script>
<script type="text/javascript" src="${path }/Z-Tree/jquery.ztree.excheck.js"></script>
<script type="text/javascript" src="${path }/Z-Tree/jquery.ztree.exedit.js"></script>
<link rel="stylesheet" href="${path}/css/zTreeStyle/zTreeStyle.css" type="text/css"/>
<title>Insert title here</title>
<style type="text/css">
.title{
margin: 30px 30px;
font-size:15px;
}
#tree{
margin: 30px 30px;
}
.ztree li span.button.add {
margin-left:2px;
margin-right: -1px;
background-position:-144px 0;
vertical-align:top;
*vertical-align:middle
}
</style>
</head>
<script>
var zTree;
var selectNode;
var load = false;
var menus;
$(function(){
$.post('${path}/RoleMenuServlet?roleId='+"<%= roleId %>",function(data){
if(data.success){
menus= data.menus;
zTree = $.fn.zTree.init($("#treeDemo"), setting);
}
})
})
var setting = {
async : {
enable : true,
dataType : "text",
type : "post",
url : "${path}/MenuNodeServlet?timestamp="+ new Date().getTime(), //请求节点生成的servlet
autoParam : [ "id" ] //每次异步加载传给服务器的参数
},
check : {
enable: true,
chkStyle: "checkbox",
chkboxType: { "Y": "p", "N": "s" }
},
view : {
dblClickExpand : true,
selectedMulti:false,
},
data : {
key : {
name : "nodeName" // 取后台传过来的json数据中 nodeName 字段值作为节点名称
},
simpleData : {
enable : true,
idKey : "id", //节点的id,注意此处要对应你后台传过来的节点的属性名id
pIdKey : "pId", //节点的pId,注意此处要对应你后台传过来的节点的属性名pId
rootPId : 0 //根节点的pId = 0
}
},
callback : {
onAsyncSuccess: zTreeOnAsyncSuccess //异步加载完毕的回调函数
}
};
function zTreeOnAsyncSuccess(event, treeId, treeNode, msg){ // 这个函数仅仅是为了 初始化时展开 1级菜单
if(!load){
var nodes = zTree.getNodesByParam("pId", 0, null);
$.each( nodes, function(i, n){
zTree.expandNode(n, true, false, true);
});
load = true;
}
else{
var nodes = zTree.getNodesByParam("pId", treeNode.id, null);
$.each( nodes, function(i, n){
zTree.expandNode(n, true, false, true);
});
}
if(isExist(treeNode)){
zTree.checkNode(treeNode,true,true);
}
var nodes=treeNode.children; //判断异步加载的子节点,
// 因为zTreeOnAsyncSuccess只有是父节点才可以调用此函数
//所以为了防止忘了判断叶子节点,所以此处牺牲性能来获取正确的结果
$.each( nodes, function(i, n){
if(isExist(n)){
zTree.checkNode(n,true,true);
}
});
}
function isExist(treeNode){ //判断节点是否存在menus中
for(var i=0;i<menus.length;i++){
if(treeNode.id==menus[i].id){
return true;
}
}
return false;
}
</script>
<style type="text/css">
.title{
margin: 30px 30px;
font-size:15px;
}
#tree{
margin: 30px 30px;
}
</style>
<body>
<div id="tree">
<ul id="treeDemo" class="ztree"></ul>
</div>
</body>
</html>
注意:对于RoleMenuServlet 就是传过来角色对应的权限集合。
此处只给出部分代码,具体请自己尝试实现。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer roleId= Integer.parseInt(request.getParameter("roleId"));
List<Menu> menus = rmD.findMenuIdByRoleId(roleId);
JSONObject jO = new JSONObject();
jO.put("success", true);
jO.put("menus", menus);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(jO.toString());
}
findMenuIdByRoleId
public List findMenuIdByRoleId(Integer roleId) {
java.sql.Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Menu> menus = new ArrayList<Menu>();
try{
conn=DbUtil.getConnection();
String sql="select * from menu where id in (select m_id from role_menu where r_id=? )" ;
ps=(PreparedStatement) conn.prepareStatement(sql);
ps.setInt(1,roleId);
rs=ps.executeQuery();
while(rs.next()){
Menu ui = new Menu();
ui.setId(rs.getInt("id"));
ui.setName(rs.getString("name"));
menus.add(ui);
}
}catch (Exception e) {
e.printStackTrace();// TODO: handle exception
}finally{
DbUtil.closeAll(conn, ps, rs);
}
return menus;
}
结果实例图
若点击上上图的区长