2023年2月

脊柱外科患者资料管理系统

脊柱外科患者资料管理系统,能非常方便实现对外科患者相关病历数据和图片资料的管理,并可实现对患者随访的跟踪记录,以及术前术后进行VAS评分和JOA评分对比,实现患者病历电子化的管理和跟踪。

软件对患者的数据管理分为“基本信息”、“手术情况”、“患者病历”、“随访情况”,软件支持数据条件查询、Excel导入导出、高级查询、图片查看预览、列表打印,以及字典数据管理、数据库备份恢复等功能,是一款优秀易用的患者数据管理软件。

下载
购买

★系统需求

该软件使用C#语言开发,适运行在 Windows 7/Vista/2000/XP/2003 等平台,但必须安装有.Net4.0平台。 如果您的计算机不能运行本程序,强烈建议您下载 .NET 4.0 运行库。 .NET Framework 4.0 官方下载地址:
http://www.microsoft.com/zh-cn/download/details.aspx?id=17718

★软件注册

该软件是一款共享软件,您可以自由发布和传播软件,未注册版本会在使用20天后过期。在带给您方便的同时, 希望您能考虑注册这款软件,注册软件的时候请提供软件的机器码。如果您在电脑报刊发表了介绍这个软件的文章,将刊物名称和期号告诉我,我们将免费为您提供注册码。

该软件版权归"
广州爱奇迪软件科技有限公司
"所有,作者保留该软件所有权利,未注册用户不得将该软件用于商业用途。

系统界面截图介绍

软件登陆界面截图如下:

软件主界面截图如下,患者资料里面包括了常规的查询数据项,包括查询按钮、高级查询、新建、导入、导出功能项,其中导出是把列表中的患者数据导出到Excel进行展示,导入是把一些患者资料以固定的Excel模板格式进行批量导入。
软件除了患者资料管理外,还包括了JOA评分项目维护、数据字典、数据备份与恢复、密码修改等一些列功能。


在主界面中“新建”、或双击记录“编辑”患者资料,会弹出下面新建或者编辑患者资料的对话框,其中包括了患者资料的基本信息、手术情况、患者病历、随访情况等信息管理。 其中患者基本信息界面如下所示,输入身份证,可以自动填写用户的出生日期、年龄、性别信息,其他下拉列表从字典中获取,字典列表内容可以动态配置。

患者手术情况界面如下所示,其中影像学资料分类进行管理,可以单击“查看附件”进行查看,附件信息以缩略图进行显示,需要大图展示可以双击图标即可显示,另外图片及Excel、Word文档也可以通过附件上传方式上传到系统里面。


患者的病历界面如下所示,其中细化评估了脊柱骨科很多相关的数据项,所有数据项均从预设的数据字典里面选取。另外对患者术前术后的身体状况进行了JOA评分和VAS评分管理,使得评估更加准确,根据具有参考价值。


单击上图的“JOA评分”,会弹出一个新的对话框显示患者术前和术后的JOA评分明细和总分,可以对患者这些评分项目进行对比分析。


在VAS评分对话框里面,对评分的数值进行了可视化的展示,方便对患者VAS评分进行直观化评分。


另外,刚才主对话框里面,也有一项“随访情况”的数据记录,系统可以对患者的多次随访数据进行记录,随访界面如下所示,其中包括了常规的随访项目外,还可以对患者进行JOA评分和VAS评分,以及对随访的相关影像学资料进行查看管理。

新建随访记录界面如下所示。


整个系统里面用到了很多下列项目,里面的数据均可在系统的字典里面进行配置管理,界面如下所示。


软件还具备对数据库的备份和恢复,可以对系统重要的数据进行有效的备份管理。


系统在主界面的患者资料管理中,由于界面的限制,数据查询项只是列出一些常规重要的查询项目,如果需要进行更多条件的查询,可以通过患者资料的“高级查询”按钮进行,在弹出的高级查询对话框中,里面列出了所有患者的数据项目,可以双击列表进行条件设置,界面如下所示。


