Web开发框架之权限管理系统

开发 前端 项目管理
我整理的一个框架体系,其中包含有WInform开发框架以及我的Web开发框架,由于前段时间一直忙于Winform开发框架的提炼以及优化,并统一整理了很多Winform开发框架以及WCF开发框架的随笔文章。

记得我在很早之前,开始介绍我的Winform开发框架和我的WCF开发框架之初,我曾经给出下面的视图,介绍我整理的一个框架体系,其中包含有WInform开发框架以及我的Web开发框架,由于前段时间一直忙于Winform开发框架的提炼以及优化,并统一整理了很多Winform开发框架以及WCF开发框架的随笔文章。随着我的Winform逐步完善,终于有时间来整理介绍我的Web开发框架的事宜了,下面先介绍一下我最新优化整理的Web开发框架之权限管理系统,其中这个权限管理系统可以说是集众多宠爱于一身了,除了一贯的和代码生成工具集成,可生成基础性的框架代码外,还整合Winform开发框架继承而来的多数据库支持,在界面层,也就是Web权限管理系统,整合了JQuery的Easy-UI界面组件,功能强大的zTree控件、KindEditor在线编辑控件、界面层获取数据及保存使用基于JQuery的json数据操作,实现数据局部刷新等等操作,其中提供两种不同的菜单布局操作,非常方便应用于其他业务系统的界面。

首先在介绍之前,我们来贴几个Web权限系统的图片进行感性的了解先。

1)简洁的界面布局效果。这种效果顶部横幅比较紧凑,左边有一些常用的按钮操作,适合于菜单功能不太多的小业务系统,如我的Web权限系统。

2)功能强大的界面企业业务系统布局。这种界面效果适合于功能比较众多,菜单展示进行分类管理等业务系统。这种框架顶部的菜单为一级菜单,单击一级菜单可以在左边展示二级菜单,这种效果可以不用一次性列出所有系统的功能,而是分层次进行功能展示。

顶部的Tab选项卡每次打开页面的时候,增加一个Tab页,页面可以双击进行关闭,也可以右键弹出菜单进行更多操作,如下图所示。

如果需要了解整个系统的效果,也可以下载《Web权限系统操作视屏》进行全面的了解。

在提炼优化这个Web权限框架的过程中,碰到了不少的问题,一一进行解决,现总结一部分进行进行介绍。

#p#

1)使用JSON数据构造zTree

使用zTree确实比easy-ui自带的Tree好很多,功能也强大很多,由于我的Web权限中,各个模块几乎都需要树控件来展示相关的数据,如功能、组织机构等等。在对比了我自己的传统Tree、Easy-UI的Tree控件以及zTree后,发现使用zTree还是可以提高不少的界面分数的。但是其自带的例子,以及网上的例子,多数是使用预先弄好的树形数据,而我需要动态使用ashx进行树形数据的获取及生成,这确实费了一些周折来进行调试。

首先要准备基于ashx处理程序生成的Tree数据,树的数据使用JSON格式。如功能定义的树形数据如下所示。

  1. /// <summary>  
  2. /// 递归获取树形信息  
  3. /// </summary>  
  4. private string GetTreeJson(int PID, string folderIcon, string leafIcon)  
  5. {  
  6.     string condition = string.Format("PID={0}", PID);  
  7.     List<FunctionInfo> nodeList = BLLFactory<Function>.Instance.Find(condition);  
  8.     StringBuilder content = new StringBuilder();  
  9.     foreach (FunctionInfo model in nodeList)  
  10.     {  
  11.         int ParentID = (model.PID == -1 ? 0 : model.PID);  
  12.         //string tempMenu = string.Format("{{ id:{0}, pId:{1}, name:\"{2}\",icon:\"{3}\" }},", model.ID, ParentID, model.Name, imgsrc); //简单的作法  
  13.         string subMenu = this.GetTreeJson(model.ID, folderIcon, leafIcon);  
  14.         string parentMenu = string.Format("{{ \"id\":{0}, \"pId\":{1}, \"name\":\"{2}\" ", model.ID, ParentID, model.Name);  
  15.         if (string.IsNullOrEmpty(subMenu))  
  16.         {  
  17.             if (!string.IsNullOrEmpty(leafIcon))  
  18.             {  
  19.                 parentMenu += string.Format(",\"icon\":\"{0}\" }},", leafIcon);  
  20.             }  
  21.             else 
  22.             {  
  23.                 parentMenu += "},";  
  24.             }  
  25.         }  
  26.         else 
  27.         {  
  28.             if (!string.IsNullOrEmpty(folderIcon))  
  29.             {  
  30.                 parentMenu += string.Format(",\"icon\":\"{0}\" }},", folderIcon);  
  31.             }  
  32.             else 
  33.             {  
  34.                 parentMenu += "},";  
  35.             }  
  36.         }  
  37.  
  38.         content.AppendLine(parentMenu.Trim());  
  39.         content.AppendLine(subMenu.Trim());  
  40.     }  
  41.  
  42.     return content.ToString().Trim();  
  43. }  

