用ssh,练习了一下Ztree的 菜单授权,简单的总结如下:
基本功能描述:
admin管理员登录之后,对当前的用户可以 菜单授权。界面基本上就是下面这样子,便于理解,所以上传了.
基本思路:
菜单节点类: Menu 类 ,Ztree 数据格式 转换类 :TreeNode 类,pojo:User类,json数据转换类: JsonUtil类。因为小弟是用的注解。如有不方便之处,看到的人勿喷~
1 @Entity 2 @Table(name = "t_menu") 3 public class Menu { 4 @Id 5 @GeneratedValue 6 private Integer id;//节点Id 7 private String name;//节点名称 8 private String url;//节点 跳转url 9 private String target;//设置点击节点后在何处打开 url 10 private String click;//最简单的 click 事件操作。相当于 onclick="..." 的内容 11 /* 12 * 节点自关联 13 */ 14 @ManyToOne 15 private Menu parent; //父类节点 16 17 @OneToMany(mappedBy = "parent") 18 private Set<Menu> children = new HashSet<Menu>();//孩子节点 19 20 @ManyToMany(mappedBy="menus") 21 private Set<User> users = new HashSet<User>();
1 /* 2 * 数据转换 适配器 3 * ztree 解析 的 数据 格式 如下 .所以 创建 TreeNode 类。把 menu 类 转换成 ztree 能够 解析的 数据结构。 4 * var nodes = [ 5 {id:1, pId:0, name: "父节点1"}, 6 {id:11, pId:1, name: "子节点1"}, 7 {id:12, pId:1, name: "子节点2"} 8 ]; 9 */ 10 public class TreeNode { 11 private Integer id; 12 private String name; 13 private String url;//跳转的Url 14 private String target;//Url跳转的 打开搁置 15 private String click;//节点的 click 事件 16 private boolean checked;//初始化的数据设置 默认为勾选状态 17 private Integer pId; 18
1 @Entity 2 @Table(name = "t_user") 3 public class User { 4 @Id 5 @GeneratedValue 6 private Integer id; 7 private String uname; 8 private String pwd; 9 private String email; 10 private String phone; 11 12 @ManyToMany 13 private Set<Menu> menus = new HashSet<Menu>();
1 public class JsonUtil { 2 private static Gson gson; 3 4 static{ 5 GsonBuilder gsonBuilder = new GsonBuilder(); 6 gsonBuilder.setPrettyPrinting(); 7 gson = gsonBuilder.create(); 8 } 9 /* 10 * 生成 gson 数据结构 的 数据。 11 */ 12 public static String toGson(Object obj){ 13 return gson.toJson(obj); 14 } 15 /* 16 * 将数据库里面的数据写到 页面。 17 */ 18 public static void write2response(Object object){ 19 HttpServletResponse response = ServletActionContext.getResponse(); 20 response.setCharacterEncoding("utf-8"); 21 response.setContentType("text/plain"); 22 try { 23 response.getWriter().write(gson.toJson(object)); 24 response.getWriter().close(); 25 } catch (IOException e) { 26 // TODO Auto-generated catch block 27 e.printStackTrace(); 28 } 29 } 30 }
这是menu类中的数据。生成表单t_menu后,手动添加数据,利用JsonUtil 把数据库里面的数据响应到页面。
1 </style> 2 <link rel="stylesheet" type="text/css" 3 href="css/zTreeStyle/zTreeStyle.css" /> 4 <script type="text/javascript" src="js/jquery-1.4.4.min.js"> 5 </script> 6 <script type="text/javascript" src="js/jquery.ztree.all-3.5.js"> 7 </script> 8 <script type="text/javascript"> 9 10 $(function() { 11 $.ajax({ 12 url:'menuAction!findMyMenu',//指定用户的登录菜单节点 。 13 dataType:'json', 14 success:function(data){ 15 var setting={ 16 data:{ 17 simpleData:{ 18 enable:true 19 } 20 } 21 }; 22 $.fn.zTree.init($("#treeDemo"),setting,data); 23 var tre =$.fn.zTree.getZTreeObj("treeDemo");//ztree对象。 24 25 tre.expandAll(true);//zrree对象节点 全部展开。 26 } 27 }); 28 }); 29 30 </script> 31 </head> 32 33 <body> 34 <form name="ff"> 35 <!-- 指定用户登录菜单时,需要扫描的用户Id。 userId --> 36 <input type="hidden" name="userId" value="${param.userId }" /> 37 38 </form> 39 <!-- 需要生成 Ztree 的ul对象 --> 40 <ul id="treeDemo" class="ztree"></ul> 41 </body>
1 <c:forEach var="obj" items="${user.userlist}"> 2 <tr> 3 <td> 4 ${obj.id} 5 </td> 6 <td>${obj.uname}</td> 7 <td>${obj.email}</td> 8 <td>${obj.phone}</td> 9 <td><a href="userAction!updateBefore?id=${obj.id}"> 编辑</a></td> 10 <td><a href="userAction!delete?id=${obj.id}"> 删除</a></td> 11 <td><a href="user/grant.jsp?userId=${obj.id}"> 授权</a></td> 12 </tr> 13 </c:forEach>
1 <script type="text/javascript"> 2 3 $(function() { 4 $.ajax( { 5 6 url:'menuAction!findAll?userId=${param.userId}',//每次授权时拿出勾选节点的上次记录,所以需要传参userId 7 dataType : 'json', 8 success : function(data) { 9 var setting = { 10 data : { 11 simpleData : { 12 enable : true 13 } 14 }, 15 check : { 16 enable : true //授权菜单节点 前的复选框。 true 为选中。false 为不选 17 } 18 }; 19 20 $.fn.zTree.init($("#treeDemo"), setting, data); 21 $.fn.zTree.getZTreeObj("treeDemo").expandAll(true); 22 } 23 }); 24 25 $("#save").click(function() { 26 var tree = $.fn.zTree.getZTreeObj("treeDemo"); 27 28 var ss = tree.getCheckedNodes(true);//拿到 授权用户勾选的节点集 29 30 var ff = document.ff; 31 ff.action = "menuAction!grant"; 32 ff.method = "post"; 33 34 for ( var i = 0; i < ss.length; i++) { 35 var node = ss[i]; 36 console.info(node.name + "--" + node.id); 37 //拼接 往action提交的 node.id值。 38 $(ff).append( 39 "<input type=\"hidden\" name=\"menuIds\" value=\"" 40 + node.id + "\" />"); 41 } 42 43 ff.submit(); 44 }); 45 }); 46 </script> 47 </head> 48 49 <body> 50 <form name="ff"> 51 <input type="hidden" name="userId" value="${param.userId }" /> 52 53 </form> 54 <ul id="treeDemo" class="ztree"></ul> 55 <input type="button" value="保存" id="save" /> 56 </body>
1 /** 2 * @author Administrator 3 * 菜单接口 4 */ 5 public interface ImplMenuService { 6 //将数据库中的节点 对象 转换成为 ztree能够 识别 的 gson数据结构,所以 类型 为TreeNode。 7 //userId 是为了取出上次授权所需的节点 值 记录。 8 public List<TreeNode>findAll(Integer userId); 9 //将勾选中的菜单 跟用户Id建立连接,存进数据库 10 public void grant(Integer userId,Integer []menusId); 11 //展示 用户登录后 的 功能 菜单 节点 12 public List<TreeNode>findByUser(Integer userId); 13 }
1 @Component 2 public class MenuServiceImpl implements ImplMenuService { 3 @Resource 4 private HibernateTemplate hibernateTemplate; 5 6 /* 遍历功能菜单节点 7 * @see com.shuanlei.service.ImplMenuService#findAll(java.lang.Integer) 8 */ 9 public List<TreeNode> findAll(Integer userId) { 10 //遍历menu菜单 11 List<Menu>list =hibernateTemplate.find("from Menu"); 12 //用户所选 节点 的 Id记录 13 List<Integer> menuList = hibernateTemplate.find("select u.id from Menu u where u.users.id=?", new Object[]{userId}); 14 15 //创建一个转换 menu菜单 的 treeNode转换集合类 16 List<TreeNode> treeNodes = new ArrayList<TreeNode>(); 17 18 for (Iterator iterator = list.iterator(); iterator.hasNext();) { 19 //遍历 菜单 类节点 20 Menu menu = (Menu) iterator.next(); 21 //将遍历的菜单节点 转换成为 ztree能够 识别的 数据结构 类。 22 TreeNode treeNode = new TreeNode(); 23 //将 menu类中的属性 set 进 数据转换器 ztreeNode 24 treeNode.setName(menu.getName()); 25 treeNode.setId(menu.getId()); 26 treeNode.setUrl(menu.getUrl()); 27 treeNode.setTarget(menu.getTarget()); 28 treeNode.setClick(menu.getClick()); 29 //如果父节点不为空,menu id set into treeNode 30 if (menu.getParent() != null) 31 treeNode.setpId(menu.getParent().getId()); 32 else 33 treeNode.setpId(-1); 34 //菜单节点中 包括 用户的授权 记录 Id时,checkbox =true.勾选。不包括时.checkbox=false.不勾选。 35 if (menuList.contains(menu.getId())) { 36 treeNode.setChecked(true); 37 } else { 38 treeNode.setChecked(false); 39 } 40 treeNodes.add(treeNode); 41 } 42 43 return treeNodes; 44 } 45 46 /* (non-Javadoc) 47 * @see 用户勾选 权限菜单 节点,存进数据库。 48 */ 49 @Transactional 50 public void grant(Integer userId, Integer[] menusId) { 51 //找到要授权的用户 52 User user = (User) hibernateTemplate.get(User.class, userId); 53 Set<Menu> menus = new HashSet<Menu>(); 54 for (int i = 0; i < menusId.length; i++) { 55 Integer menuId = menusId[i]; 56 Menu menu = (Menu) hibernateTemplate.get(Menu.class, menuId); 57 //菜单节点 更新 58 menus.add(menu); 59 } 60 user.setMenus(menus); 61 //更新 菜单勾选 后的 User。 62 hibernateTemplate.update(user); 63 64 } 65 66 /* @desc 用户登录时,展示出来的 菜单节点 67 * @see com.shuanlei.service.ImplMenuService#findByUser(java.lang.Integer) 68 */ 69 public List<TreeNode> findByUser(Integer userId) { 70 List<Menu> menulist = hibernateTemplate.find("from Menu u where u.users.id=?", new Object[] { userId }); 71 72 List<TreeNode> nodes = new ArrayList<TreeNode>();//转换数据格式的treeNode list 73 74 for (Iterator iterator = menulist.iterator(); iterator.hasNext();) { 75 Menu menu = (Menu) iterator.next(); 76 77 TreeNode treeNode = new TreeNode(); 78 treeNode.setName(menu.getName()); 79 treeNode.setTarget(menu.getTarget()); 80 treeNode.setUrl(menu.getUrl()); 81 treeNode.setClick(menu.getClick()); 82 treeNode.setId(menu.getId()); 83 84 if (menu.getParent() != null) { 85 treeNode.setpId(menu.getParent().getId()); 86 } else { 87 treeNode.setpId(-1); 88 } 89 nodes.add(treeNode); 90 } 91 return nodes; 92 } 93 94 }
1 @Component 2 @Scope("prototype") 3 public class MenuAction { 4 @Resource 5 private ImplMenuService implMenuService; 6 7 private Integer userId;//授权时的userId 8 private Integer[] menuIds;//授权时勾选 的菜单节点集 9 10 //以 json数据格式 向 页面 响应。 11 public String findAll() { 12 13 JsonUtil.write2response(implMenuService.findAll(userId)); 14 return null; 15 } 16 17 //用户勾选菜单 项,存进数据库 18 public String grant() { 19 System.out.println("MenuAction.grant()" + userId); 20 implMenuService.grant(userId, menuIds); 21 22 return null; 23 } 24 //打印 用户登录 所拥有 的权限 菜单 25 public String findMyMenu(){ 26 User user =(User) ActionContext.getContext().getSession().get("user"); 27 List <TreeNode>list =implMenuService.findByUser(user.getId()); 28 JsonUtil.write2response(list); 29 return null; 30 } 31 32 public Integer getUserId() { 33 return userId; 34 } 35 36 public void setUserId(Integer userId) { 37 this.userId = userId; 38 } 39 40 public Integer[] getMenuIds() { 41 return menuIds; 42 } 43 44 public void setMenuIds(Integer[] menuIds) { 45 this.menuIds = menuIds; 46 } 47 48 }
以上呢,就是菜单授权的基本思路和代码,有什么问题,尽量喷,可以相互学习~