1. 程式人生 > >管理系統權限設計借鑒

管理系統權限設計借鑒

p2p new query pen 變量 checkbox lan tro prot

轉自:http://blog.csdn.net/zwx19921215/article/details/44467099/

最近在做一個網站類型項目,主要負責後臺,ui框架選型為jquery easy ui,項目架構為spring mvc + spring jdbc,簡單易用好上手!搭建好框架後開始了第一個任務,設計並實現一套簡單的權限管理功能。

一套最基本的權限管理包括用戶、角色、資源。

數據庫設計

我的設計如下:

用戶:user

角色:role

用戶-角色:user_role

資源:resource(包括上級菜單、子菜單、按鈕等資源)

角色-資源:role_resource

標準的權限管理系統設計為以上5張表。

註:用戶、用戶-角色我就不做說明了,這兩個是很簡單的兩塊,用戶的crud,以及為用戶分配角色(多對多的關系)稍微琢磨一下就清楚了,下面都是針對為角色分配權限的實現

後臺實現

展示層采用ztree樹

role.jsp

[html] view plain copy
  1. <%@ page contentType="text/html;charset=UTF-8"%>
  2. <%@ include file="/views/back/include/taglib.jsp"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head>
  6. <meta name="decorator" content="back" />
  7. <script type="text/javaScript">
  8. //打開菜單窗口
  9. function openMenuDialog(){
  10. var selected = $("#list").datagrid(‘getSelected‘);
  11. if (selected != null) {
  12. $("#id").val(selected.id);
  13. queryMenus(selected.id);
  14. $("#menuWindow").window("open");
  15. } else {
  16. $.messager.alert(‘提示‘, "未選擇數據!");
  17. }
  18. }
  19. //角色-菜單信息入庫
  20. function ajaxSubmit(rid,idstr){
  21. $.post("${ctx}/roleMenu/save.jhtml",{"roleId":rid,"ids":idstr},function(obj){
  22. $.messager.alert(‘提示‘,obj.msg);
  23. $("#menuWindow").window(‘close‘);
  24. },‘json‘);
  25. }
  26. </script>
  27. <!-- ztree -->
  28. <script type="text/javascript">
  29. var tree = "";
  30. var setting = {
  31. check : {
  32. chkboxType:{"Y":"ps","N":"s"},//勾選checkbox對於父子節點的關聯關系,取消勾選時不關聯父
  33. chkStyle:"checkbox",
  34. enable : true //是否復選框
  35. },
  36. //數據
  37. data : {
  38. simpleData : {
  39. enable : true
  40. }
  41. }
  42. };
  43. //查詢菜單信息
  44. function queryMenus(roleId){
  45. $.post(‘${ctx}/role/treedata.jhtml‘, {‘roleId‘:roleId}, function(zNodes) {
  46. for (var i = 0; i < zNodes.length; i++) {
  47. if (zNodes[i].isParent) {
  48. } else {
  49. //zNodes[i].icon = "${ctxStatic}/images/532.ico";//設置圖標
  50. }
  51. }
  52. tree = $.fn.zTree.init($("#tree"), setting, zNodes);
  53. tree.expandAll(true);//全部展開
  54. //var nodes = treeObj.getNodes();
  55. }, ‘json‘);
  56. }
  57. //獲取選中節點
  58. function onCheck(){
  59. var rid = $("#id").val();
  60. var treeObj=$.fn.zTree.getZTreeObj("tree");
  61. var nodes=treeObj.getCheckedNodes(true);
  62. var ids = new Array();
  63. for(var i=0;i<nodes.length;i++){
  64. //獲取選中節點的值
  65. ids.push(nodes[i].id);
  66. // v+=nodes[i].id + ",";
  67. //alert(nodes[i].id);
  68. }
  69. ajaxSubmit(rid,ids);
  70. }
  71. </script>
  72. </head>
  73. <body>
  74. <!-- 數據表格 -->
  75. <table id="list" url=‘${ctx}/role/list/page.jhtml‘ method=‘post‘
  76. class="easyui-datagrid" style="width:100%;" fitcolumns="true"
  77. toolbar=‘#tb‘ pagination=‘true‘ rownumbers=‘true‘ singleSelect=‘true‘>
  78. <thead>
  79. <tr>
  80. <th field=‘name‘ sortable=‘true‘ width=‘100‘>角色名稱</th>
  81. <th field=‘description‘ width=‘200‘ align=‘right‘>描述</th>
  82. <th field=‘createTimeFormat‘ width=‘150‘ align=‘center‘>創建時間</th>
  83. </tr>
  84. </thead>
  85. </table>
  86. <!-- 編輯欄 -->
  87. <div id="tb" style="padding:5px 5px;">
  88. <div>
  89. <p2p:permission module="role" code="add"><a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="openCreateDialog();">新增</a></p2p:permission>
  90. <p2p:permission module="role" code="edit"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openUpdateDialog();">編輯</a></p2p:permission>
  91. <p2p:permission module="role" code="delete"><a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="del();">刪除</a></p2p:permission>
  92. <p2p:permission module="role" code="authority"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openMenuDialog();">設置權限</a></p2p:permission>
  93. </div>
  94. <!-- 搜索項 -->
  95. <div style="margin-top:5px;padding-left:5px">
  96. 用戶名: <input id="query_name" class="easyui-textbox" type="text" style="width:110px" />
  97. 創建日期: <input id="query_startDate" class="easyui-datebox" style="width:110px">
  98. 至: <input id="query_endDate" class="easyui-datebox" style="width:110px">
  99. <a onclick="reload();" href="#" class="easyui-linkbutton" iconCls="icon-search">查詢</a>
  100. </div>
  101. </div>
  102. <!-- 權限窗口 -->
  103. <div id="menuWindow" class="easyui-window" title="配置權限" data-options="modal:true,iconCls:‘icon-save‘,footer:‘#menuWindowfooter‘" style="width:350px;height:420px;padding:10px">
  104. <div id="tree" class="ztree" style="padding: 10px 20px;"></div>
  105. </div>
  106. <div id="menuWindowfooter" style="padding:5px;text-align:right;">
  107. <a href="#" onclick="onCheck();" class="easyui-linkbutton" data-options="iconCls:‘icon-save‘">提交</a>
  108. </div>
  109. </body>
  110. </html>