然后就是页面的调用了,这里为了增强体验效果,使用了基于javascript的JQuery的异步操作进行数据处理,而不是基于aspx后台页面的处理,如下所示。

  1. //重新加载树形结构(异步)  
  2. function reloadTree() {  
  3.     $("#loading").show();  
  4.     $.getJSON("http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=" + Math.random() + "&op=tree"function (json) {  
  5.         $.fn.zTree.init($("#treeDemo"), setting, json);  
  6.         $.fn.zTree.getZTreeObj("treeDemo").expandAll(true);  
  7.  
  8.         var treeObj = $.fn.zTree.getZTreeObj("treeDemo");  
  9.         var treeNodes = treeObj.getNodes();  
  10.         if (treeNodes != null) {  
  11.             loadData(treeNodes[0].id);  
  12.         }  
  13.     });  
  14.     $("#loading").fadeOut(500);  

这样处理的效果是页面只是局部刷新,体验很好。

2)基于JQuery的数据加载及保存操作

由于JQuery的方便性及良好体验性,我统一了数据的获取及保存操作。下面给出相关的处理代码供参考。

  1. //加载制定的对象数据  
  2. function loadData(id) {  
  3.     $("#loading").show();  
  4.     $.getJSON("http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=" + Math.random() + "&op=findbyid&id=" + id, function (json) {  
  5.         $("#txtID").val(json.ID);  
  6.         $("#txtName").val(json.Name);  
  7.         $("#txtControlID").val(json.ControlID);  
  8.         $("#txtPID").val(json.PID);  
  9.     });  
  10.  
  11.     $('#lbxRoles').empty();  
  12.     $.getJSON("http://www.cnblogs.com/AjaxHandler/RoleJson.ashx?r=" + Math.random() + "&op=getrolesbyfunction&id=" + id, function (json) {  
  13.         $.each(json, function (i, item) {  
  14.             $('#lbxRoles').append('<option value="' + item.ID + '">' + item.Name + '</option>');  
  15.         });  
  16.     });  
  17.     $("#loading").fadeOut(500);  
  18. }  
  19.  
  20. //保存对象数据  
  21. function saveData() {  
  22.     $.ajax({  
  23.         type: 'POST',  
  24.         url: 'http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=' + Math.random() + '&op=insert',  
  25.         async: false,  
  26.         data: { ID: $("#txtID").val(), Name: $("#txtName").val(), ControlID: $("#txtControlID").val(), PID: $("#txtPID").val() },  
  27.         success: function (id) {  
  28.             alert("操作成功! ");  
  29.             reloadTree();  
  30.  
  31.             if (id != "")  
  32.                 loadData(id);  
  33.         },  
  34.         error: function (xhr, status, error) {  
  35.             alert("操作失败"); //xhr.responseText  
  36.         }  
  37.     });  

3)在数据操作等待的时候,页面中间显示Loading效果。

整个系统,在各种请求操作,我都统一了作法,在界面显示Loading的等待效果,任务结束后关闭,这种效果在费事的操作,用户体检会好一些,下面看看其效果以及实现代码。

[[87310]]

增加下面javascript脚本

  1. //对象居中的函数,调用例子:$("#loading").center();  
  2. jQuery.fn.center = function () {  
  3.     this.css("position""absolute");  
  4.     this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +  
  5.                                         $(window).scrollTop()) + "px");  
  6.     this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +  
  7.                                         $(window).scrollLeft()) + "px");  
  8.     return this;  
  9. }  
  10.  
  11. //初始化对象  
  12. $(document).ready(function () {  
  13.  
  14.     $("#loading").center();//loading的图片显示居中  
  15. }); 

然后再页面Body后面增加一行代码即可(默认loading图片不显示的哦)。

  1. < id="loading" style="display: none;"><img alt="数据正在加载中..." src="http://images.cnblogs.com/loading02.gif" /></> 

4)控件数据清空操作

由于添加和编辑公用界面控件元素,因此我们在要添加数据的时候,需要清空或者设置某些控件的值,但我们的控件可能比较多,一种好的方法是利用JQuery的选择器功能来进行有目的的控件清空操作。

