用最基本的EF+MVC+JQ+AJAX+bootstrap实现权限管理的简单实例 之登陆和操作权限
先来一堆关于上篇文章的废话(不喜者点此隐藏)
上篇文章发布后有一定的推荐量和浏量,对一个初学者来说,自认为还是挺不错的。最主要的是收到了不少的评论,有鼓励的,有建议的,当然也有反对的。最重要的是有一大牛级的人物对我表示了特别的关心,此人工作经验大于10年,准备单干。加了QQ聊了一阵,当然不是技术讨论,我估计也不够格跟他谈,主要是他表示关心和鼓励,虽然没有收留我的意向,再此仍深表谢意。以后可能会有技术问题咨询。我写文章最大的意图和乐趣在于把自己的想法写出来,然后希望能收获到比较好的建议和指正,从中找出自己的毛病,扩大自己的视野。
评论中,其实也就那么一两条是关于我实现想法的建议。其中有一个说到了操作权限,以下是原文引用:
“博主这个思路有个很大的问题,就是很难收敛。举个栗子吧,一个订单管理有新建、编辑、删除、归档这些操作,这样的聚合根就很难应用你的权限。增删改查很容易对应数据库操作,但是归档是个什么鬼?从业务上来看,归档就是把订单从业务库移动到历史库里面去,又增又删,还操作两个库。我看不出来你的系统能解决这个问题”
另外的都是觉得权限是与业务藕合,根本无法抽象。其中一个原文引用:
“学生信息管理:
班主任看自己所带班级的
年级组长看自己所担任年级的
校领导看全校的
而这种业务数据的界定,根本不是你角色控制的。
这是职务or岗位权限!
属于业务的一部分!
如果你要角色控制,也最多这这三种角色,但是你最后还是需要有职务信息(这种业务数据)来辅助你实现数据查询边界
还有一个特别懂我的人,相信他应该是认真的看过了,才会如此懂我。原文:
“反对的原因无非是无法完全抽象
一个行业有一个行业的权限
不同行权限有细微而又本质的区别导致无法抽象共用
也即是说 对象可能是这样 但是对对象的限制 层级关系 相互约束确是千奇百怪的
不过这个本文其实没有太大联系 博主写的权限 相信最终还是依赖其公司所面向的行业 而能从中看到些什么 从而优化我们的自己的权限 我觉得才是最重要的”
在这些评论后,我马上想到了我所忽略的真正重要的问题。于是在原来的基础上加了一个User的抽象类,一个角色抽象类,一个处理登陆用户权限的类,把用户的权限和他拥有的角色的权限综合。对于数据权限我目前有一个自认为比较可行的抽象方案,但是本文没有涉及,我想着如果这篇能有比较好的反响的话,我想另外写篇讨论一下。
细谈我对权限系统的简单理解
还是先申明一下:以下观点纯属性一个业外人士胡思乱想,不保证实用价值。如果你认同本人观点,你可以在此基础上进行优化。如果你认为有需要改造的地方,还请不吝赐教。
对于MVC服务系统,操作权限主要就是在登陆用户和一个具体控制器方法之间发生,我把一个方法设计成界面的一个按钮(操作权限),而按钮又被包含在一个菜单中(菜单权限),菜单又被包含在一个模块中。模块是一个比较大的权限,我在例子中主要是用来对用户身份做一个区分,比如有以开发人员身份登陆,我们就有一个开发人员功能模块,有管理员登陆的管理员模块,模块主要针对的是一个MVC的控制器。菜单主要用于区分一个模块下管理的对象,比如管理的角色,就有角色管理菜单,管理的是部门,就有一个部门管理菜单,这个菜单下的方法,也就是这个菜单界面的按钮,主要就是针对这个对象的一些特定操作。下面是一张草图,以展示从用户到一个具体操作的流程。但愿这段文字加上下面的图能表达出我的思路。对于操作权限的实现,我便是依据这个图来开展的。

一个用户在登陆后,他拥有的模块,菜单及菜单下的按钮已经被加载好了,而界面部分已经针对他的菜单权限有了不同的展示,所有可操作权限按菜单分类分配到不同菜单下对应的按钮。下面展示一下我实现的部分小功能效果展示。请不要介意界面的好看与否。主要看不同点,红色框起部分,几乎每个地方都有不同的。但是在同一个页面,对于小实例,我认为一个页面足已应付各种不同身份的登陆用户。由于我认为模块,菜单和按钮的管理是应该由开发人员来执行的,而权限对于开发人员是没有约束的,所以开发人员模块下,有两个固定的按钮,一个是添加,一个是授权。而其它身份的用户则不应该有操作这些的权限。
看看开发人员登陆点开发人员模块下的模块管理菜单效果

点管理员模块下的角色管理菜单下的变化

一般的无权限的用户登陆后的界面

在浏览器地址栏输入地址访问无权限的操作

搞一个开发者授权的菜单出来,列出所有的用户,给用户分配最大的管理权限



搞清流程和职责,代码实现喜欢怎么搞就怎么搞
到目前为止,开发人员这块我感觉差不多了。开发人员的职责无非就是按业务需要和逻辑开发一个MVC控制器和控制器下的方法,这跟平常的没有权限管理是一样一样的,如果要加权限管理,你只需要把它逻辑分类,保存到数据库,加上一些验证标签然后扔给前前端设计和管理员去管理分配。
模型都是最基本的属性,全部用的贫血的,如果用充血模型,API逻辑应该更清晰。比如用户隐藏字段的权限,可以写到用户类中去的。调用仓储接口来持久化,你可以用user.HideFiledToxx。
不多说了。我是把上篇文章的EF操作和水货RBAC生成DLL引用到这是测试项目来的。




