原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(24)-权限管理系统-将权限授权给角色
过了个年回来,回顾一下,我们上次讲了角色管理,我们这一次来讲将权限授权给角色,这一节也是大家比较关心的。因为我们已经跑通了整个系统,知道权限的流转,我们先来看一张图
这张图主要分要3块,角色组----系统模块----操作码授权
选择角色组(表示要授权的角色,选择需要授权的模块,最后授权操作码。当存在一个操作码时候,我们应该改变SysRight表中的rightflag字段,表示他有权限。不知道大家是否还记得,这个图也是我们要做的。由于图中用的是JQGrid看起来跟Easyui有点差别,但是方式却是一样的)
回到头看到SysRightOperate表的IsValid,我们将授权角色和模块和操作码这3张表关联起来,其中IsValid字段是来标识是否有操作的权限,当第一次授权,那么是向SysRightOperate添加一条记录,如果下次更新先判断是否已经授权如果没有,那么删除或者更新IsValid,我这里是更新,你也可以删除掉,一样的道理。
之前我们已经新建过SysRight这个表的DAL层和BLL层了,根据想法,我们只要建立多两个方法
- 更新SysRightOperate(即上面所说)
- 和按选择的角色及模块加载模块的权限项(确定操作码是否被授权,即图中的复选框)
现在向ISysRightRepository添加2个方法
//更新 int UpdateRight(SysRightOperate model); //按选择的角色及模块加载模块的权限项 List<P_Sys_GetRightByRoleAndModule_Result> GetRightByRoleAndModule(string roleId, string moduleId);
P_Sys_GetRightByRoleAndModule_Result这个是存储过程,由于这2个方法比较复杂,这里用存储过程来做
Create proc [dbo].[P_Sys_GetRightByRoleAndModule] @roleId varchar(50),@moduleId varchar(50) as --按选择的角色及模块加载模块的权限项 begin select a.Id,a.Name,a.KeyCode,a.ModuleId,ISNULL(b.IsValid,0) as isvalid,a.Sort,@roleId+@moduleId as RightId from SysModuleOperate a left outer join( select c.Id,a.IsValid from SysRightOperate a,SysRight b, SysModuleOperate c where RightId in (select Id From SysRight where RoleId =@roleId and ModuleId =@moduleId) and a.RightId=b.Id and b.ModuleId=c.ModuleId and a.KeyCode =c.KeyCode) b on a.Id = b.Id where a.ModuleId =@moduleId end
所以必须要把这个存储过程添加到EF,并生成复杂类型的实体P_Sys_GetRightByRoleAndModule_Result
然后创建P_Sys_UpdateSysRightRightFlag
Create proc [dbo].[P_Sys_UpdateSysRightRightFlag] @moduleId varchar(200),@roleId varchar(200) as begin --计算上级模块的rightflag标识 declare @count int --第一层:由操作权限项计算模块权限 select @count=COUNT(*) from SysRightOperate where RightId=@roleId+@moduleId and IsValid=1 if(@count>0) begin update SysRight set Rightflag=1 where ModuleId=@moduleId and RoleId=@roleId end else begin update SysRight set Rightflag=0 where ModuleId=@moduleId and RoleId=@roleId end --计算下一层 declare @parentId varchar(50) set @parentId=@moduleId while(@parentId<>'0') begin select @parentid=ParentId from SysModule where Id=@parentId if (@parentId is null) begin return end select @count=COUNT(*) from SysRight where ModuleId in (select Id from SysModule where ParentId=@parentId) and RoleId =@roleId and Rightflag=1 if(@count>0) begin update SysRight set Rightflag=1 where ModuleId=@parentId and RoleId=@roleId end else begin update SysRight set Rightflag=0 where ModuleId=@parentId and RoleId=@roleId end end end
这个是计算上级模块的rightflag标识也就是开头所说的RightFlag字段,这个字段将决定导航条的显示,所以每一次授权操作都要执行
下面添加SysRightRepository逻辑代码
public int UpdateRight(SysRightOperateModel model) { //转换 SysRightOperate rightOperate = new SysRightOperate(); rightOperate.Id = model.Id; rightOperate.RightId = model.RightId; rightOperate.KeyCode = model.KeyCode; rightOperate.IsValid = model.IsValid; //判断rightOperate是否存在,如果存在就更新rightOperate,否则就添加一条 using (DBContainer db = new DBContainer()) { SysRightOperate right = db.SysRightOperate.Where(a => a.Id == rightOperate.Id).FirstOrDefault(); if (right != null) { right.IsValid = rightOperate.IsValid; } else { db.SysRightOperate.AddObject(rightOperate); } if (db.SaveChanges() > 0) { //更新角色--模块的有效标志RightFlag var sysRight = (from r in db.SysRight where r.Id == rightOperate.RightId select r).First(); db.P_Sys_UpdateSysRightRightFlag(sysRight.ModuleId, sysRight.RoleId); return 1; } } return 0; } //按选择的角色及模块加载模块的权限项 public List<P_Sys_GetRightByRoleAndModule_Result> GetRightByRoleAndModule(string roleId, string moduleId) { List<P_Sys_GetRightByRoleAndModule_Result> result = null; using (DBContainer db = new DBContainer()) { result = db.P_Sys_GetRightByRoleAndModule(roleId,moduleId).ToList(); } return result; }
按照习惯,我们要向IBLL 和BLL 添加代码,大家自行添加访问DAL层的代码即可
比较繁琐的还是Controller层和页面UI的代码,这些先贴出
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; using App.IBLL; using App.Models; using App.Common; using App.Models.Sys; namespace App.Admin.Controllers { public class SysRightController : BaseController { // // GET: /SysRight/ [Dependency] public ISysRightBLL sysRightBLL { get; set; } [Dependency] public ISysRoleBLL sysRoleBLL { get; set; } [Dependency] public ISysModuleBLL sysModuleBLL { get; set; } [SupportFilter] public ActionResult Index() { ViewBag.Perm = GetPermission(); return View(); } //获取角色列表 [SupportFilter(ActionName = "Index")] [HttpPost] public JsonResult GetRoleList(GridPager pager) { List<SysRoleModel> list = sysRoleBLL.GetList(ref pager, ""); var json = new { total = pager.totalRows, rows = (from r in list select new SysRoleModel() { Id = r.Id, Name = r.Name, Description = r.Description, CreateTime = r.CreateTime, CreatePerson = r.CreatePerson }).ToArray() }; return Json(json); } //获取模组列表 [SupportFilter(ActionName = "Index")] [HttpPost] public JsonResult GetModelList(string id) { if (id == null) id = "0"; List<SysModuleModel> list = sysModuleBLL.GetList(id); var json = from r in list select new SysModuleModel() { Id = r.Id, Name = r.Name, EnglishName = r.EnglishName, ParentId = r.ParentId, Url = r.Url, Iconic = r.Iconic, Sort = r.Sort, Remark = r.Remark, Enable = r.Enable, CreatePerson = r.CreatePerson, CreateTime = r.CreateTime, IsLast = r.IsLast, state = (sysModuleBLL.GetList(r.Id).Count > 0) ? "closed" : "open" }; return Json(json); } //根据角色与模块得出权限 [SupportFilter(ActionName = "Index")] [HttpPost] public JsonResult GetRightByRoleAndModule(GridPager pager, string roleId, string moduleId) { pager.rows = 100000; var right = sysRightBLL.GetRightByRoleAndModule(roleId,moduleId); var json = new { total = pager.totalRows, rows = (from r in right select new SysRightModelByRoleAndModuleModel() { Ids= r.RightId+ r.KeyCode, Name= r.Name, KeyCode =r.KeyCode, IsValid=r.isvalid, RightId=r.RightId }).ToArray() }; return Json(json); } //保存 [HttpPost] [SupportFilter(ActionName = "Save")] public int UpdateRight(SysRightOperateModel model) { return sysRightBLL.UpdateRight(model); } } }
@using App.Common; @using App.Admin; @{ ViewBag.Title = "角色授权设置"; Layout = "~/Views/Shared/_Index_Layout.cshtml"; List<App.Models.Sys.permModel> perm = (List<App.Models.Sys.permModel>)ViewBag.Perm; if (perm == null) { perm = new List<App.Models.Sys.permModel>(); } } <div class="mvctool"> @Html.ToolButton("btnSave", "icon-save", "保存", perm, "Save", true) </div> <table style="width: 100%"> <tbody> <tr> <td style="width: 420px; padding-right: 3px; vertical-align: top"> <table id="roleList"></table> </td> <td style="width: 200px; padding-right: 3px; vertical-align: top"> <table id="moduleList"></table> </td> <td> <table id="operateList"></table> </td> </tr> </tbody> </table> <script type="text/javascript"> $(function () { var curModuleId, curRoleId, curModuleName, curRoleName, curSystemId, curSystemName;//选择的模块ID,选中的角色ID,选中的模块名称,角色名称 curRoleName = "?"; curModuleName = "?"; $('#roleList').datagrid({ url: '@Url.Action("GetRoleList")', width: 420, methord: 'post', height: $(window).height() - 35, fitColumns: true, sortName: 'CreateTime', sortOrder: 'desc', idField: 'Id', pageSize: 15, pageList: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleSelect: true,//单选模式 rownumbers: true,//行号 title: '角色列表', columns: [[ { field: 'Id', title: '', width: 80, hidden: true }, { field: 'Name', title: '角色组', width: 80, sortable: true }, { field: 'Description', title: '说明', width: 80, sortable: true }, { field: 'CreateTime', title: '创建时间', width: 80, sortable: true }, { field: 'CreatePerson', title: '', width: 80, sortable: true, hidden: true } ]], onClickRow: function (index, data) { var row = $('#roleList').datagrid('getSelected'); if (row != null) { curRoleName = row.Name; curRoleId = row.Id; $('#operateList').datagrid({ url: "/SysRight/GetRightByRoleAndModule?roleId=" + curRoleId + "&moduleId=" + curModuleId + "" }); $('#operateList').datagrid({ 'title': "角色组: " + curRoleName + " >> 模块:" + curModuleName }); } } }); $('#moduleList').treegrid({ url: '@Url.Action("GetModelList")', width: 300, methord: 'post', height: $(window).height() - 35, fitColumns: true, treeField: 'Name', idField: 'Id', pagination: false, striped: true, //奇偶行是否区分 singleSelect: true,//单选模式 title: '模块列表', columns: [[ { field: 'Id', title: '唯一标识', width: 120, hidden: true }, { field: 'Name', title: '名称', width: 220, sortable: true }, { field: 'EnglishName', title: '英文名称', width: 80, sortable: true, hidden: true }, { field: 'ParentId', title: '上级Id', width: 80, sortable: true, hidden: true }, { field: 'Url', title: '链接地址', width: 80, sortable: true, hidden: true }, { field: 'Iconic', title: '图标', width: 80, sortable: true, hidden: true }, { field: 'Sort', title: '排序号', width: 80, sortable: true, hidden: true }, { field: 'Remark', title: '说明', width: 80, sortable: true, hidden: true }, { field: 'Enable', title: '是否启用', width: 60, align: 'center', formatter: function (value) { if (value) { return "<img src='/Content/Images/icon/pass.png'/>"; } else { return "<img src='/Content/Images/icon/no.png'/>"; } }, hidden: true }, { field: 'CreatePerson', title: '创建人', width: 80, sortable: true, hidden: true }, { field: 'CreateTime', title: '创建时间', width: 120, sortable: true, hidden: true }, { field: 'IsLast', title: '是否最后一项', align: 'center', width: 100, formatter: function (value) { if (value) { return "是"; } else { return "否"; } }, hidden: true }, ]], onClickRow: function (index, data) { var row = $('#moduleList').treegrid('getSelected'); if (row != null) { curModuleName = row.Name; curModuleId = row.Id; if (curRoleId == null && row.IsLast) { $.messageBox5s('提示', "请再选择一个角色!"); return; } $('#operateList').datagrid({ url: "/SysRight/GetRightByRoleAndModule?roleId=" + curRoleId + "&moduleId=" + curModuleId + "" }); $('#operateList').datagrid({ 'title': "角色组: " + curRoleName + " >> 模块:" + (row.IsLast ? curModuleName : "[请再选择最后菜单项]") }); } } }); $('#operateList').datagrid({ url: '@Url.Action("GetRightByRoleAndModule")', width: $(window).width() - 736, methord: 'post', height: $(window).height() - 35, fitColumns: true, sortName: 'CreateTime', sortOrder: 'desc', idField: 'Id', striped: true, //奇偶行是否区分 singleSelect: true,//单选模式 title: '授权操作', //rownumbers: true,//行号 columns: [[ { field: 'Ids', title: 'Ids', width: 80, hidden: true }, { field: 'Name', title: '名称', width: 80, sortable: true }, { field: 'KeyCode', title: '操作码', width: 80, sortable: true }, { field: 'IsValid', title: "<a href='#' title='@Suggestion.Select' onclick=\"SelAll();\" ><img src='/Content/Images/icon/select.gif'></a> <a href='#' title='@Suggestion.UnSelect' onclick=\"UnSelAll();\" ><img src='/Content/Images/icon/unselect.gif'></a>", align: 'center', width: 30, formatter: function (value) { if (value) { return "<input type='checkbox' checked='checked' value=" + value + " />"; } else { return "<input type='checkbox' value=" + value + " />"; } }, }, { field: 'RightId', title: '模块ID', width: 80, sortable: true, hidden: true } ]] }); $("#btnSave").click(function () { var updateRows = 0; var rows = $("#operateList").datagrid("getRows"); //这段代码是获取当前页的所有行。 for (var i = 0; i < rows.length; i++) { var setFlag = $("td[field='IsValid'] input").eq(i).prop("checked"); if (rows[i].IsValid != setFlag)//判断是否有作修改 { $.post("@Url.Action("UpdateRight")", { "Id": rows[i].Ids, "RightId": rows[i].RightId, "KeyCode": rows[i].KeyCode, "IsValid": setFlag }, "json"); updateRows++; } } if (updateRows > 0) { $.messageBox5s('提示', '保存成功!'); } else { $.messageBox5s('提示', '@Suggestion.NoAnyChanges!'); } }); $(window).resize(function () { $('#operateList').datagrid('resize', { width: $(window).width() - 736, height: $(window).height() - 35 }).datagrid('resize', { width: $(window).width() - 736, height: $(window).height() - 35 }); $('#moduleList,#roleList').datagrid('resize', { height: $(window).height() - 35 }).datagrid('resize', { height: $(window).height() - 35 }); }); }); function SelAll() { $("td[field='IsValid'] input").prop("checked", true); $("#btnSave").trigger("click"); return; } function UnSelAll() { $("td[field='IsValid'] input").prop("checked", false); $("#btnSave").trigger("click"); return; } </script>
最后效果图
这次发布还是做得比较认真的。大家可以详细细读代码和存储过程。不清楚的欢迎留言,必定回答
接下来是讲角色和用户的互相授权,有兴趣的朋友可以先做做看。