另外,整个软件界面美观大方,默认提供了Office2010蓝色样式,如果需要体验其他界面样式,可以在工具栏的“界面皮肤”列表中选择,效果如下所示。

心脏骤停患者数据统计系统

心脏骤停患者数据统计系统,该软件根据书面采集到的心脏骤停患者相关数据,进行数据库建模,并依据数据库数据,实现查询统计分析功能。软件支持数据条件查询、数据导入导出、高级查询,以及数据库备份恢复等功能,以及字典数据管理、数据库备份恢复等功能,是一款优秀易用的患者数据管理软件。

★系统需求

该软件使用C#语言开发,适运行在 Windows 7/Vista/2000/XP/2003 等平台,但必须安装有.Net4.0平台。 如果您的计算机不能运行本程序,强烈建议您下载 .NET 4.0 运行库。 .NET Framework 4.0 官方下载地址:
http://www.microsoft.com/zh-cn/download/details.aspx?id=17718

★软件注册

该软件是一款共享软件,您可以自由发布和传播软件,未注册版本会在使用20天后过期。在带给您方便的同时, 希望您能考虑注册这款软件,注册软件的时候请提供软件的机器码。如果您在电脑报刊发表了介绍这个软件的文章,将刊物名称和期号告诉我,我们将免费为您提供注册码。

该软件版权归"
广州爱奇迪软件科技有限公司
"所有,作者保留该软件所有权利,未注册用户不得将该软件用于商业用途。

系统界面截图介绍

软件登陆界面截图如下:


软件主界面截图如下,患者资料里面包括了常规的查询数据项,包括查询按钮、高级查询、新建、导入、导出功能项,其中导出是把列表中的患者数据导出到Excel进行展示,导入是把一些患者资料以固定的Excel模板格式进行批量导入。


在主界面中“新建”、或双击记录“编辑”患者资料,会弹出下面新建或者编辑患者资料的对话框, 其中包括了基心脏患者的基本资料管其他信息高管理,界面截图如下所示


其他信息管理的界面截图如下:


系统在主界面的资料管理中,由于界面的限制,数据查询项只是列出一些常规重要的查询项目,如果需要进行更多条件的查询,可以通过患者资料的“高级查询”按钮进行,在弹出的高级查询对话框中,里面列出了所有患者的数据项目,可以双击列表进行条件设置,界面如下所示。 截图如下:


整个系统里面用到了很多下列项目,里面的数据均可在系统的字典里面进行配置管理,界面如下所示。截图如下:


软件还具备对数据库的备份和恢复,可以对系统重要的数据进行有效的备份管理。截图如下:

做了好多年Winform的程序的开发,主窗口的界面设计一般都要求做的更好一些,可以根据不同的系统功能模块进行归类整合,能使客户迅速寻找到相关功能的同时,也能感觉到整体性的美观大方,因此主窗口的界面设计总是会精益求精,力求做到更好用、更美观,这样才能吸引客户使用。

目前的主体界面设计,可以使用很多控件进行美化,这样能使得开发者能够迅速开发好美观的界面,也可以使得界面总体性有一个统一、规范的基准。一般推荐使用DevExpress或者DotNetbar这两款界面控件套件,他们都能设计出类似Office的Ribbon界面,这种界面整体感觉会比较好一些。

1、标准的DevExpress样式界面

在我的Winform开发框架中,也分为了传统性界面、DotNetBar样式界面、DevExpress样式界面这三种,根据不同的开发场景进行使用,如果是历史性原因导致,那就根据需要选择,如果是新的程序开发,那么建议采用DevExpress样式的界面,这种界面样式,经过我这几年的开发应用了解,觉得真的非常棒,非常强大,基于Dev样式的《Winform开发框架》主体界面设计如下所示。

这个主体界面是Ribbon样式的界面,它分为了几个部分,我从顶部开始到下面进行介绍。

1)、顶部样式选择

DevExpress控件可以将窗体的空间运用到极致,很多细微的地方都可以用起来。在开发的应用程序中,增加这个样式选择,也会使客户觉得这个程序开发也是非常专业的(^_^)。