如下面的例子所示。

  1. //新增清空控件  
  2. function addData() {  
  3.     $("#txtPID").val($("#txtID").val());  
  4.     $("input[type=text][id*='txt']").val("");  
  5.     $("textarea[id*='txt']").empty();  
  6.     $("select[id*='lbx']").empty();  

其中$("#txtPID").val($("#txtID").val());是把当前的用户作为添加数据的上级,其他的就是清空控件的数据了,不同的类型控件清空的步骤有些不同。

5)Ashx处理程序的安全性考虑

我们在系统中,多数都是调用ashx进行数据处理,虽然一般业务系统在VPN或者内网中运行,但是也要考虑用户没登陆的时候,不运行调用ashx程序,这样可以提高数据的安全性。

默认的ashx处理程序是没有Session的操作的,所以我们需要修改其继承接口(多增加IReadOnlySessionState 的继承),然后才能调用Session来进行判断。

  1. /// <summary>  
  2. /// 权限功能操作类  
  3. /// </summary>  
  4. [WebService(Namespace = "http://tempuri.org/")]  
  5. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
  6. public class FunctionJson : IHttpHandler, IReadOnlySessionState   
  7. {          
  8.     public void ProcessRequest(HttpContext context)  
  9.     {  
  10.         //类对象要显式的实现接口 IReadOnlySessionState,才能访问Session数据  
  11.         if (context.Session["Identity"] == null)  
  12.         {  
  13.             throw new ArgumentException("用户未登录!");  
  14.         } 

6)Tab界面布局的兼容。

Web权限系统提供了两种常用的菜单布局进行管理,一般对于常用的业务系统肯定是没问题了。

另外一种效果是系统复杂的时候用的,可以定义一级菜单和关联的二级菜单。

对于后者,一级菜单打开的时候,可以关联打开一个新的页面,并且刷新二级菜单的关系。

  1. <!----------- 一级导航 ------------------> 
  2. <ul class="navigation" style="display:block"> 
  3.     <li><a href="#" onclick="showSubMenu('ListUser.aspx', '用户管理', 'default')">权限管理</a></li> 
  4.     <li><a href="#" onclick="showSubMenu('../Commonpage/MyJob.aspx', '事务中心开发中...', 'point', 'icon-organ')">事务中心</a></li> 
  5.     <li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '合同起草开发中...', '')">合同起草</a></li> 
  6.     <li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '合同管理开发中...', '')">合同管理</a></li> 
  7.     <li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '查询打印开发中...', '')">查询打印</a></li> 
  8.     <li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '知识管理开发中...', '')">知识管理</a></li> 
  9.     <li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '系统管理开发中...', '')">系统管理</a></li> 
  10. </ul> 

好了,很多其他的特点,以后继续介绍,欢迎多多提出宝贵意见。

原文链接:http://www.cnblogs.com/wuhuacong/archive/2012/07/28/2613593.html

【编辑推荐】

  1. Web开发人员有用的代码比较工具
  2. 构建高性能Web站点(修订版)
  3. Web程序员走过的那些路
  4. 8个实用且免费的Web应用程序安全测试工具
  5. 做最好的中文Web工具,提高工作效率
责任编辑:张伟 来源: 伍华聪的博客
相关推荐

2012-09-25 09:31:58

ASP.NETC#Web

2012-08-21 11:26:17

Winform

2012-10-08 14:01:54

ASP.NETWebC

2012-12-11 10:15:02

Winform开发框架

2012-09-26 09:46:29

ASP.NETWeb框架

2009-09-03 16:52:44

Java Web开发框

2009-06-18 12:06:30

Java Web开发框

2010-05-19 14:38:11

Web开发框架Web层

2021-11-18 10:28:03

鸿蒙HarmonyOS应用

2021-11-09 09:43:52

鸿蒙HarmonyOS应用

2012-09-29 13:20:30

ASP.NETWeb框架

2012-06-12 13:33:38

HTML5

2016-01-27 09:39:13

JoobyJava Web流程

2015-11-17 13:15:23

Apache开发

2022-04-07 15:41:36

PythonWeb 开发框

2022-07-03 17:10:15

JavaScript编程语言开发

2024-03-11 10:19:30

Plasmo浏览器Web

2009-06-25 17:14:59

JSF框架

2013-01-10 11:13:38

Golang WebRevel测试Web开发

2012-09-20 09:54:12

ASP.NETWebC
点赞
收藏

51CTO技术栈公众号