Web开发框架之权限管理系统
Web开发框架之权限管理系统
记得我在很早之前,开始介绍我的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权限框架的过程中,碰到了不少的问题,一一进行解决,现总结一部分进行进行介绍。
1)使用JSON数据构造zTree
使用zTree确实比easy-ui自带的Tree好很多,功能也强大很多,由于我的Web权限中,各个模块几乎都需要树控件来展示相关的数据,如功能、组织机构等等。在对比了我自己的传统Tree、Easy-UI的Tree控件以及zTree后,发现使用zTree还是可以提高不少的界面分数的。但是其自带的例子,以及网上的例子,多数是使用预先弄好的树形数据,而我需要动态使用ashx进行树形数据的获取及生成,这确实费了一些周折来进行调试。
首先要准备基于ashx处理程序生成的Tree数据,树的数据使用JSON格式。如功能定义的树形数据如下所示。
/// <summary>
/// 递归获取树形信息
/// </summary>
private string GetTreeJson(int PID, string folderIcon, string leafIcon)
{
string condition = string.Format("PID={0}", PID);
List<FunctionInfo> nodeList = BLLFactory<Function>.Instance.Find(condition);
StringBuilder content = new StringBuilder();
foreach (FunctionInfo model in nodeList)
{
int ParentID = (model.PID == -1 ? 0 : model.PID);
//string tempMenu = string.Format("{{ id:{0}, pId:{1}, name:\"{2}\",icon:\"{3}\" }},", model.ID, ParentID, model.Name, imgsrc); //简单的作法
string subMenu = this.GetTreeJson(model.ID, folderIcon, leafIcon);
string parentMenu = string.Format("{{ \"id\":{0}, \"pId\":{1}, \"name\":\"{2}\" ", model.ID, ParentID, model.Name);
if (string.IsNullOrEmpty(subMenu))
{
if (!string.IsNullOrEmpty(leafIcon))
{
parentMenu += string.Format(",\"icon\":\"{0}\" }},", leafIcon);
}
else
{
parentMenu += "},";
}
}
else
{
if (!string.IsNullOrEmpty(folderIcon))
{
parentMenu += string.Format(",\"icon\":\"{0}\" }},", folderIcon);
}
else
{
parentMenu += "},";
}
} content.AppendLine(parentMenu.Trim());
content.AppendLine(subMenu.Trim());
} return content.ToString().Trim();
}
然后就是页面的调用了,这里为了增强体验效果,使用了基于javascript的JQuery的异步操作进行数据处理,而不是基于aspx后台页面的处理,如下所示。
//重新加载树形结构(异步)
function reloadTree() {
$("#loading").show();
$.getJSON("http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=" + Math.random() + "&op=tree", function (json) {
$.fn.zTree.init($("#treeDemo"), setting, json);
$.fn.zTree.getZTreeObj("treeDemo").expandAll(true); var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
var treeNodes = treeObj.getNodes();
if (treeNodes != null) {
loadData(treeNodes[0].id);
}
});
$("#loading").fadeOut(500);
}
这样处理的效果是页面只是局部刷新,体验很好。
2)基于JQuery的数据加载及保存操作
由于JQuery的方便性及良好体验性,我统一了数据的获取及保存操作。下面给出相关的处理代码供参考。
//加载制定的对象数据
function loadData(id) {
$("#loading").show();
$.getJSON("http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=" + Math.random() + "&op=findbyid&id=" + id, function (json) {
$("#txtID").val(json.ID);
$("#txtName").val(json.Name);
$("#txtControlID").val(json.ControlID);
$("#txtPID").val(json.PID);
}); $('#lbxRoles').empty();
$.getJSON("http://www.cnblogs.com/AjaxHandler/RoleJson.ashx?r=" + Math.random() + "&op=getrolesbyfunction&id=" + id, function (json) {
$.each(json, function (i, item) {
$('#lbxRoles').append('<option value="' + item.ID + '">' + item.Name + '</option>');
});
});
$("#loading").fadeOut(500);
} //保存对象数据
function saveData() {
$.ajax({
type: 'POST',
url: 'http://www.cnblogs.com/AjaxHandler/FunctionJson.ashx?r=' + Math.random() + '&op=insert',
async: false,
data: { ID: $("#txtID").val(), Name: $("#txtName").val(), ControlID: $("#txtControlID").val(), PID: $("#txtPID").val() },
success: function (id) {
alert("操作成功! ");
reloadTree(); if (id != "")
loadData(id);
},
error: function (xhr, status, error) {
alert("操作失败"); //xhr.responseText
}
});
}
3)在数据操作等待的时候,页面中间显示Loading效果。
整个系统,在各种请求操作,我都统一了作法,在界面显示Loading的等待效果,任务结束后关闭,这种效果在费事的操作,用户体检会好一些,下面看看其效果以及实现代码。
增加下面javascript脚本
//对象居中的函数,调用例子:$("#loading").center();
jQuery.fn.center = function () {
this.css("position", "absolute");
this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
} //初始化对象
$(document).ready(function () { $("#loading").center();//loading的图片显示居中
});
然后再页面Body后面增加一行代码即可(默认loading图片不显示的哦)。
<div id="loading" style="display: none;"><img alt="数据正在加载中..." src="http://images.cnblogs.com/loading02.gif" /></div>
4)控件数据清空操作
由于添加和编辑公用界面控件元素,因此我们在要添加数据的时候,需要清空或者设置某些控件的值,但我们的控件可能比较多,一种好的方法是利用JQuery的选择器功能来进行有目的的控件清空操作。
如下面的例子所示。
//新增清空控件
function addData() {
$("#txtPID").val($("#txtID").val());
$("input[type=text][id*='txt']").val("");
$("textarea[id*='txt']").empty();
$("select[id*='lbx']").empty();
}
其中$("#txtPID").val($("#txtID").val());是把当前的用户作为添加数据的上级,其他的就是清空控件的数据了,不同的类型控件清空的步骤有些不同。
5)Ashx处理程序的安全性考虑
我们在系统中,多数都是调用ashx进行数据处理,虽然一般业务系统在VPN或者内网中运行,但是也要考虑用户没登陆的时候,不运行调用ashx程序,这样可以提高数据的安全性。
默认的ashx处理程序是没有Session的操作的,所以我们需要修改其继承接口(多增加IReadOnlySessionState 的继承)
,然后才能调用Session来进行判断。
/// <summary>
/// 权限功能操作类
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FunctionJson : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
{
//类对象要显式的实现接口 IReadOnlySessionState,才能访问Session数据
if (context.Session["Identity"] == null)
{
throw new ArgumentException("用户未登录!");
}
6)Tab界面布局的兼容。
Web权限系统提供了两种常用的菜单布局进行管理,一般对于常用的业务系统肯定是没问题了。
另外一种效果是系统复杂的时候用的,可以定义一级菜单和关联的二级菜单。
对于后者,一级菜单打开的时候,可以关联打开一个新的页面,并且刷新二级菜单的关系。
<!----------- 一级导航 ------------------>
<ul class="navigation" style="display:block">
<li><a href="#" onclick="showSubMenu('ListUser.aspx', '用户管理', 'default')">权限管理</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/MyJob.aspx', '事务中心开发中...', 'point', 'icon-organ')">事务中心</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '合同起草开发中...', '')">合同起草</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '合同管理开发中...', '')">合同管理</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '查询打印开发中...', '')">查询打印</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '知识管理开发中...', '')">知识管理</a></li>
<li><a href="#" onclick="showSubMenu('../Commonpage/building.htm', '系统管理开发中...', '')">系统管理</a></li>
</ul>
好了,很多其他的特点,以后继续介绍,欢迎多多提出宝贵意见。
专注于Winform开发框架、Web开发框架、WCF开发框架、微信门户开发框架的研究及应用。
转载请注明出处:
撰写人:伍华聪 http://www.iqidi.com
Web开发框架之权限管理系统的更多相关文章
- Winform开发框架之权限管理系统的改进
权限管理系统,一直是很多Mis系统和一些常见的管理系统所需要的,所以一般可以作为独立的模块进行开发,需要的时候进行整合即可,不需要每次从头开发,除非特殊的系统需求.我在Winform开发框架介绍中的随 ...
- Winform开发框架之权限管理系统改进的经验总结(2)-用户选择界面的设计
在上篇总结随笔<Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用>介绍了权限管理模块的用户管理部分,其中主要介绍了其中的用户所属公司 ...
- Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用
最近一直在做一些技术性的研究和框架改进工作,博客也落下好几天没有更新了,也该是时候静下心来,总结这段时间的一些技术改进的经验了.和上一阶段的CRM系统开发和技术研究一样,我都喜欢在一个项目或者模块完成 ...
- Winform开发框架之权限管理系统改进的经验总结(4)--用户分级管理
在实际的系统应用环境中,用户的分级管理一般也是比较常见的功能,小的业务系统可以不需要,但是一般涉及到集团.分子公司.或者是事业单位里面的各个处室或者某某局的人员管理,这些分级管理就显得比较必要,否则单 ...
- Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录
在前面介绍了几篇关于我的权限系统改进的一些经验总结,本篇继续这一系列主体,介绍如何一行代码实现重要表的操作日志记录.我们知道,在很多业务系统里面,数据是很敏感的,特别对于一些增加.修改.删除等关键的操 ...
- Winform开发框架之权限管理系统改进的经验总结(3)-系统登录黑白名单的实现
在一般的权限系统里面,可能经常会看到系统的黑名单或者白名单的拦截功能.在一般权限系统里面,常见的黑名单就是禁止用户在某些IP上登录系统,白名单就是允许用户只在某些IP上登录系统.本随笔主要介绍在我的权 ...
- Winform开发框架之权限管理系统
本文章转载:http://www.cnblogs.com/wuhuacong/archive/2011/05/08/2040620.html 至此,权限管理模块介绍已经完毕,下面给出一个调用例子Dem ...
- ASP.NET MVC4.0+ WebAPI+EasyUI+KnockOutJS快速开发框架 通用权限管理系统
1.基于 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发 2.采用MVC的框架模式,具有耦合性低.重用性高.生命周期成本低.可维护性高.有利软件 ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍
最近花了很多时间在重构和进一步提炼Winform开发框架的工作上,加上时不时有一些项目的开发工作,我博客里面介绍Web开发框架的文章比较少,其实以前在单位工作,80%的时间是做Web开发的,很早就形成 ...
随机推荐
- Django - 模型层 - 上
一.ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- Python开发【模块】:time、datatime
时间模块 时间相关的操作,时间有三种表示方式: 时间戳 1970年1月1日之后的秒,即:time.time() 格式化的字符串 2014-11-11 11:11, ...
- 省市县三级联动的SQL
完整版见https://jadyer.github.io/ 首先是建表语句 CREATE TABLE `t_address_province` ( `id` INT AUTO_INCREMENT PR ...
- (1.1)DML增强功能-CTE
1.CTE的通用形式 WITH temp_name as ( CTE查询结果集 ) 释义: (1)with/as :关键字 (2)temp_name:为CTE临时使用名称,可以看初学者做是一个临时表 ...
- Openstack(十二)部署neuron(计算节点)
在计算节点安装 12.1安装neuron(计算节点) # yum install openstack-neutron-linuxbridge ebtables ipset –y 12.2配置neutr ...
- google浏览器插件安装
1:安装本地插件,直接将下载好的crx插件拖入到 chrome://extensions/ 的空白处 http://www.cnplugins.com/tool/outline-instal ...
- ajax请求,html调用js
1:html中调用js中的函数,js使用ajax请求向后台请求,返回数据. <!DOCTYPE html> <html lang="en"> <hea ...
- 博客迁移至新平台ixirong.com
很久没有在博客园上写文章了,一是时间有些忙,更重要的是自己还是没有抽出时间来坚持写下去,由于15年后自己的一些打算,在前一段时间的时候,建立了自己的个人博客站点,http://www.ixirong. ...
- gcc安装多个版本
http://blog.csdn.net/chid/article/details/6251781
- Python tricks(1) -- 动态定义一个新变量
python是动态语言, 无需声明变量即可使用. 传递一个tuple, list或者dict等等方式, 有时候这种方式的使用不是很好. 对于tuple和list来说都是用下标的访问方式(即使用[]), ...