2)、主程序菜单

在Ribbon样式中,添加这种样式的主程序菜单,比增加一个顶部的MenuBar来的好看,这也是标准的Office程序的Ribbon样式菜单,我们可以在里面添加各种层级的菜单,如下面是一个简单的退出和重登录菜单。

3)、主界面帮助小按钮

主界面的右边可以放置一些小按钮,如在程序中放置一个帮助小按钮,用来给客户提供帮助或者技术支持的网址链接,都是不错的选择。

4)、Ribbon样式分组按钮

在我的Winform开发框架中,通过图文并茂的功能按钮,可以使得整个程序看起来更加美观,选取合适的按钮图标,更加可以提高客户的认同感,Ribbon样式的分组按钮,可以增加更多的功能菜单,也可以进行更合适的归类管理。

5)、多文档界面布局

现在的程序,一般录入或者查看的资料都会很多,程序尽可能保持客户的查看的窗口状态,以便更好的参考和对比,因此多文档界面就是一个非常合适的选择,如下界面所示。

6)、底部状态栏

底部菜单可以让客户更好了解程序的一些相关信息,如程序名称、登陆用户,日期,以及程序处理进度等方面的信息。

2、Winform开发框架的扩展性界面样式

以上就是标准的框架界面,有时候我也会根据需要给客户设计一些不同的界面样式,如我的标准Winform开发框架界面,还可以扩展为下面的界面风格(
适用于界面功能比较多的情况)

这种界面方式,通过结合Ribbon功能和NaviBarControl的方式,实现更多功能的展示,如果必要,可以根据Ribbon的按钮,展开左边的NavibarControl的相关的模块内容。

上面界面的Ribbon按钮图标,在界面功能比较多的时候,还可以以小图标按钮方式进行展示,这样一个区域可以包含更多的功能按钮,如下所示。

主程序的菜单可以分级展示,如二级菜单可以进一步展开更多的菜单,如下所示。

对于一些传统布局的界面,我们还可以通过如下的人力资源管理系统界面进行展示,这种界面比较适合功能点比较多的界面,这种可以通过树形菜单进行打开操作具体的模块界面。

以上就是这几种Winform界面样式的设计思路和展示,希望对大家有启发帮助。

在很多常规的管理系统里面,都可能有附件管理的需求,在我做的一系列医疗行业的病人信息管理系统里面,都希望能很好的管理病人的相关资料,分门别类的进行存储,需要的时候可以预览查看,那么这个功能我们可以把它独立做成一个附件管理模块,这样可以在各个系统中集成即可,我曾经在《
Winform开发框架之通用附件管理模块
》里面介绍过这样的附件模块,从那时候开始了,我需要附件模块的时候,就通过集成起来即可,非常方便高效。

1、附件管理界面展示

附件管理在很多信息化管理系统中很普遍使用,例如我在病人管理系统界面里面,可以在一个界面里面分门别类管理很多影像学的图片资料,通过查看附件,可以看到其中一些图片附件的缩略图,需要进一步查看,可以双击图片即可实现预览效果。

随访信息界面也可以录入一些相关的附件信息。

附件管理的上传界面如下所示,可以从本地选择多个文件一并上传,每个文件上传成功后立即显示状态。

上传后,界面以缩略图进行展示,如果需要删除,勾选“全部选择”、“选择附件”选项即可。

图片双击后可以进行预览,如果其他文件,那么可以下载后打开。

2、附件模块的使用代码展示

1)由于附件管理已经封装好控件了,所以在使用的时候,拖动到界面即可。