action層
RoleAction.java

[java] view plain copy
  1. @RequestMapping(value = "/treedata.jhtml")
  2. @ResponseBody
  3. public String treedata(HttpServletRequest request, Model model) {
  4. DynamicParams params = new DynamicParams(request);
  5. List<Map<String, Object>> mapList = Lists.newArrayList();
  6. params.put("allMenu", "allMenu");
  7. List<Menu> list = authManager.findMenuList(params);
  8. List<RoleMenu> roleMenus = authManager.findRoleMenuList(params);
  9. for (int i = 0; i < list.size(); i++) {
  10. Menu e = list.get(i);
  11. Map<String, Object> map = Maps.newHashMap();
  12. map.put("id", e.getId());
  13. map.put("pId", e.getParentId() != null ? e.getParentId() : 0);
  14. map.put("name", e.getName());
  15. for (RoleMenu roleMenu : roleMenus) {
  16. if (roleMenu.getMenuId() == e.getId()) {
  17. map.put("checked", true);
  18. }
  19. }
  20. mapList.add(map);
  21. }
  22. return toJson(mapList);
  23. }



service層

AuthManager.java

[java] view plain copy
  1. // 菜單管理
  2. public List<Menu> findMenuList(DynamicParams params) {
  3. List<Menu> menus = new ArrayList<Menu>();
  4. if ("allMenu".equals(params.getString("allMenu"))) {
  5. menus = menuDao.findList(params);
  6. } else {
  7. // 通過用戶查詢角色
  8. List<UserRole> userRoles = userRoleDao.findList(params);
  9. // 通過角色查詢菜單
  10. List<RoleMenu> roleMenus = new ArrayList<RoleMenu>();
  11. if (userRoles != null && userRoles.size() > 0) {
  12. for (UserRole userRole : userRoles) {
  13. params = new DynamicParams();
  14. if (userRole != null) {
  15. if (userRole.getRoleId().equals(params.getString("rid"))) {
  16. break;
  17. }
  18. params.put("roleId", userRole.getRoleId().toString());
  19. List<RoleMenu> rms = roleMenuDao.findList(params);
  20. for (RoleMenu roleMenu : rms) {
  21. roleMenus.add(roleMenu);
  22. }
  23. }
  24. }
  25. }
  26. // 查詢菜單信息
  27. for (RoleMenu roleMenu : roleMenus) {
  28. if (roleMenu != null) {
  29. Menu menu = menuDao.find(roleMenu.getMenuId());
  30. if (menu != null) {
  31. menus.add(menu);
  32. }
  33. }
  34. }
  35. menus = removeDuplicate(menus);
  36. Collections.sort(menus);
  37. }
  38. return menus;
  39. }
[java] view plain copy
  1. /**
  2. * 去除菜單中重復項
  3. *
  4. * @param list
  5. * @return
  6. */
  7. private List<Menu> removeDuplicate(List<Menu> list) {
  8. List<Menu> result = new ArrayList<Menu>();
  9. Set<Long> menuIds = new HashSet<Long>();
  10. for (int i = 0; i < list.size(); i++) {
  11. Menu m = list.get(i);
  12. if (m != null && menuIds.add(m.getId())) {
  13. result.add(m);
  14. }
  15. }
  16. return result;
  17. }

[java] view plain copy
  1. public List<RoleMenu> findRoleMenuList(DynamicParams params) {
  2. List<RoleMenu> roleMenus = roleMenuDao.findList(params);
  3. return roleMenus;
  4. }

