2.菜单管理
在菜单管理中我们就可以这样管理,某一菜单,那一角色可以看到就打上√这样比较容易控制。
3.数据库
再来看数据库中,要有角色的表以及用户与角色关系表。
再就是角色与菜单的关系表,其中PermissionIDs字段为操作权限以|隔开。
4.用户登录
当用户登录时我们就可以根据登陆人的ID取到他的所有角色存到Session中,并根据登录人查出相应的菜单。
//角色基本信息 SqlHelperParameter sqlHelperParameterRole = new SqlHelperParameter(); sqlHelperParameterRole.Add("UserId", dtUserRow["UserId"].ToString()); DataTable dtRole = SqlHelper.ExecuteDataTable(@" selectSys_Roles.RoleId, Sys_Roles.RoleName, Sys_Roles.Weightfrom (select UserId,RoleId from Sys_UsersInRoles where UserId =@UserId ) as a left join Sys_Roles on a.RoleId = Sys_Roles.RoleId", sqlHelperParameterRole); int dtRoleCount = dtRole.Rows.Count; RoleWeightMax = int.MaxValue; for (int i = 0; i < dtRoleCount; i++) {RolesSession rs = new RolesSession();rs.RoleID = Guid.Parse(dtRole.Rows[i]["RoleId"].ToString());rs.RoleName = dtRole.Rows[i]["RoleName"].ToString();rs.Weight = Convert.ToInt32(dtRole.Rows[i]["Weight"]);if (RoleWeightMax > rs.Weight){ RoleWeightMax = rs.Weight;}RoleList.Add(rs); }
public class RolesSession {public Guid RoleID { get; set; }public string RoleName { get; set; }//权重public int Weight { get; set; } }前台代码:
<div data-options="region:"west",split:true" title="导航菜单" style="width: 200px; padding1: 1px; overflow: hidden;" id="left_nav"> <div class="easyui-accordion" data-options="fit:true,border:false">@H9C.PMS.BLL.LogOn.MenuList.GetMenu(ViewBag.UserName) </div></div>控制器:
public static MvcHtmlString GetMenu(string userName){ Menu menu = new Menu(); MenuStructure ms = menu.GetMenuListStructure(userName); if (ms != null) {ms.Children.Remove(ms.Children.FirstOrDefault(o => o.ModelCode == "0" && o.ParentID == "0")); } return new MvcHtmlString(MenuNav("0", ms));}private static string MenuNav(string menuCode, MenuStructure menuStruc){ if (menuStruc == null) {return "<div>没有可用菜单</div>"; } List<MenuStructure> list = menuStruc.Children.Where(m => m.ParentID == menuCode).ToList(); StringBuilder sbMenu = new StringBuilder(); foreach (var item in list) {if (item.ParentID == "0"){ sbMenu.Append("<div title="" + item.Title + "" style="overflow: auto;">"); sbMenu.Append("<ul id="menu" + item.ParentID + "" class="easyui-tree" animate="true" dnd="true">"); sbMenu.Append("<li>");}else{ sbMenu.Append("<ul id="menu" + item.ParentID + "" class="easyui-tree" animate="true" dnd="true">"); if (item.Children.Count == 0) {sbMenu.Append("<li>"); } else {sbMenu.Append("<li state="closed">"); }}sbMenu.Append("<span>");if (item.Url == "/"){ sbMenu.Append("<a class="e-submenu" href="javascript:void(0);" title="" + item.Title + "" >");}else{ string tabsIcon = "14"; if (!string.IsNullOrWhiteSpace(item.Icon)) {tabsIcon = item.Icon.Replace("/Content/images/", "").Replace(".png", ""); } sbMenu.Append("<a class="e-submenu" href="#" onclick="addTab("" + item.Url + "","" + item.Title + "")" >"); sbMenu.Append("<img src="" + item.Icon + "" >");}sbMenu.Append("" + item.Title + "");sbMenu.Append("</a></span>");if (IsExistParent(item.ModelCode, item)){ sbMenu.Append(MenuNav(item.ModelCode, item));}sbMenu.Append("</li>");sbMenu.Append("</ul>");if (item.ParentID == "0"){ sbMenu.Append("</div>");} } return sbMenu.ToString();}private static bool IsExistParent(string modelCode, MenuStructure menuModels){ var query = menuModels.Children.FirstOrDefault(m => m.ParentID == modelCode); if (query == null) {return false; } return true;}菜单类:
public class MenuStructure {public string ModelCode;public string Title;public string Icon;public string Url;public string ParentID;public List<MenuStructure> Children = new List<MenuStructure>(); }其中GetMenuListStructure()方法就是根据用户名获取菜单列表结构,我这里用户名在数据库中是唯一的,在这里注意一点比较麻烦的是根据类可以看出菜单是有父菜单子菜单的所以方法中需要有两个循环去添加。
public class Menus {public static int gongdan = 503000000;//任务工单 }然后我们需要操作权限的按钮所在的页面的Controllers(加载页面)中存到ViewBag里,如下:
public ActionResult Index(){H9C.PMS.BLL.RBAC.Permission pm = new BLL.RBAC.Permission();ViewBag.IsReportPlan = pm.IsRoleHavePermissions(Roles.Shigongduizhang, Menus.gongdan, base.UserSessionModel, Menus.GongdanReportPlanByShiGongTeamer); //上报施工计划 return View();}
/// <summary>/// 判断某权限是否在获取某角色权限的列表中/// </summary>/// <param name="roleId"></param>/// <param name="modelCode"></param>/// <param name="userSessionModel"></param>/// <param name="permissionCode"></param>/// <returns></returns>public bool IsRoleHavePermissions(Guid roleId, int modelCode, UserSessionModel userSessionModel, int permissionCode){ List<PermissionModel> permissionModelList = this.GetRolePermissionList(roleId, modelCode, userSessionModel); if (permissionModelList == null) {return false; } foreach (var o in permissionModelList) {if (o.PCode == permissionCode){ return true;} } return false;}
/// <summary>/// 获取某角色权限的列表/// </summary>/// <param name="roleId"></param>/// <param name="modelCode"></param>/// <param name="userSessionModel"></param>/// <returns></returns>public List<PermissionModel> GetRolePermissionList(Guid roleId, int modelCode, UserSessionModel userSessionModel){ foreach (var o in userSessionModel.RoleList) {if (o.RoleID == roleId){ List<Model.RBAC.PermissionModel> permissionList = this.PermissionList(roleId, modelCode); return permissionList;} } return null;}
/// <summary>/// 获取某菜单某角色下具有的权限/// </summary>/// <param name="modelId"></param>/// <param name="menuId"></param>/// <returns></returns>public List<PermissionModel> PermissionList(Guid roleId, int menuId){ List<PermissionModel> pmList = new List<PermissionModel>(); using (RBACContext connEF = new RBACContext()) {Sys_Role_Model_Permissions srmp = connEF.Sys_Role_Model_Permissions.FirstOrDefault(o => o.ModelID == menuId && o.RoleId == roleId);if (srmp != null){ string permissions = srmp.PermissionIDs; if (!string.IsNullOrWhiteSpace(permissions)) {string[] pids = permissions.Split(new char[] { "|" });for (int i = 0; i < pids.Length; i++){ if (!string.IsNullOrWhiteSpace(pids[i])) {pmList.Add(new PermissionModel() { ModelCode = menuId, PCode = Convert.ToInt32(pids[i]), PName =""}); }} }} } return pmList;}最后一个方法中运用到了EF根据菜单以及角色获取某菜单某角色下具有的权限
@if (ViewBag.IsReportPlan == true){ @: <a href="#" class="easyui-linkbutton l-btn" iconcls="icon-add">按钮</a> }四、尾声