在界面后台代码里面,给它绑定相关的属性即可,下面是我们绑定显示附件的操作。

        //PatientInfo在对象存在则为指定对象,新建则是全新的对象,初始化的GUID用于附件上传
       private voidSetAttachInfo(PatientInfo info)
{
this.attachBeforeCT.AttachmentGUID =info.BeforeCT;this.attachBeforeMRI.AttachmentGUID =info.BeforeMRI;this.attachBeforeXRay.AttachmentGUID =info.BeforeXRay;this.attachBeforeBitSlice.AttachmentGUID =info.BeforeBitSlice;this.attachBeforePicture.AttachmentGUID =info.BeforePicture;this.attachMiddlePicture.AttachmentGUID =info.MiddlePicture;this.attachMiddleVideo.AttachmentGUID =info.MiddleVideo;this.attachMiddleXRay.AttachmentGUID =info.MiddleXRay;this.attachAfterCT.AttachmentGUID =info.AfterCT;this.attachAfterMRI.AttachmentGUID =info.AfterMRI;this.attachAfterXRay.AttachmentGUID =info.AfterXRay;this.attachAfterBitSlice.AttachmentGUID =info.AfterBitSlice;this.attachAfterPicture.AttachmentGUID =info.AfterPicture;
}

在图片存储中,我们一般是根据患者姓名和ID号进行存放的,所以附件的目录需要根据参数进行指定,代码如下所示。

        /// <summary>
        ///当修改患者姓名或者ID号的时候,改变附件的目录位置/// </summary>
        private voidSetAttachmentPath()
{
if (!this.DesignMode)
{
string patientName = this.txtName.Text.Trim();string IdNumber = this.txtIDNumber.Text.Trim();if (!string.IsNullOrEmpty(patientName) && !string.IsNullOrEmpty(IdNumber))
{
string dir = string.Format("{0}.{1}", patientName, IdNumber);this.attachBeforeCT.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachBeforeMRI.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachBeforeXRay.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachBeforeBitSlice.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachBeforePicture.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachMiddlePicture.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachMiddleVideo.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachMiddleXRay.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachAfterCT.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachAfterMRI.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachAfterXRay.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachAfterBitSlice.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);this.attachAfterPicture.Init(dir, PatientInfo.ID, Portal.gc.LoginInfo.Name);
}
}
}

里面代码那个Init函数的定义如下所示,这样我们就知道附件属于那个病人的记录,属于那个登陆用户上传的了,方便我们后面对附件进行分类管理和控制。

        /// <summary>
        ///初始化相关参数/// </summary>
        /// <param name="attachmentDir">设置附件的存储目录分类</param>
        /// <param name="owerId">附件组所属的记录ID,如属于某个主表记录的ID</param>
        /// <param name="userId">操作用户ID,当前登录用户</param>
        public void Init(string attachmentDir, string owerId, string userId)

由于附件有独立的存储模块,因此我们不需要为附件的上传以及数据库记录的存储做任何特殊的操作,只需要告诉附件它对应的记录GUID,并初始化它的目录位置即可。

该附件界面以下部分,可以使用在传统Winform中,也可以使用WCF的分布式应用程序中,还可以使用在Web开发里面,如我之前写的Web开发界面中关于附件上传的操作,利用的就是这些内容,只是界面需要重新处理而已。

里面的

以上就是Winform开发框架中附件管理模块的应用场景和使用代码的展示,希望大家多多建议,吸收更好的意见,做的更好。

我在上一篇随笔《
基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍
》中大概介绍了基于MVC的Web开发框架的权限控制总体思路。其中的权限控制就是分为“用户登录身份验证”、“控制器方法权限控制”、“界面元素权限控制”三种控制方式,可以为Web开发框架本身提供了很好用户访问控制和权限控制,使得用户界面呈现菜单、Web界面的按钮和内容、Action的提交控制,均能在总体权限功能分配和控制之下。

本篇文章主要细化这三个方面的介绍,重点介绍“控制器方法权限控制”、“界面元素权限控制”这两种权限控制方式。

1、用户登录控制

登录界面如下所示。