后端就两个项目,非常简单。Domain层就一个服务是对上篇的进行二次封装,以持久化到数据库,另外一个是登陆用户服务类这两个类比较特别。其它都是一般的服务。这两个点是根据业务和数据库变化的。
namespace Domain.DataModels
{
public class User:YZY_RBAC.Core.YZYUser<int>
{
) { }
public string Name { get; set; }
public string Telphone { get; set; }
}
}
User
using System.Collections.Generic;
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Role:YZYRole<int>
{
) { }
/// <summary>
/// 指定角色可操作的门
/// </summary>
public virtual ICollection<Dep_Role> ManageDeps { get; set; } = new List<Dep_Role>();
}
}
Role
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Relevance:BaseRelevance<int>
{
) { }
}
}
Relevance
using System.Collections.Generic;
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Module:BaseEntity<int>
{
) { }
public string Name { get; set; }
public virtual ICollection<Menu> Menus { get; set; }
public string Type { get; set; }
public bool IsAdminModule { get; set; }
public string Url { get; set; }
}
}
Module
using System.Collections.Generic;
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Menu:BaseEntity<int>
{
) { }
public string Url { get; set; }
public string RoleType { get; set; }
public virtual ICollection<ActionButton> Buttons { get; set; } = new List<ActionButton>();
public string Name { get; set; }
public virtual Module Module { get; set; }
public int? ModuleId { get; set; }
}
}
Menu
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class HideFiled:BaseHideFiled<int>
{
) { }
}
}
HideFiled
using System.Collections.Generic;
namespace Domain.DataModels
{
public class Employee:User
{
public virtual ICollection<Dep_Emp> Depatments { get; set; } = new List<Dep_Emp>();
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public string Gender { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 工资
/// </summary>
public double Salary { get; set; }
}
}
Employee
using System.Collections.Generic;
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Deparentment:BaseEntity<int>
{
) { }
public string Name { get; set; }
public string Number { get; set; }
public int? ParentId { get; set; }
public virtual Deparentment Parent { get; set; }
public virtual ICollection<Dep_Emp> Employees { get; set; } = new List<Dep_Emp>();
public virtual ICollection<Dep_Role> Roles { get; set; } = new List<Dep_Role>();
public virtual ICollection<Deparentment> Childs { get; set; } = new List<Deparentment>();
public bool IsTop { get; set; }
}
}
Deparentment
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Dep_Role:BaseEntity<int>
{
) { }
public int DepId { get; set; }
public virtual Deparentment Dep { get; set; }
public int RoleId { get; set; }
public virtual Role Role { get; set; }
}
}
Dep_Role
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class Dep_Emp:BaseEntity<int>
{
) { }
public Deparentment Dep { get; set; }
public int DepId { get; set; }
public Employee Emp { get; set; }
public int EmpId { get; set; }
}
}
Dep_Emp
using YZY_RBAC.Core;
namespace Domain.DataModels
{
public class ActionButton:BaseEntity<int>
{
) { }
public int? MenuId { get; set; }
public virtual Menu Menu { get; set; }
public string Url { get; set; }
public string Icon { get; set; }
public string RoleType { get; set; }
public string Name { get; set; }
}
}
ActionButton
上面这些代码这真心是蛮不好意思贴出来的。服务类就是些CURD我就不贴出来了,把两个特别点的贴出来。AuthorizeService就是个授权服务,将两个实体间的权限通过权限类型进行关联。LoginUserService是根据当前登陆用户的身份加载用户的所有权限集合,供前端用。但是我没有写测试代码,功能现在还不知道有没有问题。
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using YZY_RBAC.Core;
namespace Domain.Service
{
public class AuthorizeService<TEntity>where TEntity:BaseEntity<int>
{
public static RBACManage<TEntity, int> rbac { get; set; } = new RBACManage<TEntity, int>();
private static RelevanceService releService;
private static HideFiledService hideService;
/// <summary>
/// 初始化RBAC
/// </summary>
public static void InitiaRbac()
{
releService = new RelevanceService();
hideService = new HideFiledService();
rbac.RelevanceQuery = releService.Find();
rbac.HideFiledQuery = hideService.Find();
}
/// <summary>
/// 为当前实体授权指定的权限
/// </summary>
/// <param name="entity"></param>
/// <param name="per"></param>
/// <param name="type"></param>
public static void Authorize<TPer>(TEntity entity,TPer per,PermissionType type)where TPer:BaseEntity<int>
{
var rel = rbac.GetBindRelevance(entity, new Relevance(), per, type) as Relevance;
if (!releService.Find().Any(o => o.EntityId == entity.Id && o.PermisId == per.Id))
releService.Add(rel);
releService.Commit();
InitiaRbac();
}
/// <summary>
/// 为当前实体授权指定的权限
/// </summary>
/// <param name="entity"></param>
/// <param name="pers"></param>
/// <param name="type"></param>
public static void Authorize<TPer>(TEntity entity,IEnumerable<TPer>pers,PermissionType type) where TPer : BaseEntity<int>
{
)
{
foreach(var p in pers)
{
var rel = rbac.GetBindRelevance(entity, new Relevance(), p, type) as Relevance;
if (!releService.Find().Any(o => o.EntityId == entity.Id && o.PermisId == p.Id))
releService.Add(rel);
}
releService.Commit();
InitiaRbac();
}
}
/// <summary>
/// 设置当前实体对其它实体隐藏指定的权限
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="per"></param>
/// <param name="filedName"></param>
public static void SetHideFiledToOther<T>(TEntity entity, T per, string filedName)
where T:BaseEntity<int>
{
//保存申请的隐藏字段权限
var hide = rbac.GetRegisteHideFiled(entity, filedName, new HideFiled()) as HideFiled;
if (!hideService.Find().Any(o => o.EntityId == entity.Id && o.HidePropertyName == filedName))
{
hideService.Add(hide);
hideService.Commit();
InitiaRbac();
}
var rel = rbac.GetBindHideFiledToOtherEntityRelevance(entity, new Relevance(), per, filedName);
//如数据库中不存在这个关联,则添加
if (!releService.Find().Any(o => o.EntityId == per.Id &&
o.PermissionType == PermissionType.Propety.ToString() && o.PermisId == hide.Id))
{
releService.Add(rel as Relevance);
}
releService.Commit();
InitiaRbac();
}
/// <summary>
/// 设置当前实体对其它实体隐藏指定的权限
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="filedName"></param>
/// <param name="others"></param>
public static void SetHideFiledToOther<T>(TEntity entity,string filedName,IEnumerable<T>others)where T:BaseEntity<int>
{
)
{
foreach(var o in others)
{
SetHideFiledToOther(entity, o, filedName);
}
}
}
/// <summary>
/// 取消隐藏字段
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="filedName"></param>
public static void ClearHideFiled(TEntity entity, string filedName)
{
if (hideService.Find().Any(o => o.EntityId == entity.Id && o.HidePropertyName == filedName))
{
var hide =hideService.Find().Where(o => o.EntityId == entity.Id && o.HidePropertyName == filedName).FirstOrDefault();
hideService.Remove(hide);
if (releService.Find().Any(o => o.PermisId == hide.Id && o.PermissionType == PermissionType.Propety.ToString()))
{
var rels = releService.Find().Where(o => o.PermisId == hide.Id && o.PermissionType == "Porpety").ToList();
foreach (var r in rels)
{
releService.Remove(r);
}
releService.Commit();
hideService.Commit();
InitiaRbac();
return;
}
}
throw new Exception("没有找到指定的字段");
}
/// <summary>
/// 取消对指的其它实体的隐藏字段
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="filedName"></param>
/// <param name="other"></param>
public static void ClearHideFiledToOther<T>(TEntity entity,string filedName,T other)where T:BaseEntity<int>
{
if(hideService.Find().Any(o=>o.EntityId==entity.Id&&o.HidePropertyName==filedName))
{
var hide = hideService.Find().Where(o => o.EntityId == entity.Id && o.HidePropertyName == filedName).FirstOrDefault();
hideService.Remove(hide);
if(releService.Find().Any(o=>o.EntityId==other.Id&&o.PermisId==hide.Id&&o.PermissionType==PermissionType.Propety.ToString()))
{
var rel = releService.Find(o => o.EntityId == other.Id && o.PermissionType == "Propety" && o.PermisId == hide.Id).FirstOrDefault();
releService.Remove(rel);
releService.Commit();
}
hideService.Commit();
InitiaRbac();
return;
}
throw new Exception("没有找到指定的字段");
}
/// <summary>
/// 取消对指的其它实体的隐藏字段
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="filedName"></param>
/// <param name="others"></param>
public static void ClearHideFiledToOther<T>(TEntity entity, string filedName, IEnumerable<T>others)
where T : BaseEntity<int>
{
)
{
foreach (var o in others)
ClearHideFiledToOther(entity, filedName, o);
}
}
/// <summary>
/// 取消当前实体的指定授权
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="other"></param>
/// <param name="relFilter"></param>
public static void ClearAuthorizetion<T>
(TEntity entity,T other,Func<Relevance,bool>relFilter=null)
where T:BaseEntity<int>
{
Relevance rel = null;
if(relFilter==null)
{
if(releService.Find(o=>o.EntityId==entity.Id&&o.PermisId==other.Id).Any())
{
rel = releService.Find(o => o.EntityId == entity.Id && o.PermisId == other.Id).FirstOrDefault();
releService.Remove(rel);
releService.Commit();
InitiaRbac();
return;
}
}
if(releService.Find(o=>o.EntityId==entity.Id&&o.PermisId==other.Id).AsEnumerable().Where(relFilter).Any())
{
rel = releService.Find(o => o.EntityId == entity.Id && o.PermisId == other.Id).AsEnumerable().Where(relFilter).FirstOrDefault();
releService.Remove(rel);
releService.Commit();
InitiaRbac();
return;
}
throw new Exception("没有找到指定的关联");
}
/// <summary>
/// 取消当前实体的指定授权
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="others"></param>
/// <param name="relFilter"></param>
public static void ClearAuthorizetion<T>
(TEntity entity, IEnumerable<T> others, Func<Relevance, bool> relFilter = null)
where T : BaseEntity<int>
{
)
{
foreach (var o in others)
ClearAuthorizetion(entity, o, relFilter);
}
}
}
}
AuthorizeService
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YZY.Domain;
using YZY_RBAC.Core;
namespace Domain.Service
{
public class LoginUserService
{
public LoginUserService(User loginUser)
{
mage = new LoginUserMagage<int>(user);
mage.HideFiledQuery = new HideFiledService().Find();
mage.RelevanceQuery = new RelevanceService().Find();
mage.RoleQuery = new RoleService().Find();
}
private User user = UserManage<int>.GetCacheUser() as User;
private Pager pager;
private LoginUserMagage<int> mage;
private List<ActionButton> btns = new List<ActionButton>();
private List<Deparentment> deps = new List<Deparentment>();
private List<Employee> ems = new List<Employee>();
private List<Menu> menus = new List<Menu>();
private List<Role> roles = new List<Role>();
private List<Module> modules = new List<Module>();
private List<User> users = new List<User>();
#region 属性
/// <summary>
/// 当前登陆用户
/// </summary>
public User LoginUser { get { return user; } }
/// <summary>
/// 当前登陆用户可访问或操作的按钮
/// </summary>
public IEnumerable<ActionButton> Buttons { get { return btns; } }
/// <summary>
/// 登陆用户可访问的模块
/// </summary>
public IEnumerable<Module> Modules { get { return modules; } }
/// <summary>
/// 当前登陆用户可访问或操作部门
/// </summary>
public IEnumerable<Deparentment> Departs { get { return deps; } }
/// <summary>
/// 当前登陆用户可访问或操作员工
/// </summary>
public IEnumerable<Employee> Employees { get { return ems; } }
/// <summary>
/// 当前登陆用户可访问或操作的菜单
/// </summary>
public IEnumerable<Menu> Menus { get { return menus; } }
/// <summary>
/// 当前登陆用户可访问或操作的角色
/// </summary>
public IEnumerable<Role> Roles { get { return roles; } }
/// <summary>
/// 登陆用户可访问的用户
/// </summary>
public IEnumerable<User> Users { get { return users; } }
//分页数据
public int EmpPageIndex { get; set; }
public int EmpPageSize { get; set; }
#endregion
/// <summary>
/// 加载当前登陆用户的权限资源和数据
/// </summary>
public void LoadLoginUserResouces()
{
if (user != null)
{
#region 系统管理员登陆
if (user.IsSysAdmin)
{
deps = new DepartmentService().Find().ToList();
btns = new ButtonService().Find().ToList();
ems = new EmpService().FindPage(EmpPageIndex, EmpPageSize).ToList();
menus = new MenuService().Find().ToList();
roles = new RoleService().Find().ToList();
modules = new ModuleService().Find().ToList();
users = new UserService().Find().ToList();
return;
}
#endregion
#region 以员工身份登陆的用户
string tel = user.Telphone;
if (new EmpService().Find(o => o.Telphone == tel).Any())
{
Employee em = new EmpService().Find(o => o.Telphone == tel).Single();
mage = new LoginUserMagage<int>(em);
mage.HideFiledQuery = new HideFiledService().Find();
mage.RelevanceQuery = new RelevanceService().Find();
mage.RoleQuery = new RoleService().Find();
//获取后台已授权的数据
btns = mage.GetInPermissionResouces(new ButtonService().Find(), null).ToList();
menus = mage.GetInPermissionResouces(new MenuService().Find(), null).ToList();
roles = mage.GetInPermissionResouces(new RoleService().Find(), null).ToList();
modules = mage.GetInPermissionResouces(new ModuleService().Find(), null).ToList();
users = mage.GetInPermissionResouces(new UserService().Find(), null).Where(o => o.IsSysAdmin == false).ToList();
//默认的数据规则:用户只能访问自己部门和同部门的员工
deps = new Dep_EmpService().Find(o => o.Emp == em).Select(o => o.Dep).ToList();
//如果当前用户有角色权限,并集角色的部门
)
{
foreach (var r in roles)
{
deps = new Dep_RoleService().Find(o => o.Role == r).ToList().Select(o => o.Dep).Union(deps).ToList();
}
deps = deps.Distinct(new DistinctEntityId<Deparentment, int>()).ToList();
}
//找出所有部门下的员工
foreach (var d in deps)
{
ems = ems.Union(new Dep_EmpService().Find(o => o.DepId == d.Id).ToList().Select(o => o.Emp)).ToList();
pager = new Pager(ems.Count);
pager.Initia(EmpPageIndex, EmpPageSize);
ems = ems.OrderBy(o => o.Id).Skip(pager.Skip).Take(pager.Take).ToList();
}
//如果其中有隐藏字段的员工,替换掉
var hides = mage.GetHideFiledResouces(new EmpService().Find());
)
{
ems = ems.Except(hides, new DistinctEntityId<Employee, int>()).Union(hides).ToList();
}
return;
}
#endregion
#region 以角色或其它身份登陆
//获取后台已授权的数据
btns = mage.GetInPermissionResouces(new ButtonService().Find(), null).ToList();
menus = mage.GetInPermissionResouces(new MenuService().Find(), null).ToList();
roles = mage.GetInPermissionResouces(new RoleService().Find(), null).ToList();
modules = mage.GetInPermissionResouces(new ModuleService().Find(), null).ToList();
users = mage.GetInPermissionResouces(new UserService().Find(), null).Where(o => o.IsSysAdmin == false).ToList();
//如果当前用户有角色权限,并集角色的部门
)
{
var drs = new Dep_RoleService();
foreach (var r in roles)
{
if (drs.Find(o => o.RoleId == r.Id).Any())
{
deps.Add(drs.Find(o => o.RoleId == r.Id).Select(o => o.Dep).Single());
}
//deps = new Dep_RoleService().Find(o => o.Role == r).ToList().Select(o => o.Dep).Union(deps).ToList();
}
deps = deps.Distinct(new DistinctEntityId<Deparentment, int>()).ToList();
}
//找出所有部门下的员工
foreach (var d in deps)
{
ems = ems.Union(new Dep_EmpService().Find(o => o.DepId == d.Id).ToList().Select(o => o.Emp)).ToList();
}
//如果其中有隐藏字段的员工,替换掉
var hids = mage.GetHideFiledResouces(new EmpService().Find());
)
{
ems = ems.Except(hids, new DistinctEntityId<Employee, int>()).Union(hids).ToList();
}
#endregion
}
}
/// <summary>
/// 根据地址和权限类型判断当前登陆用户是否有该操作权限
/// </summary>
/// <param name="url"></param>
/// <param name="type"></param>
/// <returns></returns>
public bool CheckActionAuthorize(string url,PermissionType type)
{
if (type == PermissionType.Button)
{
ButtonService service = new ButtonService();
ActionButton action = null;
if (service.Find(o => o.Url == url).Any())
action = service.Find(o => o.Url == url).First();
if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
return mage.CheckPermission(action);
}
if (type == PermissionType.Menu)
{
MenuService service = new MenuService();
Menu action = null;
if (service.Find(o => o.Url == url).Any())
action = service.Find(o => o.Url == url).First();
if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
return mage.CheckPermission(action);
}
if(type== PermissionType.Module)
{
ModuleService service = new ModuleService();
Module action = null;
if (service.Find(o => o.Url == url).Any())
action = service.Find(o => o.Url == url).First();
if (action == null) throw (new Exception("没有找到指定URL的操作,请确定URL和TYPE正确"));
return mage.CheckPermission(action);
}
return false;
}
}
}
LoginUserService
EF上下文
关健是实体之间的关联关系配置,relevance实体的关联是通过代码逻辑来实现的,其它的是上下文配置的。好像都有注释的。是的,用的正是CodeFirst
using System.Data.Entity;
using YZY.Datas.EF;
using System.Data.Entity.ModelConfiguration.Conventions;
using Domain.DataModels;
namespace EFDbcontext
{
public class RBACDemoContext:EFUnitOfWork
{
public RBACDemoContext() : base("RBACDemoContext") { }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Module> Modules { get; set; }
public virtual DbSet<Role> Roles { get; set; }
public virtual DbSet<Relevance> Relevance { get; set; }
public virtual DbSet<HideFiled> HideFiled { get; set; }
public virtual DbSet<ActionButton> Buttons { get; set; }
public virtual DbSet<Deparentment> Departments { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<Menu> Menus { get; set; }
public virtual DbSet<Dep_Emp> Dep_Emp { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//配置按钮和菜单的1:N关系
modelBuilder.Entity<ActionButton>()
.HasOptional(o => o.Menu)
.WithMany(o => o.Buttons)
.HasForeignKey(o => o.MenuId);
//配置部门的层级关系
modelBuilder.Entity<Deparentment>()
.HasOptional(o => o.Parent).WithMany(o => o.Childs).HasForeignKey(o => o.ParentId);
//配置部门和员工的N:N关系
modelBuilder.Entity<Dep_Emp>().HasKey(o => new { o.DepId, o.EmpId });
modelBuilder.Entity<Dep_Emp>()
.HasRequired(o => o.Dep).WithMany(o => o.Employees).HasForeignKey(o => o.DepId);
modelBuilder.Entity<Dep_Emp>()
.HasRequired(o => o.Emp).WithMany(o => o.Depatments).HasForeignKey(o => o.EmpId);
//配置部门和角色的N:N关系
modelBuilder.Entity<Dep_Role>().HasKey(o => new { o.DepId, o.RoleId });
modelBuilder.Entity<Dep_Role>()
.HasRequired(o => o.Dep).WithMany(o => o.Roles).HasForeignKey(o => o.DepId);
modelBuilder.Entity<Dep_Role>()
.HasRequired(o => o.Role).WithMany(o => o.ManageDeps).HasForeignKey(o => o.RoleId);
//配置模块和菜单的1:N关系
modelBuilder.Entity<Menu>()
.HasOptional(o => o.Module).WithMany(o => o.Menus).HasForeignKey(o => o.ModuleId);
}
}
}
RBACDemoContext
MVC部分:视图模型和登陆鉴权
是的,没有用到DTO。小例子,没必要用上DTO,也没用到json,因为我并没有把后端做成WebApi或是WebService,前端用的也正是.net MVC。
using Domain.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCDemo.Models
{
public class LoginUserResouces
{
public List<Menu> Menus { get; set; }
public List<ActionButton> Buttons { get; set; }
public List<Deparentment> Departs { get; set; }
public List<Employee> Employees { get; set; }
public List<Role> Roles { get; set; }
public List<Module> Modules { get; set; }
public List<User> Users { get; set; }
}
}
LoginUserResouces
我的用户与服务器交互用的是cookie和缓存,没有用session,本来是想用memcached缓存的,但是我的mem装在虚拟机在,开个VS,IIS基本机器要炸了,根本开不了其它的了。无奈之下才用的MS的缓存。
using Domain.DataModels;
using Domain.Service;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
namespace MVCDemo.Controllers
{
public class BaseController:Controller
{
public BaseController()
{
if (new LoginUserService(UserManage<int>.GetCacheUser() as User) != null)
{
lus = new LoginUserService(UserManage<int>.GetCacheUser() as User);
LoadResouce();
}
}
/// <summary>
/// 当前登陆用户
/// </summary>
public User LoginUser { get { return lus.LoginUser; } }
private LoginUserService lus ;
/// <summary>
/// 是否启用登陆检测
/// </summary>
public bool IsCheckLogin { get; set; } = true;
/// <summary>
/// 跳转登陆页前的url
/// </summary>
public string LastUrl { get { return lastUrl; } }
private string lastUrl;
/// <summary>
/// 缓存
/// </summary>
public ICache Cache { get { return DependencyContext.Resolve<ICache>(); } }
public LoginUserResouces Resouces { get { return resouces; } }
private LoginUserResouces resouces = new LoginUserResouces();
/// <summary>
/// 加载用户的所有权限供控制器
/// </summary>
private void LoadResouce()
{
if (lus != null)
{
lus.LoadLoginUserResouces();
resouces.Buttons = lus.Buttons.ToList();
resouces.Departs = lus.Departs.ToList();
resouces.Employees = lus.Employees.ToList();
resouces.Menus = lus.Menus.ToList();
resouces.Roles = lus.Roles.ToList();
resouces.Modules = lus.Modules.ToList();
resouces.Users = lus.Users.ToList();
}
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (IsCheckLogin)
{
//如果没有登陆跳转到登陆页面
if (LoginUser == null)
{
lastUrl = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName + "/"
+ filterContext.ActionDescriptor.ActionName;
//将跳转前的url保存到缓存中
if (Cache.GetCache("LastUrl") == null) Cache.AddCache("LastUrl", lastUrl);
else
{
Cache.DelCache("LastUrl");
Cache.AddCache("LastUrl", lastUrl);
}
filterContext.HttpContext.Response.Redirect("/Login/Index");
}
}
}
}
}
BaseController
基类控制器目前还没有写错误处理和日志记录,又是一个未成品,主要是没写测试,很多功能可能还有错误。下面是鉴权标签类和登陆控制器代码
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using YZY.Domain;
using YZY_RBAC.Core;
namespace MVCDemo.Controllers
{
//指示当前标签类可用于类或者方法,每个类或者方法只能有一个当前标签
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple =false)]
public class UserAuthorizeAttribute:AuthorizeAttribute
{
public PermissionType Type { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
//此处可以通过修改身份认证的provide来获取当前的用户:通过filterContext.HttpContext.User;
//User u = service.LoginUser;
LoginUserService service = null;
if (UserManage<int>.GetCacheUser() != null)
{
service = new LoginUserService(UserManage<int>.GetCacheUser() as User);
}
if (service != null)
{
if (service.LoginUser != null)
{
string conUrl = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
string actUrl = conUrl + "/" + filterContext.ActionDescriptor.ActionName;
string checkUrl = "";
if (Type == PermissionType.Module)
{
checkUrl = conUrl;
}
else
{
checkUrl = actUrl;
}
if (service.LoginUser.IsSysAdmin) return;
bool yn = false;
try { yn = service.CheckActionAuthorize(checkUrl, Type); }
//错误应该不要紧,用户没登陆会自动跳转到登陆页面,直到有用户,所以没有处理catch
catch { }
if (!yn)
{
filterContext.Result = new ContentResult { Content = "你没有权限,不是通过界面搞进来的?" };
/*此处应跳转至错误页面
filterContext.HttpContext.Response.Redirect("url");
或者filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{ "action", url },
{ "controller", url } });*/
}
}
}
}
}
}
UserAuthorizeAttribute
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
namespace MVCDemo.Controllers
{
public class LoginController : BaseController
{
public LoginController() { IsCheckLogin = false; }
private UserService service = new UserService();
private EmpService emService = new EmpService();
// GET: Login
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Account()
{
IsCheckLogin = false;
string acc = Request["Account"];
string pwd = Request["Password"];
string rem = Request["Rember"];
User u = null;
if( !service.Find(o=>o.Account==acc).Any()&& !emService.Find(o => o.Account == acc).Any())
{
return Content("no:帐户不存在");
}
if (service.Find(o => o.Account == acc).Any())
u = service.Find(o => o.Account == acc).First();
else if(emService.Find(o=>o.Account==acc).Any())
{
u = emService.Find(o => o.Account == acc).First();
}
if (u != null)
{
string depwd = UserManage<int>.GetDeCryptPwd(u.Password);
if (depwd == pwd)
{
if (rem == "true" && u != null)
{
UserManage< * * ;
UserManage< * * ;
UserManage<int>.AddCacheUser(u);
}
UserManage<int>.AddCacheUser(u);
if (Cache.GetCache("LastUrl")==null) return Content("ok:/Home/Index");
return Content("ok:/" + Cache.GetCache("LastUrl").ToString());
}
}
return Content("no:密码不正确");
}
}
}
LoginController
本来是为了方便我扩展了控制器的一些方法,结果发现用处不是很大
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;
namespace MVCDemo.Controllers
{
public static class ExtController
{
public static ButtonService btnService { get; set; } = new ButtonService();
public static MenuService menuService { get; set; } = new MenuService();
public static ModuleService modService { get; set; } = new ModuleService();
private static ILogger logger = DependencyContext.Resolve<ILogger>();
/// <summary>
/// 将当前控制器注册到数据库
/// </summary>
/// <param name="controller"></param>
/// <param name="perType"></param>
/// <param name="name"></param>
public static void RegiterToDb
(this Controller controller,PermissionType perType,string name)
{
string controlUrl = controller.RouteData.Values["controller"].ToString().ToLower();
string url = controlUrl + "/" + controller.RouteData.Values["action"].ToString().ToLower();
if(perType== PermissionType.Button)
{
var btn = new ActionButton();
btn.Name = name;
btn.Url = url;
try
{
btnService.Add(btn);
}
catch (Exception ex)
{
throw new CustomWarring("没有添加成功", "UI", logger.LogLevel, ex);
}
return;
}
if(perType== PermissionType.Module)
{
var module = new Module();
module.Name = name;
module.Url = controlUrl;
modService.Add(module);
return;
}
if(perType== PermissionType.Menu)
{
var menu = new Menu();
menu.Name = name;
menu.Url = url;
menuService.Add(menu);
return;
}
throw new CustomWarring("当前权限类型不能用于注册MVC控制器或控制器方法", "UI", logger.LogLevel);
}
public static void BindingButtonToMenu(this Controller controller, string menuName)
{
string url = controller.RouteData.Values["controller"].ToString().ToLower();
url += "/" + controller.RouteData.Values["action"].ToString().ToLower();
var btn = btnService.GetForUrl(url);
var menu = menuService.GetForName(menuName);
btnService.SetToMenu(btn.Name, menuName);
}
public static void BindingMenuToModule(this Controller controller,string moduleName)
{
string url = controller.RouteData.Values["controller"].ToString().ToLower();
url += "/" + controller.RouteData.Values["action"].ToString().ToLower();
var menu = menuService.GetForUrl(url);
menuService.SetIntoModule(menu.Name, moduleName);
}
}
}
ExtController
MVC部分:控制器
不想写字了,直接上代码吧,有问题的欢迎评论,我会积极参与
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;
using Newtonsoft.Json;
namespace MVCDemo.Controllers
{
//整个打成控制器级别的权限,除非被分配了权限,除了开发者其它都进不来
//对于模块,菜单,按钮的添加修改等开发者工作,没有存入数据库中
[UserAuthorize(Type= PermissionType.Module)]
public class AdminController : BaseController
{
private ILogger logger = DependencyContext.Resolve<ILogger>();
private ModuleService modService=new ModuleService();
private MenuService menService=new MenuService();
// GET: Admian
/// <summary>
/// 模块管理菜单
/// </summary>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Menu)]
public ActionResult ModuleManage()
{
if(!menService.Find(o=>o.Name=="模块管理").Any())
{
this.RegiterToDb(PermissionType.Menu, "模块管理");
}
this.BindingMenuToModule("开发人员模块");
return Content(PermissionType.Module.ToString());
}
/// <summary>
/// 菜单管理菜单
/// </summary>
/// <returns></returns>
[UserAuthorize(Type = PermissionType.Menu)]
public ActionResult MenuManage()
{
if (!menService.Find(o => o.Name == "菜单管理").Any())
{
this.RegiterToDb(PermissionType.Menu, "菜单管理");
}
this.BindingMenuToModule("开发人员模块");
return Content(PermissionType.Menu.ToString());
}
/// <summary>
/// 按钮管理菜单
/// </summary>
/// <returns></returns>
[UserAuthorize(Type = PermissionType.Menu)]
public ActionResult ButtonManage()
{
if (!menService.Find(o => o.Name == "按钮管理").Any())
{
this.RegiterToDb(PermissionType.Menu, "按钮管理");
}
this.BindingMenuToModule("开发人员模块");
return Content(PermissionType.Button.ToString());
}
/// <summary>
/// 添加模块
/// </summary>
/// <param name="moduleName"></param>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult AddModule()
{
if (Request["Name"]==null||Request["Url"]==null)
{
throw new CustomWarring("请求参数配置有误");
}
string moduleName = Request["Name"];
string url = Request["Url"];
if (string.IsNullOrEmpty(moduleName)) return Content("no:模块称不能为空");
var module = new Module { Name = moduleName, Url = url, Type=PermissionType.Module.ToString() };
try
{
modService.Add(module);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
catch (Exception) { throw; }
return Content("ok:添加加成功");
}
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult EditModule()
{
string controlName = Request["controlName"];
string name = Request["moduleName"];
string type = Request["type"];
if (string.IsNullOrEmpty(controlName)||string.IsNullOrEmpty(name))
throw new CustomWarring("名称或控制器地址不能为空", "UI", logger.LogLevel);
try
{
var module = modService.GetForName(name);
module.Name = name;
module.Url = controlName;
module.Type = type;
modService.Update(module);
modService.Commit();
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
//这部分错误日志应在基类和配置文件完成
catch (Exception ex) { logger.Log("", ex); throw; }
return Content("ok:修改成功");
}
/// <summary>
/// 添加按钮
/// </summary>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult AddButton()
{
if (Request["Name"]==null
|| Request["Url"] == null
|| Request["MenuName"] == null)
{
throw new Exception("请求参数配置有误");
}
string name = Request["Name"];
string url = Request["Url"];
string menuName = Request["MenuName"];
if (name == string.Empty || url == null) return Content("no:名称或地址不能为空");
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(url)) return Content("no:名称或地址不能空");
try
{
ButtonService btnService = new ButtonService();
ActionButton btn = new ActionButton
{ Name = name, Url = url, RoleType = PermissionType.Button.ToString() };
btnService.Add(btn);
if (!string.IsNullOrEmpty(menuName)) btnService.SetToMenu(name, menuName);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
catch (Exception) { throw; }
return Content("ok:添加加成功");
}
/// <summary>
/// 修改按钮
/// </summary>
/// <returns></returns>
public ActionResult EditBtn()
{
try
{
string json = Request["btnJson"];
int n;int id;
if (!int.TryParse(Request["btnId"], out n)) throw new Exception();
id = n;
ActionButton btn = JsonConvert.DeserializeObject<ActionButton>(Request["btnJson"]);
if (string.IsNullOrEmpty(btn.Name)) return Content("no:名称不能为空");
if (string.IsNullOrEmpty(btn.Url)) return Content("no:地址不能为空");
var service = new ButtonService();
var change = service.Find().Single(o => o.Id == id);
if (service.Find(o => o.Name == btn.Name&&o.Name!=change.Name).Any()) return Content("no:数据库中已有该名称的按钮");
if (service.Find(o => o.Url == btn.Url&&o.Url!=change.Url).Any()) return Content("数据库中已有该地址的按钮");
change.Icon = btn.Icon;
change.Name = btn.Name;
change.RoleType = btn.RoleType;
change.Url = btn.Url;
service.Update(change);
service.Commit();
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
//这部分错误日志应在基类和配置文件完成
catch (Exception ex) { logger.Log("",ex); throw; }
return Content("ok:添加加成功");
}
/// <summary>
/// 添加菜单
/// </summary>
/// <returns></returns>
[UserAuthorize(Type = PermissionType.Button)]
public ActionResult AddMenu()
{
if (Request["Name"] == null
|| Request["Url"] == null
|| Request["ModuleName"] == null)
{
throw new Exception("请求参数配置有误");
}
string name = Request["Name"];
string url = Request["Url"];
string moduleName = Request["ModuleName"];
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(url)) return Content("no:名称或地址不能空");
try
{
Menu menu = new Menu { Name = name, Url = url,RoleType=PermissionType.Menu.ToString() };
menService.Add(menu);
if (!string.IsNullOrEmpty(moduleName)) menService.SetIntoModule(name, moduleName);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
catch (Exception) { throw; }
return Content("ok:添加加成功");
}
[UserAuthorize(Type = PermissionType.Button)]
public ActionResult AuthorizeAppManager()
{
string userid = Request["UserId"];
if (userid == null) throw new Exception();
try
{
int id = int.Parse(userid);
var manager = new UserService().FindById(id);
AuthorizeService<User>.InitiaRbac();
AuthorizeService<User>.Authorize
(manager,modService.Find().Where(o => o.Name != "开发人员模块").AsEnumerable(), PermissionType.Module);
AuthorizeService<User>.Authorize
(manager, menService.Find()
.Where(o => o.Name != "模块管理"
&&o.Name!= "菜单管理" && o.Name!= "按钮管理").AsEnumerable(), PermissionType.Menu);
AuthorizeService<User>.Authorize
(manager, new ButtonService().Find().AsEnumerable(), PermissionType.Button);
AuthorizeService<User>.Authorize
(manager, new UserService().Find()
.Where(o => o.IsSysAdmin ==false).AsEnumerable(), PermissionType.User);
AuthorizeService<User>.Authorize
(manager, new DepartmentService().Find().AsEnumerable(), PermissionType.Group);
AuthorizeService<User>.Authorize
(manager, new RoleService().Find().AsEnumerable(), PermissionType.Role);
AuthorizeService<User>.Authorize
(manager, new EmpService().Find().AsEnumerable(), PermissionType.Data);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
catch (Exception) { throw; }
return Content("ok:已成功添加网站管理员");
}
}
}
AdminController
using Domain.DataModels;
using Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
using YZY_RBAC.Core;
namespace MVCDemo.Controllers
{
[UserAuthorize(Type = PermissionType.Module)]
public class RoleModuleController : BaseController
{
// GET: Role
public ActionResult RoleManage()
{
try
{
if (!new MenuService().Find(o => o.Name == "角色管理").Any())
{
this.RegiterToDb(PermissionType.Menu, "角色管理");
this.BindingMenuToModule("管理员操作模块");
}
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
return Content("ok:角色管理菜单添加成功");
}
/// <summary>
/// 添加角色
/// </summary>
/// <param name="role"></param>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult AddRole()
{
string roleName = Request["Name"];
string roleType = Request["Type"];
Role role = new Role { RoleName = roleName, RoleType = roleType };
try
{
new RoleService().Add(role);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
return Content("ok:角色" + role.RoleName + "添加成功");
}
/// <summary>
/// 为角色添加权限
/// </summary>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult AuthorizeForRole()
{
string roleName = Request["RoleName"];
string type = Request["Type"];
string targetName = Request["TargetName"];
if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色不能为空");
try
{
Role role = new RoleService().GetForName(roleName);
Helper.AuthorizeMenyForType(role, targetName, type);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
string successMsg = string.Format("ok:已成功为角色{0}添加{1}权限", roleName, targetName);
return Content(successMsg);
}
/// <summary>
/// 取消角色的权限
/// </summary>
/// <returns></returns>
[UserAuthorize(Type = PermissionType.Button)]
public ActionResult CancelAuthorize()
{
string roleName = Request["RoleName"];
string type = Request["Type"];
string targetName = Request["TargetName"];
if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色不能为空");
try
{
Role role = new RoleService().GetForName(roleName);
Helper.CancelAuthorizeMenyForType(role, targetName, type);
}
catch (CustomWarring cw)
{
if (cw.Code == "UI") return Content("no:" + cw.Message);
throw cw;
}
string successMsg = string.Format("ok:已成功为角色{0}添加{1}权限", roleName, targetName);
return Content(successMsg);
}
/// <summary>
/// 为角色分配可管理的部门
/// </summary>
/// <returns></returns>
[UserAuthorize(Type=PermissionType.Button)]
public ActionResult AllotDepartment()
{
string roleName = Request["RoleName"];
if (roleName == null || string.IsNullOrEmpty(roleName)) return Content("no:角色名称不能为空");
if (Request["DepNames"]==null||Request["DepNames"]==string.Empty) return Content("no:目权限名称不能空");
try
{
var depNames = Helper.GetNamesArray(Request["DepNames"]);
var role = new RoleService().GetForName(roleName);
var service = new Dep_RoleService();
var depService = new DepartmentService();
foreach (var name in depNames)
{
var dep = depService.GetForName(name);
service.Add(new Dep_Role { RoleId = role.Id, DepId = dep.Id });
}
service.Commit();
}
catch (Exception)
{
return Content("no:添加失败");
throw ;
}
string successMsg = "ok:角色已成功分配到部门" ;
return Content(successMsg);
}
}
}
RoleModuleController
using Domain.DataModels;
using Domain.Service;
using MVCDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YZY.Domain;
namespace MVCDemo.Controllers
{
public class HomeController :BaseController
{
// GET: Home
public ActionResult Index()
{
//测试插入一个用户
if (!new UserService().Find(o => o.Name == "test").Any())
{
new UserService().Add(new User
{
Name = "test",
Account = "test",
Password = ",
Telphone = "
});
}
ViewBag.IsAdmin = false;
ViewBag.PerTypes = Helper.GetUITypes();
if (LoginUser != null)
{
ViewBag.UserName = LoginUser.Name;
ViewBag.IsAdmin = LoginUser.IsSysAdmin;
}
else { ViewBag.UserName = "游客"; }
LoginUserResouces lr = new LoginUserResouces();
lr = Resouces;
return View(lr);
}
public ActionResult LogOut()
{
if (Cache.GetCache("LastUrl") == null) Cache.AddCache("LastUrl", "Home/Index");
Cache.DelCache("LastUrl"); Cache.AddCache("LastUrl", "Home/Index");
return new EmptyResult();
}
}
}
HomeController
MVC部分:视图
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<script src="~/scripts/jquery-1.9.1.min.js"></script>
<script src="~/scripts/bootstrap.min.js"></script>
<title>登陆</title>
<style type="text/css">
body{
background-color:#2F4051;
}
.login-holder {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
-ms-border-radius: 6px;
-o-border-radius: 6px;
border-radius: 6px;
position: absolute;
top: %;
left: %;
display: block;
margin-top: -185px;
margin-left: -205px;
width: 420px;
height: auto;
background: white;
padding: 10px;
}
.login-holder .form-footer {
padding: 20px;
}
</style>
<script type="text/javascript">
$(function () {
$("#btn").click(function () {
$.post("/Login/Account",
{
"Account": $("#Account").val(),
"Password": $("#Password").val(),
"Rember": $("#Rember").is(":checked")
},
function (data) {
var yn = data.split(':');
] == "ok") {
window.location.href = yn[];
}
else {
alert(yn[]);
}
})
});
});
</script>
</head>
<body>
<div>
<div class="login-holder col-md-6 col-md-offset-3">
<h2 class="page-header text-center text-primary"> 欢迎!请登陆 </h2>
<form role="form" method="post">
<div class="form-group">
<input class="form-control" id="Account" type="text" placeholder="输入帐号">
</div>
<div class="form-group">
<input class="form-control" id="Password" type="password" placeholder="输入密码">
</div>
<div class="form-footer">
<label>
<input id="> 一个月免登陆
</label><br />
<button class="btn btn-info btn-submit" id="btn" type="button">登陆</button>
</div>
</form>
</div>
</div>
</body>
</html>
登陆
现在只做出来两个视图,完成前面展示效果,Home视图抠的一个模板,所以有很多的JS和CSS文件,自己尝试写过,太痛苦了,所以干脆全扒下来算了,时间都浪费在上面划不来
@{
Layout = null;
}
@model MVCDemo.Models.LoginUserResouces
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>首页</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Loading Bootstrap -->
<link href="~/aaaa/css/bootstrap.min.css" rel="stylesheet" />
<!-- Loading Stylesheets -->
<link href="~/aaaa/css/font-awesome.css" rel="stylesheet">
<link href="~/aaaa/css/style.css" rel="stylesheet" type="text/css">
<link href="~/aaaa/less/style.less" rel="stylesheet" title="lessCss" id="lessCss">
<!-- Loading Custom Stylesheets -->
<link href="~/aaaa/css/custom.css" rel="stylesheet">
<link rel="shortcut icon" href="~/aaaa/images/favicon.ico">
<!-- Load JS here for Faster site load =============================-->
<script src="~/aaaa/js/jquery-1.10.2.min.js"></script>
<script src="~/aaaa/js/jquery-ui-1.10.3.custom.min.js"></script>
<script src="~/aaaa/js/less-1.5.0.min.js"></script>
<script src="~/aaaa/js/jquery.ui.touch-punch.min.js"></script>
<script src="~/aaaa/js/bootstrap.min.js"></script>
<script src="~/aaaa/js/bootstrap-select.js"></script>
<script src="~/aaaa/js/bootstrap-switch.js"></script>
<script src="~/aaaa/js/jquery.tagsinput.js"></script>
<script src="~/aaaa/js/jquery.placeholder.js"></script>
<script src="~/aaaa/js/bootstrap-typeahead.js"></script>
<script src="~/aaaa/js/application.js"></script>
<script src="~/aaaa/js/moment.min.js"></script>
<script src="~/aaaa/js/jquery.dataTables.min.js"></script>
<script src="~/aaaa/js/jquery.sortable.js"></script>
<script src="~/aaaa/js/jquery.gritter.js" type="text/javascript"></script>
<script src="~/aaaa/js/jquery.nicescroll.min.js"></script>
<script src="~/aaaa/js/skylo.js"></script>
<script src="~/aaaa/js/prettify.min.js"></script>
<script src="~/aaaa/js/jquery.noty.js"></script>
<script src="~/aaaa/js/bic_calendar.js"></script>
<script src="~/aaaa/js/jquery.accordion.js"></script>
<script src="~/aaaa/js/theme-options.js"></script>
<script src="~/aaaa/js/bootstrap-progressbar.js"></script>
<script src="~/aaaa/js/bootstrap-progressbar-custom.js"></script>
<script src="~/aaaa/js/bootstrap-colorpicker.min.js"></script>
<script src="~/aaaa/js/bootstrap-colorpicker-custom.js"></script>
<!-- Core JS =============================-->
<script src="~/aaaa/js/core.js"></script>
<style type="text/css">
.yuandian{
margin-right:20px;
}
</style>
<script type="text/javascript">
$(function () {
//设置全局初始变量
).find("span[class='hidden']")
var leftMenuName = $(selectMenu).attr("menuname");
var leftMenuUrl = $(selectMenu).attr("url");
var leftMenuId = $(selectMenu).attr("menuid");
var btns = $('#actionbtnlist').children("a");
//对非开发人员隐藏按钮
function hiddenBtn(){
if (leftMenuName == "按钮管理") {
if ($("#authorize").hasClass("hidden")) {
$("#authorize").removeClass("hidden")
}
if ($("#add").hasClass("hidden")) {
$("#add").removeClass("hidden")
}
}
else if (leftMenuName == "模块管理") {
if ($("#authorize").hasClass("hidden")) {
$("#authorize").removeClass("hidden")
}
if ($("#add").hasClass("hidden")) {
$("#add").removeClass("hidden")
}
}
else if (leftMenuName == "菜单管理") {
if ($("#authorize").hasClass("hidden")) {
$("#authorize").removeClass("hidden")
}
if ($("#add").hasClass("hidden")) {
$("#add").removeClass("hidden")
}
}
else {
$("#authorize").addClass("hidden")
$("#add").addClass("hidden")
}
}
hiddenBtn()
//清除模态框
function clear() {
$('#addModal').find("input").addClass("hidden").attr("placeholder", "")
$('#addModal').find("input").val('')
$('#addModal').find('textarea').val('')
$("#modalTitle").html("");
}
clear();
//界面转换
function change() {
clear()
//菜单界面
var menu = document.getElementById(leftMenuUrl);
$("#head").find("span[class='menu-title']").html(leftMenuName);
if ($(menu).hasClass("hidden")) {
$(menu).removeClass("hidden");
$(menu).siblings().addClass("hidden");
}
//按钮界面
$(btns).each(function () {
if ($(this).attr("menuid") == leftMenuId) {
if ($(this).hasClass('hidden')) {
$(this).removeClass("hidden")
}
}
else {
if ($(this).not(":hidden")) {
$(this).addClass('hidden')
}
}
})
}
change()
//模态框设置
$('.modal').on('show.bs.modal', function () {
$();
})
$('.modal').on('hidden.bs.modal', clear())
//重新登陆
$("#Logout").click(function () {
$.post("/Home/LogOut", {}, function () {
window.location.href = "/Login/Index";
})
})
//菜单点击界面响应
$(".menu").click(function () {
leftMenuId=$(this).children("span[class='hidden']").attr("menuid")
leftMenuUrl = $(this).children("span[class='hidden']").attr("url")
leftMenuName = $(this).children("span[class='hidden']").attr("menuname")
change()
hiddenBtn()
})
//添加按钮点击事件
$("#add").click(function () {
clear()
var modalele = $('#addModal')
var name = $(modalele).find("input[id='name']")
var url = $(modalele).find("input[id='url']")
var account = $(modalele).find("input[id='account']")
var password = $(modalele).find("input[id='password']")
var telphone = $(modalele).find("input[id='telphone']")
var targetname = $(modalele).find("input[id='targetname']")
if (leftMenuName == "模块管理") {
addModule(name, url, modalele)
}
else if (leftMenuName == "菜单管理") {
addMenu(name, url, targetname, modalele)
}
else if (leftMenuName == "按钮管理") {
addBtn(name, url, targetname, modalele)
}
$(modalele).find("attr[data-dismiss='modal']").click(clear)
})
//添加模块
function addModule(name, url,modalele) {
$("#modalTitle").html("添加模块");
name.removeClass("hidden").attr("placeholder", "输入要添加的模块名称");
url.removeClass("hidden").attr("placeholder", "输入要添加的模块控制器地址");
$(modalele).modal("show");
var submit = $(modalele).find("button[id='modalSubmit']")
$(submit).click(function () {
$.post("/admin/addmodule",
{
"Name": name.val(),
"Url":url.val()
},
function (data) {
var datas = data.split(':');
] == "ok") {
window.location.reload();
}
else
{
alert(datas[])
clear()
}
})
})
}
//添加菜单
function addMenu(name, url, modulename,modalele) {
$("#modalTitle").html("添加菜单");
name.removeClass("hidden").attr("placeholder", "输入要添加的菜单名称");
url.removeClass("hidden").attr("placeholder", "输入要添加的菜单地址");
modulename.removeClass("hidden").attr("placeholder", "输入要添加到的模块名称")
modalele.modal("show");
var submit = $(modalele).find("button[id='modalSubmit']")
$(submit).click(function () {
$.post("/admin/addmenu",
{
"Name": name.val(),
"Url": url.val(),
"ModuleName": modulename.val()
},
function (data) {
var datas = data.split(':');
] == "ok") {
window.location.reload();
clear()
}
else {
alert(datas[])
}
})
})
}
//添加按钮
function addBtn(name, url, menuname, modalele) {
$("#modalTitle").html("添加按钮");
name.removeClass("hidden").attr("placeholder", "输入要添加的按钮名称")
url.removeClass("hidden").attr("placeholder", "输入按钮访问地址")
menuname.removeClass("hidden").attr("placeholder", "输入要添加到的菜单名称")
modalele.modal("show");
var submit = $(modalele).find("button[id='modalSubmit']")
$(submit).click(function () {
$.post("/admin/addbutton",
{
"Name": name.val(),
"Url": url.val(),
"MenuName": menuname.val()
},
function (data) {
var datas = data.split(':');
] == "ok") {
window.location.reload();
clear()
}
else {
alert(datas[])
}
})
})
}
//查看,修改模态框
$("#ManageEditModal").on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
var name = button.data('name')
var url = button.data('url')
var type = button.data('type')
var action = button.data('action')
var btnId = button.data('btnid')
if (action == "btnEdit") {
$(this).find('.modal-title').text('编辑' + name+'按钮')
$(this).find('input').attr("readonly", null)
$(this).find("input[id='name']").val(name)
$(this).find("input[id='url']").val(url)
$(this).find("textarea[id='type']").val(type).attr("readonly",null)
$(this).find('button[id="editSubmit"]').removeClass("hidden")
.click(function () {
name = $('#ManageEditModal').find("input[id='name']").val()
url = $('#ManageEditModal').find("input[id='url']").val()
type = $('#ManageEditModal').find("textarea[id='type']").val()
$.post("/admin/editbtn",
{
"btnJson": '{"Name":"' + name + '","Url":"'
+ url + '","RoleType":"' +
type + '"}',
"btnId":btnId
},
function (data) {
var input = data.split(':');
] == "ok") {
$('#ManageEditModal').on("hidden")
window.location.reload()
}
]=="no") {
alert(input[])
}
})
})
}
if (action == "btnLook") {
$(this).find('.modal-title').text('查看' + name + '按钮')
$(this).find('input').attr("readonly","")
$(this).find("input[id='name']").val(name)
$(this).find("input[id='url']").val(url)
$(this).find("textarea[id='type']").val(type).attr("readonly","")
$(this).find('button[id="editSubmit"]').addClass("hidden")
}
})
var authorUser = $("#admin-authouser-tbody").children('tr').children('td').children('div').children('a')
authorUser.click(function () {
$.post("/admin/AuthorizeAppManager", {
"UserId":$(this).attr("userid")
},
function (data) {
var query = data.split(':')
alert(query[])
window.location.reload(query[] == "ok")
})
})
//按钮集合点击事件
$(btns).click(function () {
) {
//找出模态框
var modalele = $('#addModal')
//找出需要的控件
var name = $(modalele).find("input[id='name']")
var roletype = $(modalele).find("input[id='url']")
//显示模态框和相关控件
$("#modalTitle").html("添加按钮");
name.removeClass("hidden").attr("placeholder", "输入要添加的角色名称")
roletype.removeClass("hidden").attr("placeholder", "输入角色的类型")
modalele.modal("show");
//设置访问地址
var url = "/" + $(this).attr("url")
var submit = $(modalele).find("button[id='modalSubmit']")
$(submit).click(function () {
$.post(url,
{
"Name": $(name).val(),
"Type": $(roletype).val()
},
function (data) {
var serverdatas = data.split(':')
alert(serverdatas[])
$(modalele).on('hidden')
] == "ok") {
window.location.reload()
}
})
})
}
})
})
</script>
</head>
<body>
<div class="site-holder">
<!--横向导航 -->
<nav class="navbar" role="navigation">
<!-- Logo -->
<div class="navbar-header">
<a class="navbar-brand" >
<i class="fa fa-list btn-nav-toggle-responsive text-white"></i>
<span class="logo">
RBAC<strong>Test</strong>Demo <i class="fa fa-bookmark"></i>
</span>
</a>
</div>
<!-- 右侧图标 -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav user-menu navbar-right ">
<!--用户图标-->
<li>
<a href="#" class="settings dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user"></i>
</a>
<ul class="dropdown-menu">
<li><a><i class="fa fa-user"></i> @ViewBag.UserName</a></li>
<li class="divider"></li>
<li><a id="Logout" class="text-danger"><i class="fa fa-lock"></i>重新登陆</a></li>
</ul>
</li>
<!--样式颜色设置开关-->
<li>
<a href="#" class="settings">
<i </span>
</a>
</li>
</ul>
</div>
</nav>
<!--主体部分 -->
<div class="box-holder">
<!-- 左侧竖向导航 -->
<div class="left-sidebar">
<div class="sidebar-holder">
<ul class="nav nav-list">
<!-- 左侧导航开头 -->
<li class="nav-toggle">
<button class="btn btn-nav-toggle text-primary"><i class="fa fa-angle-double-left toggle-left"></i> </button>
</li>
<!--模块-->
@foreach (var item in Model.Modules)
{
<li>
<a class="dropdown" data-original-title=@item.Name>
<i class="fa fa-paperclip"></i>
<span class="hidden-minibar"><strong> @item.Name</strong> </span>
</a>
@if (Model.Menus.Where(o => o.ModuleId == item.Id).Any())
{
<ul id="menulist">
<!--菜单-->
@foreach (var menu in Model.Menus.Where(o => o.ModuleId == item.Id))
{
if (menu.ModuleId == item.Id)
{
<li class="menu">
<a data-original-title=@menu.Name>
<i class="fa fa-pencil"></i>
<span class="hidden-minibar"> @menu.Name</span>
</a>
<span menuname="@menu.Name" url="@menu.Url" menuid="@menu.Id"class="hidden" ></span>
</li>
}
}
</ul>
}
</li>
}
</ul>
</div>
</div>
<!-- 开发者或管理员界面 -->
<div class="content" id="managerView">
<div class="row">
<div class="col-mod-12">
<!--面包屑导航-->
@*<ul class="breadcrumb">
<li><a >Dashboard</a></li>
<li><a >Tables</a></li>
<li class="active">Dynamic Tables</li>
</ul>*@
<!--搜索框-->
@*<div class="form-group hiddn-minibar pull-right">
<input type="text" class="form-control form-cascade-control nav-input-search"
size=" placeholder="Search through site" />
<span class="input-icon fui-search"></span>
</div>*@
<!--标题-->
<h3 id="head" class="page-header">
<span class="menu-title"></span>
<i class="fa fa-info-circle animated bounceInDown show-info"></i>
</h3>
<!--横块-->
<blockquote class="page-information hidden ">
<p>
</p>
</blockquote>
</div>
</div>
<div class="row inbox">
<!--操作集合-->
<div id="manageActionContaner" class="col-md-2 mail-left-box">
<div class="panel panel-cascade">
<div class="panel-heading ">
<h3 class="text-primary panel-title">
<i class="fa fa-align-justify"></i> 操作按钮
<span class="pull-right">
<a class="panel-minimize"><i class="fa fa-chevron-up"></i></a>
</span>
</h3>
</div>
<div class="panel-body buttons-demo">
<div class="row">
<div id="actionbtnlist" class="col-md-12">
@{
var colors = new List<string>
{
"btn btn-success btn-block",
"btn btn-info btn-block",
"btn btn-warning btn-block"
};
;
}
@foreach (var item in Model.Buttons)
{
) { n = ; }
var color = colors[n];
<a class="@color hidden" url="@item.Url" menuid="@item.MenuId"> @item.Name</a>
n++;
}
<br />
</div>
</div> <!-- Large Buttons -->
</div>
</div>
<div class="panel panel-cascade">
<div class="panel-heading ">
<h3 class="panel-title text-primary">
<i class="fa fa-align-justify"></i> 其他数据
<span class="pull-right">
<a class="panel-minimize"><i class="fa fa-chevron-up"></i></a>
</span>
</h3>
</div>
<div class="panel-body list-group inbox-options">
<a class="list-group-item"><i class="fa fa-inbox"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-bolt"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-magic"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-bookmark-o"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-check-square-o"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-ban"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-trash-o"></i> 其他数据 </a>
<a class="list-group-item"><i class="fa fa-archive"></i> 其他数据 </a>
</div>
</div>
</div>
<!--菜单对应视图数据-->
<div id="manageMenuContainer" class="col-md-10 mail-right-box">
<!--头部-->
<div class="mail-options-nav">
<div class="mail-pagination btn-group yuandian">
<h4 class="text-primary">
<i class="fa fa-align-justify"></i> 列表展示
</h4>
</div>
<div class="btn-group mail-options popover-options">
<a id="add" class="btn btn-success"><i class="fa fa-archive"></i> 添加</a>
<a id="authorize" class="btn btn-warning" >
<i class="fa fa-ban"></i>
删除
</a>
</div>
<div class="mail-pagination pull-right ">
<label - of </label>
<a class="btn btn-default"><i class="fa fa-angle-double-left"></i></a>
<a class="btn btn-default"><i class="fa fa-angle-double-right"></i></a>
<a class="btn btn-info"><i class="fa fa-cogs"></i></a>
</div>
</div>
<div class="mails">
<!----------------- 模块管理------------->
<div id="admin/modulemanage" class="hidden">
<table class="table table-bordered table-hover table-striped display">
<thead>
<tr>
<th class="text-center">
<input type="checkbox" />
</th>
<th class="text-center">模块名称</th>
<th class="text-center">地址</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Modules)
{
var edit = "edit-" + item.Id;
var del = "del-" + item.Id;
var see = "see-" + item.Id;
<tr class="odd gradeX">
<td class="text-center">
<input type="checkbox" />
</td>
<td class="text-center "> @item.Name</td>
<td class="text-center "> @item.Url </td>
<td class="text-center ">
<div class="btn-group mail-options">
<a id="@edit" class="btn btn-success btn-sm">
<i class="fa fa-edit"></i> 编辑
</a>
<a id="@see" class="btn btn-warning btn-sm">
<i class="fa fa-trash-o"></i> 查看
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<!------------------菜单管理------------>
<div id="admin/menumanage" class="hidden">
<table class="table table-bordered table-hover table-striped display">
<thead>
<tr>
<th class="text-center">
<input type="checkbox" />
</th>
<th class="text-center">名称</th>
<th class="text-center">地址</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Menus)
{
var edit = "edit-" + item.Id;
var del = "del-" + item.Id;
var see = "see-" + item.Id;
<tr class="odd gradeX">
<td class="text-center">
<input type="checkbox" />
</td>
<td class="text-center "> @item.Name</td>
<td class="text-center "> @item.Url </td>
<td class="text-center ">
<div class="btn-group mail-options">
<a id="@see" class="btn btn-warning btn-sm">
<i class="fa fa-trash-o"></i> 查看
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<!-------------------按钮管理------------>
<div id="admin/buttonmanage" class="hidden">
<table id="btnManageTable" class="table table-bordered table-hover table-striped display">
<thead>
<tr>
<th class="text-center">
<input type="checkbox" />
</th>
<th class="text-center">名称</th>
<th class="text-center">地址</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Buttons)
{
<tr class="odd gradeX">
<td class="text-center">
<input type="checkbox" />
</td>
<td class="text-center "> @item.Name</td>
<td class="text-center "> @item.Url </td>
<td class="text-center ">
<div class="btn-group mail-options">
<a class="btn btn-success btn-sm"
data-toggle="modal"
data-target="#ManageEditModal"
data-name="@item.Name"
data-url="@item.Url"
data-type="@item.RoleType"
data-action="btnEdit"
data-btnid="@item.Id">
<i class="fa fa-edit"></i> 编辑
</a>
<a class="btn btn-warning btn-sm"
data-toggle="modal"
data-target="#ManageEditModal"
data-name="@item.Name"
data-url="@item.Url"
data-type="@item.RoleType"
data-action="btnLook"
data-btnid="@item.Id">
<i class="fa fa-trash-o"></i> 查看
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<!-------------------开发人员授权管理------------>
<div id="admin/menu" class="hidden">
<table id="admin-authouser-table" class="table table-bordered table-hover table-striped display">
<thead>
<tr>
<th class="text-center">
<input type="checkbox" />
</th>
<th class="text-center">用户名称</th>
<th class="text-center">帐号</th>
<th class="text-center">电话</th>
</tr>
</thead>
<tbody id="admin-authouser-tbody">
@foreach (var item in Model.Users)
{
if (!item.IsSysAdmin)
{
<tr class="odd gradeX">
<td class="text-center">
<input type="checkbox" />
</td>
<td class="text-center "> @item.Name</td>
<td class="text-center "> @item.Account </td>
<td class="text-center"> @item.Telphone</td>
<td class="text-center ">
<div class="btn-group mail-options">
<a userid="@item.Id" class="btn btn-success btn-sm">
<i class="fa fa-edit"></i> 授权为网站管理员
</a>
</div>
</td>
</tr>
}
}
</tbody>
</table>
</div>
<!-------------------角色管理------------>
<div id="rolemodule/rolemanage" class="hidden">
<table class="table table-bordered table-hover table-striped display">
<thead>
<tr>
<th class="text-center">
<input type="checkbox" />
</th>
<th class="text-center">角色名称</th>
<th class="text-center">角色类型</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Roles)
{
var edit = "edit-" + item.Id;
var del = "del-" + item.Id;
var see = "see-" + item.Id;
<tr class="odd gradeX">
<td class="text-center">
<input type="checkbox" />
</td>
<td class="text-center "> @item.RoleName</td>
<td class="text-center "> @item.RoleType </td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-----------------------------模态框----------------------------------------------->
<!--添加框-->
<div class="modal fade" id="addModal" tabindex="-1"
role="dialog" aria-labelledby="addModuleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<button type="button" class="close text-white"
data-dismiss="modal" aria-hidden="true">
×
</button>
<h3 id="modalTitle" class="modal-title">Subject</h3>
</div>
<div class="modal-body">
<div class="icon-show">
<form id="addForm" role="form">
<div class="form-group">
<input class="form-control" id="name" type="text" placeholder="">
</div>
<div class="form-group">
<input class="form-control" id="url" type="text" placeholder="">
</div>
<div class="form-group">
<input class="form-control" id="account" type="text" placeholder="">
</div>
<div class="form-group">
<input class="form-control" id="password" type="password" placeholder="">
</div>
<div class="form-group">
<input class="form-control" id="telphone" type="text" placeholder="">
</div>
<div class="form-group">
<input class="form-control" id="targetname" type="text" placeholder="">
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button id="close" data-dismiss="modal" type="button" class="btn bg-primary text-white">退出</button>
<button id="modalSubmit" type="button" class="btn bg-primary text-white">提交</button>
</div>
</div>
</div>
</div>
<!--修改框-->
<div class="modal fade" id="ManageEditModal" tabindex="-1"
role="dialog" aria-labelledby="ManageEditModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<button type="button" class="close text-white"
data-dismiss="modal" aria-hidden="true">
×
</button>
<h3 id="modalTitle" class="modal-title">编辑</h3>
</div>
<div class="modal-body">
<div class="icon-show">
<form id="ManageEditForm" role="form" class="form-horizontal">
<div class="form-group">
<label id="labelName" for="name" class="control-label col-md-2">按钮名称</label>
<div class="col-md-10">
<input class="form-control" id="name" type="text" placeholder="">
</div>
</div>
<div class="form-group">
<label id="labelUrl" for="url" class="control-label col-md-2">地址</label>
<div class="col-md-10">
<input class="form-control" id="url" type="text" placeholder="">
</div>
</div>
<div class="form-group">
<label id="labelType" for="type" class="control-label col-md-2">属性</label>
<div class="col-md-10">
<textarea rows=" class="form-control" id="type" type="text" ></textarea>
</div>
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button id="close" data-dismiss="modal" type="button" class="btn bg-primary text-white">退出</button>
<button id="editSubmit" type="button" class="btn bg-primary text-white">提交修改</button>
</div>
</div>
</div>
</div>
</div>
<!--用户界面-->
<div id="userView" class="content hidden">
</div>
<!-- 右侧页面编辑模块 -->
<div class="right-sidebar right-sidebar-hidden">
<div class="right-sidebar-holder">
<h4 class="page-header text-primary text-center">
页面样式颜色选项
</h4>
<ul class="list-group theme-options">
<!---样式-->
<li class="list-group-item" href="#">
<div class="checkbox">
<label>
<input type="checkbox" id="fixedNavbar" value=""> 顶部导航栏
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="fixedNavbarBottom" value=""> 底部导航栏
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="boxed" value=""> 缩小居中
</label>
</div>
<div class="form-group backgroundImage hidden">
<label class="control-label">Paste Image Url and then hit enter</label>
<input type="text" class="form-control" id="backgroundImageUrl" />
</div>
</li>
<!--颜色-->
<li class="list-group-item" href="#">
颜色搭配选项
<ul class="list-inline predefined-themes">
<li><a class="badge" style="background-color:#54b5df" data-color-primary="#54b5df" data-color-secondary="#2f4051" data-color-link="#FFFFFF"> </a></li>
<li><a class="badge" style="background-color:#d85f5c" data-color-primary="#d85f5c" data-color-secondary="#f0f0f0" data-color-link="#474747"> </a></li>
<li><a class="badge" style="background-color:#3d4a5d" data-color-primary="#3d4a5d" data-color-secondary="#edf0f1" data-color-link="#777e88"> </a></li>
<li><a class="badge" style="background-color:#A0B448" data-color-primary="#A0B448" data-color-secondary="#485257" data-color-link="#AFB5AA"> </a></li>
<li><a class="badge" style="background-color:#2FA2D1" data-color-primary="#2FA2D1" data-color-secondary="#484D51" data-color-link="#A5B1B7"> </a></li>
<li><a class="badge" style="background-color:#2f343b" data-color-primary="#2f343b" data-color-secondary="#525a65" data-color-link="#FFFFFF"> </a></li>
</ul>
</li>
<li class="list-group-item">
主体颜色
<div class="input-group colorpicker-component bscp" data-color="#54728c" data-color-format="hex" id="colr">
<span class="input-group-addon"><i style="background-color: #54728c"></i></span>
<input type="text" value="#54728c" id="primaryColor" readonly class="form-control" />
</div>
</li>
<li class="list-group-item" href="#">
左侧导航背景颜色
<div class="input-group colorpicker-component bscp" data-color="#f9f9f9" data-color-format="hex" id="Scolr">
<span class="input-group-addon"><i style="background-color: #f9f9f9"></i></span>
<input type="text" value="#f9f9f9" id="secondaryColor" readonly class="form-control" />
</div>
</li>
<li class="list-group-item" href="#">
左侧导航字体颜色
<div class="input-group colorpicker-component bscp" data-color="#54728c" data-color-format="hex" id="Lcolr">
<span class="input-group-addon"><i style="background-color: #54728c"></i></span>
<input type="text" value="#54728c" id="linkColor" readonly class="form-control" />
</div>
</li>
<li class="list-group-item" href="#">
右侧导航背景色
<div class="input-group colorpicker-component bscp" data-color="#f9f9f9" data-color-format="hex" id="Rcolr">
<span class="input-group-addon"><i style="background-color: #f9f9f9"></i></span>
<input type="text" value="#f9f9f9" id="rightsidebarColor" readonly class="form-control" />
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
首页
做前端界面真的好痛苦啊,不知道有没调试的工具。我都不想干这种义务劳动了。
用最基本的EF+MVC+JQ+AJAX+bootstrap实现权限管理的简单实例 之登陆和操作权限的更多相关文章
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- MVC 5 Ajax + bootstrap+ handle bar 例: 实现service 状态
Js Script <script src="../../Scripts/handlebars-v1.3.0.js"></script> <scrip ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理(附源码)
前言:时间很快,已经快到春节的时间了,这段时间由于生病,博客基本没更新,所以今天写一下我们做的一个项目吧,是对权限的基本操作的操作,代码也就不怎么说了,直接上传源码和图片展示,下面我们直接进入主题介绍 ...
- MVC之权限管理-网站开发之路
一.前言 刚到公司没多长时间就开始接触MVC到现在不能说懂了,只能说到达会用这个层次吧,感觉MVC用来写Web还是很强大的,层次清晰. 今天我来写写关于权限管理这一块,自我感觉网站的权限主要分为菜单权 ...
- [转]Asp.Net大型项目实践(11)-基于MVC Action粒度的权限管理【续】【源码在这里】(在线demo,全部源码)
本文转自:http://www.cnblogs.com/legendxian/archive/2010/01/25/1655551.html 接上篇Asp.Net大型项目实践(10)-基于MVC Ac ...
- ASP.NET MVC利用ajax把action的JavaScript注册到页面并执行
相信大家在做Webform时经常会遇到在页面的后台CS文件中根据数据运行结果修改页面显示样式.显示(隐藏).或者弹出框,当时我们会用到ScriptManage或者Page来向页面注册一段js来实现页面 ...
- Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07
目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...
- 分享基于EF+MVC+Bootstrap的通用后台管理系统及架构
基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级的缓存模块.日志模块.上传缩略图模块.通用配置及服务调用, 提供了OA.CRM.CMS的原型实例,适合快速构建中小型互联网及行业 ...
- MVC使用ajax异步刷新时怎样输出从后台中传过来的JSON数据
前言 这几天在学习MVC使用AJAX异步刷,因为是新手.所以在js中传参数到后台以及后台返回数据到前台怎么接受,怎么前台遍历出JSON数据都开始不知道,相信新手在使用时跟我一样会遇到,这里我就和大家分 ...
随机推荐
- 修改ie的默认值 为ie10
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10" />
- noip200802排座椅
排座椅 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的 ...
- 多线程相关------信号量Semaphore
Semaphore用于对资源进行计数.允许一定数量的线程同时访问该资源.可以用于进程间同步 相关函数 CreateSemaphore 创建或打开一个信号量对象 HANDLE WINAPI Create ...
- grpc例子
grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...
- Git 恢复某个文件指定版本
1. git reflog 找到comit id 2. git reset edf92f a.txt 3. git commit -m "ssss" 4. git checkou ...
- VirtualBox + CentOS 使用 NAT + Host-Only 方式联网
之前一直使用 VMware 作为虚拟机,这几天看<跟阿铭学Linux>,里面用的是虚拟机是 Oracle VirtualBox,也跟着安装配置一个,但是比较坑的是照着上面的配置折腾了很久才 ...
- Android--Activity(活动)
1. 安卓中的 Activity 大致等于桌面应用中的window 2. Activity 的生命周期由系统控制, 所以在开发时要假设 Activity 会被随时销毁掉的情况, 比如: 应用中有一个 ...
- 来回切换页面并关闭其他tab
要下班了,就先把这个方法copy上来.反正自己能看懂. public void checkSchemaDetail(String logext, String expectRes){ String c ...
- spring_异常提示1
nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource ------- 缺少j ...
- HTTPS 协议和原理
1 HTTPS 协议概述 HTTPS 可以认为是 HTTP + TLS.HTTP 协议大家耳熟能详了,目前大部分 WEB 应用和网站都是使用 HTTP 协议传输的. TLS 是传输层加密协议,它的前身 ...