Dao層

menuDao

[java] view plain copy
  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from sys_menu s where 1=1 ");
  4. String parentId = params.getString("parentId");
  5. if (StringUtils.isNotBlank(parentId)) {
  6. sql.append(" and parent_id = ? ");
  7. args.add(parentId);
  8. }
  9. String sort = params.getString("sort");
  10. String order = params.getString("order");
  11. if (StringUtils.isNotBlank(sort)) {
  12. sql.append(" order by ").append(hump2underline(sort));
  13. if (StringUtils.isNotBlank(order)) {
  14. sql.append(" " + order);
  15. } else {
  16. sql.append(" desc ");
  17. }
  18. } else {
  19. sql.append("order by sort asc,id desc ");
  20. }
  21. }


userRoleDao

[java] view plain copy
  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from sys_user_role s where 1=1 ");
  4. Long adminId = params.getLong("adminId");
  5. if (adminId != null) {
  6. sql.append(" and s.user_id = ?");
  7. args.add(adminId);
  8. }
  9. }


roleMenuDao

[java] view plain copy
  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from ").append("sys_role_menu").append(" s where 1=1 ");
  4. Long adminId = params.getLong("roleId");
  5. if (adminId != null) {
  6. sql.append(" and s.role_id = ?");
  7. args.add(adminId);
  8. }
  9. }

在WEB-INF目錄下建立文件夾tlds 建立自定義標簽文件shiros.tld,我們通過自定義標簽實現頁面按鈕的控制。

[html] view plain copy
  1. <span style="color:#333333;"><?xml version="1.0" encoding="UTF-8" ?>
  2. <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  4. version="2.0">
  5. <description>p2p permission taglib</description>
  6. <display-name>permission taglib</display-name>
  7. <tlib-version>1.0</tlib-version>
  8. <short-name>p2p_back</short-name>
  9. <uri>http://vanfon.p2p.cn/</uri>
  10. <tag>
  11. <description>權限校驗標簽,有權限就顯示標簽體的內容,否則不顯示</description>
  12. <name>permission</name>
  13. <tag-class>com.vanfon.p2p.back.tag.PermissionTag</tag-class>
  14. <body-content>JSP</body-content>
  15. <attribute>
  16. <description></description>
  17. <name>module</name>
  18. <required>true</required>
  19. <rtexprvalue>false</rtexprvalue>
  20. </attribute>
  21. <attribute>
  22. <description></description>
  23. <name>code</name>
  24. <required>true</required>
  25. <rtexprvalue>false</rtexprvalue>
  26. </attribute>
  27. </tag>
  28. </taglib></span>

自定義標簽類

[java] view plain copy
  1. package com.vanfon.p2p.back.tag;
  2. import java.util.List;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.jsp.JspException;
  5. import javax.servlet.jsp.tagext.TagSupport;
  6. import com.vanfon.p2p.entity.system.Admin;
  7. import com.vanfon.p2p.entity.system.Menu;
  8. import com.vanfon.p2p.manager.system.AuthManager;
  9. import com.vanfon.p2p.utils.DynamicParams;
  10. import com.vanfon.p2p.utils.SpringContextHolder;
  11. /**
  12. * 權限控制標簽
  13. *
  14. * @author zhangwx
  15. * @date 2015-2-5
  16. */
  17. public class PermissionTag extends TagSupport {
  18. /**
  19. *
  20. */
  21. private static final long serialVersionUID = 4592227792811389132L;
  22. private String module;// 屬性名必須與JSP自定義標簽的屬性名一樣
  23. private String code;
  24. public String getModule() {
  25. return module;
  26. }
  27. public void setModule(String module) {
  28. this.module = module;
  29. }
  30. public String getCode() {
  31. return code;
  32. }
  33. public void setCode(String code) {
  34. this.code = code;
  35. }
  36. @Override
  37. public int doStartTag() throws JspException {
  38. boolean result = false;
  39. HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();// 通過成員變量獲取HttpServletRequest對象
  40. Admin admin = (Admin) request.getSession().getAttribute("admin");// 獲取登錄到系統的用戶
  41. if (admin != null) {
  42. if ("1".equals(String.valueOf(admin.getIfsuper()))) {// 超級管理員
  43. result = true;
  44. } else {
  45. DynamicParams params = new DynamicParams();
  46. params.put("id", String.valueOf(admin.getId()));
  47. params.put("module", this.module);
  48. params.put("code", this.code);
  49. AuthManager authManager = SpringContextHolder.getBean(AuthManager.class);
  50. List<Menu> userRoleAuths = authManager.findUserRoleAuthList(params);
  51. if (userRoleAuths != null && userRoleAuths.size() > 0) {
  52. result = true;
  53. }
  54. }
  55. }
  56. return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
  57. }
  58. }




以上就是該權限管理中權限樹(為角色分配權限)的大體實現。

技術分享

技術分享

管理系統權限設計借鑒