其中登录的前台页面代码如下所示,其中可以在登录界面接收验证码(如果必要的话)。

        //实现用户登录
        functionLoginUserInfo() {//获取单击用户登录按钮的事件
            $("#btnLogin").click(function() {//首先获取到要传递到控制器的参数,并且狗造成Json。UserName,UserPassword,Code
                var postData ={
UserName: $(
"#UserName").val(),
Password: $(
"#Password").val(),
Code: $(
"#Code").val()
};
//发送异步请求实现登录 ajax $.ajax({
url:
'/Login/CheckUser',
data: postData,
cache:
false,
async:
true,
type:
'post',
success:
function(data) {if (data == "OK") {
window.location.href
= "/Home/Index";

}
else{
alert(data);
window.location.href
= "/Login/Index";
}
}
});
});
}

用户登录的后台控制器方法如下所示:

        /// <summary>
        ///对用户登录的操作进行验证/// </summary>
        /// <param name="username">用户账号</param>
        /// <param name="password">用户密码</param>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        public ActionResult CheckUser(string username, string password, stringcode)
{
string result = "";bool codeValidated = true;if (this.TempData["ValidateCode"] != null)
{
codeValidated
= (this.TempData["ValidateCode"].ToString() ==code);
}
if (string.IsNullOrEmpty(username))
{
result
= "用户名不能为空";
}
else if (!codeValidated)
{
result
= "验证码输入有误";
}
else{string ip =GetClientIp();string macAddr = "";string identity = BLLFactory<WHC.Security.BLL.User>.Instance.VerifyUser(username, password, MyConstants.SystemType, ip, macAddr);if (!string.IsNullOrEmpty(identity))
{
UserInfo info
= BLLFactory<WHC.Security.BLL.User>.Instance.GetUserByName(username);if (info != null)
{
result
= "OK";
Session[
"UserInfo"] =info;
Session[
"Identity"] =info.Name.Trim();#region 取得用户的授权信息,并存储在Session中List<FunctionInfo> functionList = BLLFactory<Function>.Instance.GetFunctionsByUser(info.ID, MyConstants.SystemType);
Dictionary
<string, string> functionDict = new Dictionary<string, string>();foreach (FunctionInfo functionInfo infunctionList)
{
if (!string.IsNullOrEmpty(functionInfo.ControlID) && !functionDict.ContainsKey(functionInfo.ControlID))
{
functionDict.Add(functionInfo.ControlID, functionInfo.ControlID);
}
}
Session[
"Functions"] =functionDict;#endregion}
}
else{
result
= "用户名输入错误或者您已经被禁用";
}
}
returnContent(result);
}

从上面的代码,我们可以看到,在用户登录成功后,后台把用户信息、用户权限列表信息放到了Session里面,方便进行后面的权限控制。

然后当前端页面获得成功响应并切换到Home的Index视图前,后台会调用Home的控制器,把一些用户信息放到了ViewBag对象里面,并构造用户的相关菜单项目,代码如下所示。

    public classHomeController : BaseController
{
publicActionResult Index()
{
if (CurrentUser != null)
{
ViewBag.FullName
=CurrentUser.FullName;
ViewBag.Name
=CurrentUser.Name;

StringBuilder sb
= newStringBuilder();
List
<MenuInfo> menuList = BLLFactory<Menu>.Instance.GetTopMenu(MyConstants.SystemType);int i = 0;foreach (MenuInfo menuInfo inmenuList)
{
sb.Append(GetMenuItemString(menuInfo, i));
i
++;
}
ViewBag.HeaderScript
= sb.ToString();//一级菜单代码 }returnView();
}

2、控制器方法权限控制

我们知道,对页面的权限控制,可以分为前端控制和后台代码的控制,控制器方法的权限控制属于后台代码的控制。为了方便基类代码的权限控制,我们定义一个权限控制键的类,用来记录通用的增加、修改、删除、查看、列表、导出等传统控制元素,代码如下所示。

    /// <summary>
    ///定义常用功能的控制ID,方便基类控制器对用户权限的控制/// </summary>
[DataContract]
[Serializable]
public classAuthorizeKey
{
#region 常规功能控制ID /// <summary> ///新增记录的功能控制ID/// </summary> public string InsertKey { get; set; }/// <summary> ///更新记录的功能控制ID/// </summary> public string UpdateKey { get; set; }/// <summary> ///删除记录的功能控制ID/// </summary> public string DeleteKey { get; set; }/// <summary> ///查看列表的功能控制ID/// </summary> public string ListKey { get; set; }/// <summary> ///查看明细的功能控制ID/// </summary> public string ViewKey { get; set; }/// <summary> ///导出记录的功能控制ID/// </summary> public string ExportKey { get; set; }#endregion #region 常规权限判断 /// <summary> ///判断是否具有插入权限/// </summary> public bool CanInsert { get; set; }/// <summary> ///判断是否具有更新权限/// </summary> public bool CanUpdate { get; set; }/// <summary> ///判断是否具有删除权限/// </summary> public bool CanDelete { get; set; }/// <summary> ///判断是否具有列表权限/// </summary> public bool CanList { get; set; }/// <summary> ///判断是否具有查看权限/// </summary> public bool CanView { get; set; }/// <summary> ///判断是否具有导出权限/// </summary> public bool CanExport { get; set; }#endregion /// <summary> ///默认构造函数/// </summary> publicAuthorizeKey() { }/// <summary> ///常用构造函数/// </summary> public AuthorizeKey(string insert, string update, string delete, string view = "")
{
this.InsertKey =insert;this.UpdateKey =update;this.DeleteKey =delete;this.ViewKey =view;
}
}

有了这个实体类,我们就可以在控制器的基类
BaseController
里面实现一些控制逻辑了。首先我们在控制器每次执行方法前,都对权限进行一个转换,并把控制键存储到ViewBage里面,方便前端页面的控制,如下代码所示。

        /// <summary>
        ///重新基类在Action执行之前的事情/// </summary>
        /// <param name="filterContext">重写方法的参数</param>
        protected override voidOnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);//得到用户登录的信息 CurrentUser = Session["UserInfo"] asUserInfo;if (CurrentUser == null)
{
Response.Redirect(
"/Login/Index");//如果用户为空跳转到登录界面 }//设置授权属性,然后赋值给ViewBag保存 ConvertAuthorizedInfo();
ViewBag.AuthorizeKey =
AuthorizeKey;
}

其中ConvertAuthorizedInfo()函数是验证登陆用户是否具有相应的权限的。

        /// <summary>
        ///对AuthorizeKey对象里面的操作权限进行赋值,用于页面判断/// </summary>
        protected virtual voidConvertAuthorizedInfo()
{
//判断用户权限 AuthorizeKey.CanInsert =HasFunction(AuthorizeKey.InsertKey);
AuthorizeKey.CanUpdate
=HasFunction(AuthorizeKey.UpdateKey);
AuthorizeKey.CanDelete
=HasFunction(AuthorizeKey.DeleteKey);
AuthorizeKey.CanView
=HasFunction(AuthorizeKey.ViewKey);
AuthorizeKey.CanList
=HasFunction(AuthorizeKey.ListKey);
AuthorizeKey.CanExport
=HasFunction(AuthorizeKey.ExportKey);
}

其中BaseController的控制器基类还定义了判断用户是否有某些权限的逻辑,如果没有没有权限,就会抛出
自定义异常(MyDenyAccessException)
,代码如下。

        /// <summary>
        ///用于检查方法执行前的权限,如果未授权,返回MyDenyAccessException异常/// </summary>
        /// <param name="functionId"></param>
        protected virtual void CheckAuthorized(stringfunctionId)
{
if(!HasFunction(functionId))
{
string errorMessage = "您未被授权使用该功能,请重新登录测试或联系管理员进行处理。";throw newMyDenyAccessException(errorMessage);
}
}

有了上面的这些逻辑,我们在业务控制器基类(
BusinessController<B, T>
)里面,就可以实现对一些基本操作的API的权限控制了。

    /// <summary>
    ///本控制器基类专门为访问数据业务对象而设的基类/// </summary>
    /// <typeparam name="B">业务对象类型</typeparam>
    /// <typeparam name="T">实体类类型</typeparam>
    public class BusinessController<B, T>: BaseControllerwhere B : class
        where T : WHC.Framework.ControlUtil.BaseEntity, new()
{
/// <summary> ///插入指定对象到数据库中/// </summary> /// <param name="info">指定的对象</param> /// <returns>执行操作是否成功。</returns> public virtualActionResult Insert(T info)
{
//检查用户是否有权限,否则抛出MyDenyAccessException异常 base.CheckAuthorized(AuthorizeKey.InsertKey);bool result = false;if (info != null)
{
result
=baseBLL.Insert(info);
}
returnContent(result);
}
/// <summary> ///更新对象属性到数据库中/// </summary> /// <param name="info">指定的对象</param> /// <param name="id">主键ID的值</param> /// <returns>执行成功返回<c>true</c>,否则为<c>false</c></returns> public virtual ActionResult Update(stringid, FormCollection formValues)
{
//检查用户是否有权限,否则抛出MyDenyAccessException异常 base.CheckAuthorized(AuthorizeKey.UpdateKey);

T obj
=baseBLL.FindByID(id);if (obj != null)
{
//遍历提交过来的数据(可能是实体类的部分属性更新) foreach (string key informValues.Keys)
{
string value =formValues[key];
System.Reflection.PropertyInfo propertyInfo
=obj.GetType().GetProperty(key);if (propertyInfo != null)
{
try{//obj对象有key的属性,把对应的属性值赋值给它(从字符串转换为合适的类型)//如果转换失败,会抛出InvalidCastException异常 propertyInfo.SetValue(obj, Convert.ChangeType(value, propertyInfo.PropertyType), null);
}
catch{ }
}
}
}
bool result =baseBLL.Update(obj, id);returnContent(result);
}

3、界面元素权限控制

我们从上面那个Web开发框架的主界面图可以看到,里面对于某个特定的业务,增加、修改、、查看、删除等操作都放在了EasyUI的DataGrid工具栏里面了,为了动态控制用户能访问的界面按钮,我们需要结合用户权限集合进行界面呈现,首先我们把ToolBar放到一个层里面进行定义,如下代码所示。

        //实现对DataGird控件的绑定操作
function InitGrid(queryData) {
$(
'#grid').datagrid({ //定位到Table标签,Table标签的ID是grid url: '/Information/FindWithPager', //指向后台的Action来获取当前用户的信息的Json格式的数据 title: '通知公告',
iconCls:
'icon-view',
height:
650,
width: function () {
return document.body.clientWidth * 0.9 },//自动宽度 nowrap: true,
autoRowHeight:
true,
striped:
true,
collapsible:
true,
pagination:
true,
pageSize:
50,
pageList: [
50, 100, 200],
rownumbers:
true,//sortName: 'ID',//根据某个字段给easyUI排序 sortOrder: 'asc',
remoteSort:
false,
idField:
'ID',
queryParams: queryData,
//异步查询的参数 columns: [[
{ field:
'ck', checkbox: true }, //选择 { title: '标题', field: 'Title', width: 350, sortable: true},
{ title:
'编辑者', field: 'Editor', width: 80, sortable: true},
{ title:
'编辑时间', field: 'EditTime', width: 150, sortable: true},
{ title:
'附件', field: 'Attachment_GUID', width: 250, sortable: true}
]],
toolbar:
"#gridtoolbar",

然后在HTML里面添加gridtoolbar的层定义,作为easyUI的表格控件的工具条。由于使用了HTML辅助类来实现界面控件代码控制生成,因此已经可以达到了界面权限的控制了。使用这种HTML层定义的工具条定义方式,比通过脚本定义的工具条效果少了一个分隔线,其他的都还是一致的。

    <div id="gridtoolbar" style="padding: 5px; height: auto">
        <div style="margin-bottom: 5px">@if (@ViewBag.AuthorizeKey.CanInsert)
{
@Html.ActionLink(
"添加", null, null, new {onclick="ShowAddDialog()", data_options="iconCls:'icon-add', plain:true", @class = "easyui-linkbutton", href="javascript:void(0)"})
}
@if (@ViewBag.AuthorizeKey.CanUpdate)
{
@Html.ActionLink(
"修改", null, null, new {onclick="ShowEditOrViewDialog()", data_options="iconCls:'icon-edit', plain:true", @class = "easyui-linkbutton", href="javascript:void(0)"})
}
@if (@ViewBag.AuthorizeKey.CanDelete)
{
@Html.ActionLink(
"删除", null, null, new {onclick="Delete()", data_options="iconCls:'icon-remove', plain:true", @class = "easyui-linkbutton", href="javascript:void(0)"})
}
@if (@Html.HasFunction(
"Information/View"))
{
@Html.ActionLink(
"查看", null, null, new {onclick="ShowEditOrViewDialog('view')", data_options="iconCls:'icon-table', plain:true", @class = "easyui-linkbutton", href="javascript:void(0)"})
}
@Html.ActionLink(
"刷新", null, null, new {onclick="$('#grid').datagrid('reload');", data_options="iconCls:'icon-reload', plain:true", @class = "easyui-linkbutton", href="javascript:void(0)"})</div> </div>

上面使用了两种方式来判断用户的权限的,一种是使用
这种ViewBag对象的树形进行判断,如下所示。

@if (@ViewBag.AuthorizeKey.CanDelete)

还有一种是使用HTML辅助类的扩展方法进行判断,这种方法适用于一些非常规的权限控制集合的判断,如下所示

@if (@Html.HasFunction("Information/View"))

其中HTML辅助类方法是通过扩展静态方法进行实现,代码如下所示。

    public static classHtmlHelpers
{
public static bool HasFunction(this HtmlHelper helper, stringfunctionId)
{
returnPermission.HasFunction(functionId);
}
public static boolIsAdmin()
{
returnPermission.IsAdmin();
}
}

上面的界面控制方法,是通过控制界面代码的生成与否进行权限控制的,前面我们讲了,通过后台代码的控制器方法也是可以实现控制,而且是抛出自定义的错误,那么我们在使用Ajax方法调用的时候,也可以对这个错误信息进行友好显示,提示用户权限不足,前端页面操作代码如下。

        //绑定添加按钮的事件
        functionBindAddEvent() {
$(
"#btnAddOK").click(function() {//判断表单的信息是否通过验证 var validate = $("#ffAdd").form('validate');if (validate == false) {return false;
}
var postData = $("#ffAdd").serializeArray();
$.post(
"/Information/Insert", postData, function(data) {if (data = "true") {//添加成功 1.关闭弹出层,2.刷新DataGird $.messager.alert("提示", "添加成功");
$(
"#DivAdd").dialog("close");
$(
"#grid").datagrid("reload");
$(
"#ffAdd").form("clear");//本页面的类型为【通知公告】,固定不变 $("#Category").val("通知公告");
}
else{
$.messager.alert(
"提示", "添加失败,请您检查");
}
}).error(
function () {
$.messager.alert("提示", "您未被授权使用该功能,请联系管理员进行处理。", 'warning'
);
});

});
}

以上就是我对Web开发框架中的权限控制几个方面的思路和代码,希望抛砖引玉,获得大家更好的反馈和支持。

基于MVC4+EasyUI的Web开发框架的系列文章:

基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍


基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计

基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用

基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用

基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍

基于MVC4+EasyUI的Web开发框架形成之旅--基类控制器CRUD的操作

基于MVC4+EasyUI的Web开发框架形成之旅--权限控制

基于MVC4+EasyUI的Web开发框架经验总结(1)-利用jQuery Tags Input 插件显示选择记录

基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面

基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据

基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts

基于MVC4+EasyUI的Web开发框架经验总结(5)--使用HTML编辑控件CKEditor和CKFinder

基于MVC4+EasyUI的Web开发框架经验总结(6)--在页面中应用下拉列表的处理

基于MVC4+EasyUI的Web开发框架经验总结(7)--实现省份、城市、行政区三者联动

基于MVC4+EasyUI的Web开发框架经验总结(8)--实现Office文档的预览

基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作

基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出

基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码

基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度

基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作