索引
【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引
简述
今天我们来做权限的管理,这篇比较多 希望新手朋友慢慢消化
项目准备
我们用的工具是:VS 2013 + SqlServer 2012 + IIS7.5
希望大家对ASP.NET MVC有一个初步的理解,理论性的东西我们不做过多解释,有些地方不理解也没关系,会用就行了,用的多了,用的久了,自然就理解了。
项目开始
一、新建权限控制器 继承 基础控制器
1、我们在Areas/SysManage/Controllers 下新建一个控制器 叫PermissionController
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 namespace WebPage.Areas.SysManage.Controllers 8 { 9 public class PermissionController : Controller 10 { 11 // GET: SysManage/Permission 12 public ActionResult Index() 13 { 14 return View(); 15 } 16 } 17 }
2、我们让PermissionController 继承基础控制器 BaseController 这里需要添加引用 using WebPage.Controllers
3、我们添加需要的接口声明,这里需要添加引用 using Service.IService
1 public class PermissionController : BaseController 2 { 3 #region 声明容器 4 ///5 /// 系统管理 6 /// 7 ISystemManage SystemManage { get; set; } 8 /// 9 /// 权限管理 10 /// 11 IPermissionManage PermissionManage { get; set; } 12 /// 13 /// 模块管理 14 /// 15 IModuleManage ModuleManage { get; set; } 16 #endregion 17 18 public ActionResult Index() 19 { 20 return View(); 21 } 22 }
4、千万不要忘记 我们添加xml的注入配置 (Config/Controllers.xml)
配置注入:
完整代码:
1 "1.0" encoding="utf-8" ?> 2"http://www.springframework.net"> 3 Spring注入控制器,容器指向Service层封装的接口 4 5 6 <object type="WebPage.Areas.SysManage.Controllers.HomeController,WebPage" singleton="false"> 7"ModuleManage" ref="Service.Module"/> 8 object> 9 10 <object type="WebPage.Areas.SysManage.Controllers.AccountController,WebPage" singleton="false"> 11 "UserManage" ref="Service.User"/> 12 object> 13 14 <object type="WebPage.Areas.SysManage.Controllers.ModuleController,WebPage" singleton="false"> 15 "ModuleManage" ref="Service.Module"/> 16 "PermissionManage" ref="Service.Permission"/> 17 "SystemManage" ref="Service.System"/> 18 object> 19 20 <object type="WebPage.Areas.SysManage.Controllers.PermissionController,WebPage" singleton="false"> 21 "ModuleManage" ref="Service.Module"/> 22 "SystemManage" ref="Service.System"/> 23 "PermissionManage" ref="Service.Permission"/> 24 object> 25 26
OK,这样 控制器和容器声明 我们就完成了~
二、添加侧栏选择
我们把权限管理的页面 分左右两栏 左栏是所有的模块 右栏是权限
效果是这样的:
1、我们新建一个Home视图页 这个视图页的作用就是 左右分栏 并添加权限验证
2、我们转到视图页 添加样式和布局 这里前端各人有个人的写法 我就不详细介绍了
我们先来做左栏 加载系统模块,我们添加一个下拉菜单,让用户选择操作的系统
1 <select id="sel-system" > 2 3 select>
这里的下拉选项,我们是应该输出到页面上的,所以 我们在 视图Home 下面获取这个系统集合
1 ///2 /// 权限管理 默认页面 3 /// 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")] 6 public ActionResult Home() 7 { 8 try 9 { 10 //获取用户可操作的系统列表 11 ViewData["Systemlist"] = this.SystemManage.LoadSystemInfo(CurrentUser.System_Id); 12 } 13 catch(Exception e) 14 { 15 WriteLog(Common.Enums.enumOperator.Select, "对模块权限按钮的管理加载导航页:", e); 16 } 17 18 return View(); 19 }
我们修改一下select 的 option 通过接收 后台的ViewData["Systemlist"] 输出 下拉选项
1 <select id="sel-system"> 2 @{ 3 foreach (var item in ViewData["Systemlist"] as dynamic) 4 { 5 6 } 7 } 8 select>
然后就是树形菜单了,以前用的是jquery.ztree.core-3.5 今天换一换 用 jstree,我们看一下jstree json的格式
1 $('#using_json_2').jstree({ 'core' : { 2 'data' : [ 3 { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" }, 4 { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }, 5 { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" }, 6 { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }, 7 ] 8 } });
当然,这是默认关闭的 展开呢 就是在属性里加上"state": { "opened": true },我要关闭的,我就不加这个了,那么按照这个格式,我们写一个方法,返回我们模块的json数据
这个方法 我们起名叫做 GetTree
1 ///2 /// 获取模块树形菜单 3 /// 4 public ActionResult GetTree() 5 { 6 var json = new JsonHelper() { Msg = "Success", Status = "y" }; 7 8 //获取系统ID 9 var sysId = Request.Form["sysId"]; 10 11 //判断系统ID是否传入 12 if (string.IsNullOrEmpty(sysId)) 13 { 14 json.Status = "n"; 15 json.Msg = "获取模块失败!"; 16 return Json(json); 17 } 18 try 19 { 20 //获取系统下的模块列表 按照 SHOWORDER字段 升序排列 21 var query = this.ModuleManage.LoadAll(p => p.FK_BELONGSYSTEM == sysId).OrderBy(p => p.SHOWORDER).ToList(); 22 23 //这里就是按照jsTree的格式 输出一下 模块信息 24 var result = query.Select(m => new 25 { 26 id = m.ID, 27 parent = m.PARENTID>0?m.PARENTID.ToString():"#", 28 text = m.NAME, 29 icon = m.LEVELS == 0 ? "fa fa-circle text-danger" : "fa fa-circle text-navy" 30 }).ToList(); 31 32 json.Data = result; 33 } 34 catch (Exception e) 35 { 36 json.Status = "n"; 37 json.Msg = "服务器忙,请稍后再试!"; 38 WriteLog(Common.Enums.enumOperator.Select, "权限管理,获取模块树:", e); 39 } 40 return Json(json); 41 }
再回到我们Home视图页,用jstree呢 首先我们要引入它的css
然后引入它的js
我们在页面中新建一个DIV 来存放这个树形菜单
写个简洁的ajax获取数据 并且填充给上面那个DIV
$.post("/permission/gettree", { sysId: $("#sel-system").val() }, function (res) { if (res.Status == "y") { $("#ModuleTree").jstree({ "core": { "multiple": false, "data": res.Data } }).on("changed.jstree", function (e, data) { alert(data.instance.get_node(data.selected).text); }); } else { dig.error(res.Msg); } });
因为我们这个是要选择系统 然后列出系统下的树形菜单的,所以我们把这个ajax方法 写到一个function方法里
1 function ShowMoudle() 2 { 3 $("#ModuleTree").data('jstree', false).empty(); 4 $.post("/permission/gettree", { sysId: $("#sel-system").val() }, function (res) { 5 if (res.Status == "y") { 6 $("#ModuleTree").jstree({ 7 "core": { "multiple": false, "data": res.Data } 8 }).on("changed.jstree", function (e, data) { 9 alert(data.instance.get_node(data.selected).text); 10 }); 11 } 12 else { 13 dig.error(res.Msg); 14 } 15 }); 16 }
页面打开和系统下拉菜单select 更改的时候 加载这个菜单,下面是完整的
OK,是不是出来了
那接下来,我们要点击模块之后 操作模块的权限,我们列出了树形菜单,上面做了一个方法就是 选中 菜单的时候 弹出 菜单的text
我们要做的是,点击菜单的是后展示这个模块的权限,所以,我们先新建一个权限列表页
三、权限管理
1、我们用Index这个视图 来展示模块列表页,我们给Index 添加权限验证 也是 查看
1 ///2 /// 权限管理 权限列表 3 /// 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")] 6 public ActionResult Index() 7 { 8 return View(); 9 }
2、好的习惯,try catch
1 ///2 /// 权限管理 权限列表 3 /// 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")] 6 public ActionResult Index() 7 { 8 try 9 { 10 return View(); 11 } 12 catch (Exception e) 13 { 14 WriteLog(Common.Enums.enumOperator.Select, "对模块权限按钮的管理加载主页:", e); 15 throw e.InnerException; 16 } 17 }
3、权限列表应该是某一个模块的权限列表,因此,我们要接收一个模块ID的参数(如何传递的,待会再修改我们树形菜单的js,这里先不管)
1 ///2 /// 权限管理 权限列表 3 /// 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")] 6 public ActionResult Index() 7 { 8 try 9 { 10 //获取模块ID 11 var moduleId = Request.QueryString["moduleId"] ?? (Request["moduleId"] ?? ""); 12 13 //如果模块ID不为空或NULL 14 if(!string.IsNullOrEmpty(moduleId)) 15 { 16 17 } 18 19 return View(); 20 } 21 catch (Exception e) 22 { 23 WriteLog(Common.Enums.enumOperator.Select, "对模块权限按钮的管理加载主页:", e); 24 throw e.InnerException; 25 } 26 }
4、如果ID不为空或NULL 我们 模块信息和模块的权限列表 传递给视图页
1 ///2 /// 权限管理 权限列表 3 /// 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")] 6 public ActionResult Index() 7 { 8 try 9 { 10 //获取模块ID 11 var moduleId = Request.QueryString["moduleId"] ?? (Request["moduleId"] ?? ""); 12 13 //如果模块ID不为空或NULL 14 if(!string.IsNullOrEmpty(moduleId)) 15 { 16 //把模块ID转为Int 17 int module_Id = int.Parse(moduleId); 18 19 //模块信息 20 var module = this.ModuleManage.Get(p => p.ID == module_Id); 21 22 //绑定列表 23 var query = this.PermissionManage.LoadAll(p => p.MODULEID == module.ID); 24 25 //关键字查询 26 if (!string.IsNullOrEmpty(keywords)) 27 { 28 query = query.Where(p => p.NAME.Contains(keywords)); 29 } 30 //输出结果 31 var result = query.OrderBy(p => p.SHOWORDER).ToList(); 32 33 ViewBag.Search = base.keywords; 34 35 ViewBag.Module = module; 36 37 return View(result); 38 } 39 40 return View(); 41 } 42 catch (Exception e) 43 { 44 WriteLog(Common.Enums.enumOperator.Select, "对模块权限按钮的管理加载主页:", e); 45 throw e.InnerException; 46 } 47 }
5、我们在视图页 输出信息 (注意一下,因为我们没有添加初始化权限的初始数据 所以 初始化权限 按钮是不展示的)
1 @{ 2 Layout = "~/Views/Shared/_Layout.cshtml"; 3 } 4 @model List5 class="wrapper wrapper-content animated fadeInRight"> 689 @section scripts{ 90 92 }class="row"> 788class="col-sm-12"> 887class="ibox float-e-margins"> 986class="ibox-title"> 10 @{ 11 if (ViewBag.Module != null) 12 { 13 Domain.SYS_MODULE module = ViewBag.Module as Domain.SYS_MODULE; 14 if (module != null) 15 { 1637@(module.NAME) - 权限
17 @Html.Hidden("moduleId", module.ID) 18 @Html.Hidden("moduleType", module.MODULETYPE) 19 } 20 21class="ibox-tools"> 22 class="btn btn-primary btn-xs p310" id="reset" action="reset">class="im-plus"> 初始化权限 23 class="btn btn-primary btn-xs p210" id="insert" action="add">class="fa fa-plus-circle fa-fw"> 创建新分类 24 class="btn btn-warning btn-xs p210" id="modify" action="edit">class="fa fa-pencil fa-fw"> 编辑 25 class="btn btn-danger btn-xs p210" id="delete" action="remove">class="fa fa-trash-o fa-fw"> 删除 26 class="reload-link" style="color: #c4c4c4" href="javascript:dig.reload()" data-toggle="tooltip" data-placement="left" title="刷新"> 27 class="fa fa-repeat fa-lg"> 28 2930 } 31 else 32 { 33权限管理
34 } 35 } 36class="ibox-content"> 38 @using (Ajax.BeginForm("Index", null, new AjaxOptions() { }, new { @id = "form1", @class = "form-horizontal", @method = "get" })) 39 { 4085class="row"> 4152 } 53class="col-sm-9"> 4243class="col-sm-3"> 4451class="input-group"> 45 @Html.TextBox("Search", null, new { @class = "input-sm form-control", @placeholder = "请输入查询关键词" }) 46 class="input-group-btn"> 47 48 4950class="row"> 5484"dataTable" class="table table-striped table-bordered table-hover dataTables-example" style="text-align:center;"> 55 56
8357 63 64 65 @{ 66 if (Model != null) 67 { 68 @Html.Hidden("percount", Model.Count) 69 foreach (var item in Model) 70 { 71class="tn" style="width: 50px !important">"checkall" class="icheck_box" type="checkbox" value=""> 58所属系统 59权限动作 60图标 61顺序 6272 78 } 79 } 80 } 81 82class="tn">"checkbox_name" class="icheck_box" type="checkbox" value="@item.ID"> 73"javascript:modify('@item.ID')" listaction="detail"> @item.NAME 74@item.PERVALUE 75"color:#1ab394; ">class="@item.ICON"> 76@item.SHOWORDER 77
6、我们再回到Home视图页,添加右栏,我们添加一个iframe
iFrameHeight()是设置Iframe的高度,我们把这个方法写在home视图里
1 function iFrameHeight() { 2 var ifm = document.getElementById("DeployBase"); 3 var subWeb = document.frames ? document.frames["DeployBase"].document : ifm.contentDocument; 4 if (ifm != null && subWeb != null) { 5 ifm.height = subWeb.body.scrollHeight + 30; 6 } 7 }
7、我们来修改一下树形菜单的 选中节点的方法 把模块的ID传递给Iframe
OK,到这里 我们 Home应该是完成了,下面就是 权限的添加、修改、删除了
四、权限的 添加、修改、删除 (这个跟上一篇模块基本是一样的 我就不详细解释了,只是有些判断的地方 我给大家看下)
1、我们创建个视图 Detail
1 ///2 /// 加载权限详情 3 /// 4 /// 5 /// 6 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "Detail")] 7 public ActionResult Detail(int? id) 8 { 9 try 10 { 11 var _entity = this.PermissionManage.Get(p => p.ID == id) ?? new Domain.SYS_PERMISSION(); 12 13 //获取模块ID 14 var moduleId = Request.QueryString["moduleId"]; 15 16 if (!string.IsNullOrEmpty(moduleId)) 17 { 18 int newmoduleid = int.Parse(moduleId); 19 _entity.MODULEID = newmoduleid; 20 } 21 22 return View(_entity); 23 } 24 catch (Exception e) 25 { 26 WriteLog(Common.Enums.enumOperator.Select, "对模块权限按钮的管理加载详情:", e); 27 throw e.InnerException; 28 } 29 }
2、这里呢,我们要获取权限操作的集合,传递给视图页 供用户选择(当然用户可以自定义权限,只是我们添加一部分常用的权限 方便用户)
我们要用到表SYS_CODE大家可能已经有这个表了,但是没有数据 我给大家一些默认数据
1 USE [wkmvc_db] 2 GO 3 /****** Object: Table [dbo].[SYS_CODE] Script Date: 2016/6/1 17:37:41 ******/ 4 SET ANSI_NULLS ON 5 GO 6 SET QUOTED_IDENTIFIER ON 7 GO 8 CREATE TABLE [dbo].[SYS_CODE]( 9 [ID] [int] IDENTITY(1,1) NOT NULL, 10 [CODETYPE] [nvarchar](50) NULL, 11 [NAMETEXT] [nvarchar](200) NULL, 12 [CODEVALUE] [nvarchar](100) NULL, 13 [SHOWORDER] [int] NULL, 14 [ISCODE] [int] NULL, 15 [REMARK] [nvarchar](2000) NULL, 16 [CREATEDATE] [datetime] NULL, 17 [CREATEUSER] [nvarchar](36) NULL, 18 [UPDATEDATE] [datetime] NULL, 19 [UPDATEUSER] [nvarchar](36) NULL, 20 [PARENTID] [int] NULL, 21 CONSTRAINT [PK_SYS_CODE] PRIMARY KEY CLUSTERED 22 ( 23 [ID] ASC 24 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 25 ) ON [PRIMARY] 26 27 GO 28 SET IDENTITY_INSERT [dbo].[SYS_CODE] ON 29 30 GO 31 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (1, N'ROLEVALUE', N'删除', N'Remove', 4, 1, N'删除所用到的权限值', CAST(0x0000A57500A49432 AS DateTime), N'管理员', CAST(0x0000A57500A49432 AS DateTime), N'管理员', 0) 32 GO 33 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (2, N'ROLEVALUE', N'导出', N'Export', 5, 1, N'导出所用到的权限值', CAST(0x0000A57500A49437 AS DateTime), N'管理员', CAST(0x0000A57500A49437 AS DateTime), N'管理员', 0) 34 GO 35 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (3, N'ROLEVALUE', N'导入', N'Import', 6, 1, N'导入所用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 36 GO 37 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (4, N'ROLEVALUE', N'审核', N'Audit', 7, 1, N'审核用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 38 GO 39 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (5, N'ROLEVALUE', N'回复', N'Reply', 8, 1, N'回复用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 40 GO 41 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (6, N'ROLEVALUE', N'分配', N'Allocation', 9, 1, N'分配用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 42 GO 43 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (7, N'ROLEVALUE', N'选择', N'Select', 10, 1, N'选择用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 44 GO 45 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (8, N'ROLEVALUE', N'上传', N'Upload', 11, 1, N'上传用到的权限值', CAST(0x0000A57500A49438 AS DateTime), N'管理员', CAST(0x0000A57500A49438 AS DateTime), N'管理员', 0) 46 GO 47 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (9, N'ROLEVALUE', N'下载', N'Download', 12, 1, N'下载用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 48 GO 49 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (10, N'ROLEVALUE', N'列表', N'List', 1, 1, N'列表用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 50 GO 51 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (14, N'ROLEVALUE', N'查看', N'View', 0, 1, N'查看所用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 52 GO 53 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (15, N'ROLEVALUE', N'详情', N'Detail', 1, 1, N'详情所用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 54 GO 55 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (16, N'ROLEVALUE', N'添加', N'Add', 2, 1, N'添加所用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 56 GO 57 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (17, N'ROLEVALUE', N'编辑', N'Edit', 3, 1, N'编辑用到的权限值', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 58 GO 59 INSERT [dbo].[SYS_CODE] ([ID], [CODETYPE], [NAMETEXT], [CODEVALUE], [SHOWORDER], [ISCODE], [REMARK], [CREATEDATE], [CREATEUSER], [UPDATEDATE], [UPDATEUSER], [PARENTID]) VALUES (18, N'ROLEVALUE', N'发布', N'Publish', 14, 1, N'发布所需权限', CAST(0x0000A57500A49439 AS DateTime), N'管理员', CAST(0x0000A57500A49439 AS DateTime), N'管理员', 0) 60 GO 61 62 SET IDENTITY_INSERT [dbo].[SYS_CODE] OFF 63 GO 64 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主键ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'ID' 65 GO 66 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'代码类型' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'CODETYPE' 67 GO 68 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'代码显示文本' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'NAMETEXT' 69 GO 70 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'代码值' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'CODEVALUE' 71 GO 72 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'排序值' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'SHOWORDER' 73 GO 74 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否为编码(0否1是)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'ISCODE' 75 GO 76 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'备注' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'REMARK' 77 GO 78 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'CREATEDATE' 79 GO 80 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建者' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'CREATEUSER' 81 GO 82 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'修改时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'UPDATEDATE' 83 GO 84 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'修改者' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'UPDATEUSER' 85 GO 86 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'父级ID(使用时注意ISCODE为0)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SYS_CODE', @level2type=N'COLUMN',@level2name=N'PARENTID' 87 GO
3、我们在Service类库IService/SysManage下面添加一个接口 ICodeManage
1 using System.Collections.Generic; 2 using System.Linq; 3 4 namespace Service.IService 5 { 6 ///7 /// Service层代码配置接口 8 /// add yuangang by 2015-05-22 9 /// 10 public interface ICodeManage : IRepository 11 { 12 /// 13 /// 根据编码类型获取编码集合 14 /// 15 /// 编码类型 16 /// 编码值 17 List GetCode(string codetype, params string[] codevalue); 18 /// 19 /// 通过字典查询字典指向的编码集合 20 /// 21 IQueryable GetDicType(); 22 /// 23 /// 根据字典ID与类型获取一条数据 24 /// 25 string GetCodeByID(int id, string codetype); 26 /// 27 /// 根据字典编码值与类型获取一条数据 28 /// 29 string GetCodeNameByCodeValue(string codeType, string codevalue); 30 } 31 }
4、我们在Service类库ServiceImp/SysManage下面它的实现类 CodeManage
1 using Common; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Data.Entity; 7 8 namespace Service.ServiceImp 9 { 10 ///11 /// Service层代码配置 12 /// add yuangang by 2015-05-22 13 /// 14 public class CodeManage : RepositoryBase , IService.ICodeManage 15 { 16 /// 17 /// 根据编码类型获取编码集合 18 /// 19 public List GetCode(string codetype, params string[] codevalue) 20 { 21 var predicate = PredicateBuilder.True (); 22 predicate = predicate.And(p => p.CODETYPE == codetype); 23 if (codevalue != null && codevalue.Length > 0) 24 { 25 var str = codevalue.ToList(); 26 predicate = predicate.And(p => str.Contains(p.CODEVALUE)); 27 } 28 return this.LoadAll(predicate).OrderBy(p => p.SHOWORDER).ToList(); 29 } 30 31 /// 32 /// 通过系统字典获取编码值 33 /// 34 public IQueryable GetDicType() 35 { 36 Dictionary<string, string> code = Common.Enums.ClsDic.DicCodeType; 37 string dic = code.Aggregate(string.Empty, (current, item) => current + (item.Value + ",")).TrimEnd(','); 38 return this.LoadAll(p => dic.Contains(p.CODETYPE)).OrderBy(p => p.SHOWORDER); 39 } 40 41 /// 42 /// 根据字典ID与类型获取一条数据 43 /// 44 public string GetCodeByID(int id, string codetype) 45 { 46 return (this.Get(p => p.ID == id) ?? new Domain.SYS_CODE()).NAMETEXT; 47 } 48 49 /// 50 /// 根据字典编码值与类型获取一条数据 51 /// 52 public string GetCodeNameByCodeValue(string codeType, string codevalue) 53 { 54 if (string.IsNullOrEmpty(codevalue)) 55 return ""; 56 var entity = this.Get(p => p.CODETYPE == codeType && p.CODEVALUE == codevalue); 57 if (entity == null) return ""; 58 return entity.NAMETEXT; 59 } 60 } 61 }
注意:这里我们用到了一个 谓词表达式构建器
我把这个类 贴给大家,大家放到Common类库下面就可以
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 using System.Text; 6 7 namespace Common 8 { 9 ///10 /// 谓词表达式构建器 11 /// add yuangang by 2015-09-08 12 /// 13 public static class PredicateBuilder 14 { 15 /// 16 /// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效 17 /// 18 /// 19 /// 20 public static Expression bool>> True () { return f => true; } 21 22 /// 23 /// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效 24 /// 25 /// 26 /// 27 public static Expression bool>> False () { return f => false; } 28 29 public static Expression bool>> Or (this Expression bool>> expr1, 30 Expression bool>> expr2) 31 { 32 return expr1.Compose(expr2, Expression.Or); 33 } 34 35 public static Expression bool>> And (this Expression bool>> expr1, 36 Expression bool>> expr2) 37 { 38 return expr1.Compose(expr2, Expression.And); 39 } 40 public static Expression Compose (this Expression first, Expression second, Func merge) 41 { 42 // build parameter map (from parameters of second to parameters of first) 43 var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); 44 45 // replace parameters in the second lambda expression with parameters from the first 46 var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); 47 48 // apply composition of lambda expression bodies to parameters from the first expression 49 return Expression.Lambda (merge(first.Body, secondBody), first.Parameters); 50 } 51 } 52 public class ParameterRebinder : ExpressionVisitor 53 { 54 private readonly Dictionary map; 55 56 public ParameterRebinder(Dictionary map) 57 { 58 this.map = map ?? new Dictionary (); 59 } 60 61 public static Expression ReplaceParameters(Dictionary map, Expression exp) 62 { 63 return new ParameterRebinder(map).Visit(exp); 64 } 65 66 protected override Expression VisitParameter(ParameterExpression p) 67 { 68 ParameterExpression replacement; 69 if (map.TryGetValue(p, out replacement)) 70 { 71 p = replacement; 72 } 73 return base.VisitParameter(p); 74 } 75 } 76 }
5、我们在Service类库下的Config/Service.xml添加一下配置
1 2 <object id="Service.Code" type="Service.ServiceImp.CodeManage,Service" singleton="false"> 3 object>
6、别忘了在WebPage/Config/Controllers.xml里注入一下
7、我们在PermissionController 控制器里 声明一下这个接口
8、我们修改一下 Detail 视图,获取一下 权限的预置编码
9、修改 Detail视图页 展示权限信息 创建 添加修改 表单
1 @{ 2 Layout = "~/Views/Shared/_Layout.cshtml"; 3 } 4 @model Domain.SYS_PERMISSION 5 10 @using (Ajax.BeginForm("Save", null, new AjaxOptions() 11 { 12 HttpMethod = "Post", 13 OnBegin = "SubAjax.Loading", 14 OnComplete = "SubAjax.Complate", 15 OnFailure = "SubAjax.Failure", 16 OnSuccess = "SubAjax.Success" 17 }, 18 new { @class = "form-horizontal dig-from", @role = "form" })) 19 { 20 @Html.HiddenFor(p => p.ID) 21 @Html.HiddenFor(p => p.MODULEID) 22class="wrapper wrapper-content animated fadeInUp"> 2395 } 96 @section scripts{ 97 127 }class="row"> 2494class="ibox-detail-title"> 25 class="fa fa-pencil-square-o">添加/修改权限 2627class="ibox-content"> 2893class="form-group"> 29 3034class="col-sm-8"> 31 @Html.TextBoxFor(p => p.NAME, new { @class = "form-control", @id = "modulename", @placeholder = "请输入权限名称", @datatype = "*", @nullmsg = "请输入权限名称!", @errormsg = "请输入权限名称!" }) 3233class="hr-line-dashed">35class="row"> 3664class="col-sm-6 b-r"> 3756class="form-group"> 38 3955class="col-sm-8"> 40 <select id="PERVALUE" name="PERVALUE" class="form-control input-s-sm"> 41 42 @{ 43 var per = ViewData["PresetValue"] as List54; 44 if (per != null && per.Count > 0) 45 { 46 foreach (var item in per) 47 { 48 49 } 50 } 51 } 52 select> 53 class="col-sm-6"> 5763class="form-group"> 5862class="col-sm-12"> 59 @Html.TextBox("NEXTPERVALUE", "", new { @class = "form-control input-s-sm" }) 6061class="hr-line-dashed">65class="form-group"> 66 6780class="col-sm-8"> 68 "icon" class="form-control input-s-sm"> 69 @Html.Hidden("ICON", Model.ICON) 70 class="btn btn-primary btn-xs">class="@Model.ICON"> 71 74 77 7879class="hr-line-dashed">81class="form-group"> 82 8387class="col-sm-8"> 84 @Html.TextBoxFor(p => p.SHOWORDER, new { @class = "form-control", @placeholder = "请输入显示顺序", @datatype = "n1-5", @nullmsg = "请输入显示顺序!", @errormsg = "显示顺序只能是数字!" }) 8586class="hr-line-dashed">88class="text-center"> 89 90 9192
10、保存权限(这个跟模块管理也是一样的流程,我直接把代码贴给大家)
1 ///2 /// 保存权限 3 /// 4 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "Add,Edit")] 5 public ActionResult Save(Domain.SYS_PERMISSION entity) 6 { 7 bool isEdit = false; 8 JsonHelper json = new JsonHelper() { Msg = "保存权限成功", Status = "n" }; 9 try 10 { 11 if (entity != null) 12 { 13 if (System.Text.Encoding.GetEncoding("gb2312").GetBytes(entity.NAME.Trim()).Length > 50) 14 { 15 json.Msg = "权限的名称长度不能超过50个字符"; 16 return Json(json); 17 } 18 entity.ICON = Request.Form["ICON"]; 19 var nextpervalue = Request.Form["NEXTPERVALUE"]; 20 if (!string.IsNullOrEmpty(nextpervalue)) 21 { 22 if (!Regex.IsMatch(nextpervalue, @"^[A-Za-z0-9]{1,20}$")) 23 { 24 json.Msg = "权限值只能以英文数字组成,长度不能超过20个字符"; 25 return Json(json); 26 } 27 entity.PERVALUE = nextpervalue; 28 } 29 //添加 30 if (entity.ID <= 0) 31 { 32 entity.CREATEDATE = DateTime.Now; 33 entity.UPDATEDATE = DateTime.Now; 34 entity.UPDATEUSER = this.CurrentUser.Name; 35 entity.CREATEUSER = this.CurrentUser.Name; 36 } 37 else //编辑 38 { 39 entity.UPDATEUSER = this.CurrentUser.Name; 40 entity.UPDATEDATE = DateTime.Now; 41 isEdit = true; 42 } 43 //同一模块下权限不能重复 44 if (!this.PermissionManage.IsExist(p => p.NAME.Equals(entity.NAME) && p.ID != entity.ID && p.MODULEID == entity.MODULEID)) 45 { 46 if (PermissionManage.SaveOrUpdate(entity, isEdit)) 47 { 48 json.Status = "y"; 49 } 50 else 51 { 52 json.Msg = "保存失败"; 53 } 54 } 55 else 56 { 57 json.Msg = "权限" + entity.NAME + "同一模块下已存在,不能重复添加"; 58 } 59 } 60 else 61 { 62 json.Msg = "未找到要保存的权限记录"; 63 } 64 if (isEdit) 65 { 66 WriteLog(Common.Enums.enumOperator.Edit, "修改权限,结果:" + json.Msg, Common.Enums.enumLog4net.INFO); 67 } 68 else 69 { 70 WriteLog(Common.Enums.enumOperator.Add, "添加权限,结果:" + json.Msg, Common.Enums.enumLog4net.INFO); 71 } 72 } 73 catch (Exception e) 74 { 75 json.Msg = "保存权限发生内部错误!"; 76 WriteLog(Common.Enums.enumOperator.None, "对模块权限按钮的管理保存权限:", e); 77 } 78 return Json(json); 79 }
11、删除权限 同上
////// 删除权限 /// [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "Remove")] public ActionResult Delete(string idList) { var json = new JsonHelper() { Msg = "删除权限成功", Status = "n" }; try { if (!string.IsNullOrEmpty(idList)) { var idList1 = idList.Trim(',').Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(p => int.Parse(p)).ToList(); //判断查找角色是否调用 if (!this.RolePermissionManage.IsExist(p => idList1.Any(e => e == p.PERMISSIONID))) { //判断查找用户是否调用 if (!this.UserPermissionManage.IsExist(p => idList1.Any(e => e == p.FK_PERMISSIONID))) { this.PermissionManage.Delete(p => idList1.Any(e => e == p.ID)); json.Status = "y"; } else { json.Msg = "有用户正在使用该权限,不能删除!"; } } else { json.Msg = "有角色正在使用该权限,不能删除!"; } } else { json.Msg = "未找到要删除的权限记录"; } WriteLog(Common.Enums.enumOperator.Remove, "删除权限,结果:" + json.Msg, Common.Enums.enumLog4net.WARN); } catch (Exception e) { json.Msg = e.InnerException.Message; WriteLog(Common.Enums.enumOperator.Remove, "对模块权限按钮的管理删除权限:", e); } return Json(json); }
需要注意的是,我们在删除权限的时候,需要判断 角色是否调用了权限、用户是否调用了权限,所以 我们要再声明两个接口
注意注入:
UserPermissionManage 这个有了,但是RolePermissionManage 我们貌似没做,上面讲过了 添加CodeManage 接口实现类和配置,都是一样的 我把接口和实现类贴给大家,大家尝试一下 自己添加
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Service.IService 7 { 8 ///9 /// Service层角色授权关系接口 10 /// add yuangang by 2015-05-22 11 /// 12 public interface IRolePermissionManage : IRepository 13 { 14 /// 15 /// 保存角色权限 16 /// 17 /// 角色ID 18 /// 权限字符串 19 /// 系统ID 20 /// 21 bool SetRolePermission(int roleId, string newper, string sysId); 22 } 23 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Service.IService; 6 7 namespace Service.ServiceImp 8 { 9 ///10 /// Service层角色授权关系接口 11 /// add yuangang by 2015-05-22 12 /// 13 public class RolePermissionManage : RepositoryBase , IService.IRolePermissionManage 14 { 15 IPermissionManage PermissionManage { get; set; } 16 /// 17 /// 保存角色权限 18 /// 19 public bool SetRolePermission(int roleId, string newper, string sysId) 20 { 21 try 22 { 23 //1、获取当前系统的模块ID集合 24 var permissionId = this.PermissionManage.GetPermissionIdBySysId(sysId).Cast<int>().ToList(); 25 //2、获取角色权限,是否存在,存在即删除,只删除当前选择的系统 26 if (this.IsExist(p => p.ROLEID == roleId && permissionId.Any(e => e == p.PERMISSIONID))) 27 { 28 //3、删除角色权限 29 this.Delete(p => p.ROLEID == roleId && permissionId.Any(e => e == p.PERMISSIONID)); 30 } 31 //4、添加角色权限 32 if (string.IsNullOrEmpty(newper)) return true; 33 //Trim 保证数据安全 34 var str = newper.Trim(',').Split(','); 35 foreach (var per in str.Select(t => new Domain.SYS_ROLE_PERMISSION() 36 { 37 PERMISSIONID = int.Parse(t), 38 ROLEID = roleId 39 })) 40 { 41 this.dbSet.Add(per); 42 } 43 //5、Save 44 return this.Context.SaveChanges() > 0; 45 } 46 catch (Exception e) { throw e.InnerException; } 47 } 48 } 49 }
OK,====,好像还有个初始化权限,在Index视图页 我们有个ajax 初始化权限,我们在PermissionController 控制器里新建个初始化权限的方法 验证权限是Reset
1 ///2 /// 初始化权限,默认增删改查详情 3 /// 模块ID 4 /// 5 [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "Reset")] 6 public ActionResult Reset(string id) 7 { 8 var json = new JsonHelper() { Status = "n", Msg = "初始化完毕" }; 9 try 10 { 11 //判断模块ID 是否符合规范 12 if (string.IsNullOrEmpty(id) || !Regex.IsMatch(id, @"^\d+$")) 13 { 14 json.Msg = "模块参数错误"; 15 WriteLog(Common.Enums.enumOperator.Allocation, "初始化权限,结果:" + json.Msg, Common.Enums.enumLog4net.ERROR); 16 return Json(json); 17 } 18 //将 ID 转为 Int 19 int newid = int.Parse(id); 20 21 //判断权限里 模块是否有了权限 22 if (this.PermissionManage.IsExist(p => p.MODULEID == newid)) 23 { 24 json.Msg = "该模块已存在权限,无法初始化"; 25 WriteLog(Common.Enums.enumOperator.Allocation, "初始化权限,结果:" + json.Msg, Common.Enums.enumLog4net.ERROR); 26 return Json(json); 27 } 28 //添加默认权限 29 var per = new string[] { "查看,View", "列表,List", "详情,Detail", "添加,Add", "修改,Edit", "删除,Remove" }; 30 var list = new List (); 31 foreach (var item in per) 32 { 33 list.Add(new Domain.SYS_PERMISSION() 34 { 35 CREATEDATE = DateTime.Now, 36 CREATEUSER = this.CurrentUser.Name, 37 NAME = item.Split(',')[0], 38 PERVALUE = item.Split(',')[1], 39 UPDATEDATE = DateTime.Now, 40 UPDATEUSER = this.CurrentUser.Name, 41 MODULEID = newid, 42 SHOWORDER = 0 43 }); 44 } 45 //批量添加 46 if (this.PermissionManage.SaveList(list) > 0) 47 { 48 json.Status = "y"; 49 } 50 else 51 { 52 json.Msg = "初始化失败"; 53 } 54 WriteLog(Common.Enums.enumOperator.Allocation, "初始化权限,结果:" + json.Msg, Common.Enums.enumLog4net.INFO); 55 } 56 catch (Exception e) 57 { 58 json.Msg = e.InnerException.Message; 59 WriteLog(Common.Enums.enumOperator.Allocation, "对模块权限按钮的管理初始化权限:", e); 60 } 61 return Json(json); 62 }
现在OK了,权限的管理我们就完成了~~~
原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com