角色配置菜单完成,处理了几个ToDo
This commit is contained in:
parent
3dffd04718
commit
6e1a306ac6
|
@ -264,6 +264,7 @@
|
|||
<Content Include="Views\Admin\Profiles.cshtml" />
|
||||
<Content Include="Views\Shared\Footer.cshtml" />
|
||||
<Content Include="Views\Shared\MenuTree.cshtml" />
|
||||
<Content Include="Views\Shared\NavigatorConfig.cshtml" />
|
||||
<Content Include="Views\Shared\SubNavigation.cshtml" />
|
||||
<Content Include="Views\Shared\SubMenu.cshtml" />
|
||||
<Content Include="Views\Shared\SubMenuTree.cshtml" />
|
||||
|
|
|
@ -310,4 +310,19 @@
|
|||
Group.saveGroupsByRoleId = function (roleId, groupIds, callback) {
|
||||
processData.call(this, { Id: roleId, callback: callback, method: "PUT", data: { type: "role", groupIds: groupIds } });
|
||||
};
|
||||
htmlTemplateForMenu='<li class="dd-item dd3-item" data-id="{0}"><div class="dd-handle dd3-handle"></div><div class="dd3-content"><label><input name="menuParent" type="checkbox" value="{0}" {2} /><input type="radio" name="menu" value="{0}" {2} /><span>{1}</span></label></div></li>';
|
||||
//Menus
|
||||
Menu = {
|
||||
url: '../api/Menus/', title: "授权菜单", html: function (result) {
|
||||
return $.map(result, function (element, index) {
|
||||
return $.format(htmlTemplateForMenu, element.ID, element.Name, element.Active);
|
||||
}).join('');
|
||||
}
|
||||
}
|
||||
Menu.getMenusByRoleId = function (roleId, callback) {
|
||||
processData.call(this, { Id: roleId, callback: callback, data: { type: "role" } });
|
||||
};
|
||||
Menu.saveMenusByRoleId = function (roleId, menuIds, callback) {
|
||||
processData.call(this, { Id: roleId, callback: callback, method: "PUT", data: { type: "role", menuIds:menuIds } });
|
||||
};
|
||||
})(jQuery);
|
|
@ -1,5 +1,8 @@
|
|||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.DataAccess;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers
|
||||
|
@ -34,5 +37,36 @@ namespace Bootstrap.Admin.Controllers
|
|||
{
|
||||
return MenuHelper.DeleteMenu(value);
|
||||
}
|
||||
[HttpPost]
|
||||
public IEnumerable<Menu> Post(int id, [FromBody]JObject value)
|
||||
{
|
||||
var ret = new List<Menu>();
|
||||
dynamic json = value;
|
||||
switch ((string)json.type)
|
||||
{
|
||||
case "role":
|
||||
ret = MenuHelper.RetrieveMenusByRoleId(id).ToList();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
[HttpPut]
|
||||
public bool Put(int id, [FromBody]JObject value)
|
||||
{
|
||||
var ret = false;
|
||||
dynamic json = value;
|
||||
string menuIds = json.menuIds.ToString();
|
||||
switch ((string)json.type)
|
||||
{
|
||||
case "role":
|
||||
ret = MenuHelper.SaveMenusByRoleId(id, menuIds);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ namespace Bootstrap.Admin.Models
|
|||
}
|
||||
var ret = new QueryData<Group>();
|
||||
ret.total = data.Count();
|
||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
||||
data = Order == "asc" ? data.OrderBy(t => t.GroupName) : data.OrderByDescending(t => t.GroupName);
|
||||
ret.rows = data.Skip(Offset).Take(Limit);
|
||||
return ret;
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace Bootstrap.Admin.Models
|
|||
}
|
||||
var ret = new QueryData<Role>();
|
||||
ret.total = data.Count();
|
||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
||||
data = Order == "asc" ? data.OrderBy(t => t.RoleName) : data.OrderByDescending(t => t.RoleName);
|
||||
ret.rows = data.Skip(Offset).Take(Limit);
|
||||
return ret;
|
||||
|
|
|
@ -32,8 +32,17 @@ namespace Bootstrap.Admin.Models
|
|||
}
|
||||
var ret = new QueryData<User>();
|
||||
ret.total = data.Count();
|
||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
||||
switch (Sort)
|
||||
{
|
||||
case "UserName":
|
||||
data = Order == "asc" ? data.OrderBy(t => t.UserName) : data.OrderByDescending(t => t.UserName);
|
||||
break;
|
||||
case "RegisterTime":
|
||||
data = Order == "asc" ? data.OrderBy(t => t.RegisterTime) : data.OrderByDescending(t => t.RegisterTime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret.rows = data.Skip(Offset).Take(Limit);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -45,13 +45,44 @@
|
|||
return $(element).val();
|
||||
}).toArray().join(',');
|
||||
Group.saveGroupsByRoleId(roleId, groupIds, { modal: 'dialogGroup' });
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'btn_assignMenu',
|
||||
click: function (row) {
|
||||
Menu.getMenusByRoleId(row.ID, function (data) {
|
||||
$(".menu-content .modal-header .modal-title").text($.format('{0}-菜单授权窗口', row.RoleName));
|
||||
$('.menu-content button:last').data('type', 'menu');
|
||||
$('ol.dd-list').html(data);
|
||||
$('#dialogMenu').modal('show');
|
||||
$('.menu-content').show();
|
||||
$('div.dd3-content :checkbox').show();
|
||||
$('div.dd3-content :radio').hide();
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'btnSubmitMenu',
|
||||
click: function (row) {
|
||||
var roleId = row.ID;
|
||||
var type = $('.menu-content button:last').data('type');
|
||||
switch (type) {
|
||||
case "menu":
|
||||
var menuIds = $('.dd3-content :checkbox:checked').map(function (index, element) {
|
||||
return $(element).val();
|
||||
}).toArray().join(',');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Menu.saveMenusByRoleId(roleId, menuIds, { modal: 'dialogMenu' });
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
$('#nestable_menu').nestable();
|
||||
|
||||
$('table').smartTable({
|
||||
url: '../api/Roles', //请求后台的URL(*)
|
||||
sortName: 'RoleName',
|
||||
|
|
|
@ -3,8 +3,14 @@
|
|||
ViewBag.Title = "角色管理";
|
||||
Layout = "~/Views/Shared/_Default.cshtml";
|
||||
}
|
||||
@section css {
|
||||
<link href="~/Content/css/fa.css" rel="stylesheet" />
|
||||
<link href="~/Content/css/jquery.nestable.css" rel="stylesheet" />
|
||||
}
|
||||
@section Javascript {
|
||||
<script src="~/Content/js/jquery.nestable.js"></script>
|
||||
<script src="~/scripts/Roles.js"></script>
|
||||
|
||||
}
|
||||
@section header {
|
||||
@Html.Partial("Header", Model)
|
||||
|
@ -34,6 +40,9 @@
|
|||
<button id="btn_assignGroup" type="button" class="btn btn-info">
|
||||
<span class="fa fa-home" aria-hidden="true"></span>指派部门
|
||||
</button>
|
||||
<button id="btn_assignMenu" type="button" class="btn btn-info">
|
||||
<span class="fa fa-home" aria-hidden="true"></span>指派菜单
|
||||
</button>
|
||||
}
|
||||
@section modal {
|
||||
<div class="modal-header">
|
||||
|
@ -57,4 +66,5 @@
|
|||
@section customModal{
|
||||
@Html.Partial("UserConfig")
|
||||
@Html.Partial("GroupConfig")
|
||||
@Html.Partial("NavigatorConfig", Model.Navigations)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
@model IEnumerable<Menu>
|
||||
|
||||
<div class="modal fade" id="dialogMenu" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myMenuModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
@Html.Partial("MenuTree", Model)
|
||||
</div>
|
||||
</div>
|
|
@ -25,6 +25,7 @@
|
|||
<cacheManager>
|
||||
<add key="MenuHelper-RetrieveMenus" interval="600" desc="所有菜单数据缓存" />
|
||||
<add key="MenuHelper-RetrieveMenusByUserId" interval="600" desc="指定用户菜单数据缓存"/>
|
||||
<add key="MenuHelper-RetrieveMenusByRoleId" interval="600" desc="角色菜单信息缓存" />
|
||||
<add key="UserHelper-RetrieveUsers" interval="600" desc="所有用户数据缓存"/>
|
||||
<add key="UserHelper-RetrieveUsersByName" interval="600" desc="指定用户名的用户数据缓存"/>
|
||||
<add key="UserHelper-RetrieveUsersByRoleId" interval="600" desc="指定角色的用户数据缓存"/>
|
||||
|
|
|
@ -7,6 +7,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -16,6 +17,7 @@ namespace Bootstrap.DataAccess
|
|||
{
|
||||
internal const string RetrieveMenusDataKey = "MenuHelper-RetrieveMenus";
|
||||
internal const string RetrieveMenusByUserIDDataKey = "MenuHelper-RetrieveMenusByUserId";
|
||||
internal const string RetrieveMenusByRoleIDDataKey = "MenuHelper-RetrieveMenusByRoleId";
|
||||
/// <summary>
|
||||
/// 查询所有菜单信息
|
||||
/// </summary>
|
||||
|
@ -184,5 +186,88 @@ namespace Bootstrap.DataAccess
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询某个角色所配置的菜单
|
||||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Menu> RetrieveMenusByRoleId(int roleId)
|
||||
{
|
||||
string key = string.Format("{0}-{1}", RetrieveMenusByRoleIDDataKey, roleId);
|
||||
return CacheManager.GetOrAdd(key, CacheSection.RetrieveIntervalByKey(RetrieveMenusByRoleIDDataKey), k =>
|
||||
{
|
||||
List<Menu> Menus = new List<Menu>();
|
||||
string sql = "select n.ID,n.ParentId, n.Name,n.[Order],n.Icon,n.Url,n.Category, case nr.NavigationID when n.ID then 'active' else '' end [status] from Navigations n left join NavigationRole nr on n.ID = nr.NavigationID and RoleID = @RoleID";
|
||||
DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, sql);
|
||||
cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@RoleID", roleId, ParameterDirection.Input));
|
||||
try
|
||||
{
|
||||
using (DbDataReader reader = DBAccessManager.SqlDBAccess.ExecuteReader(cmd))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Menus.Add(new Menu()
|
||||
{
|
||||
ID = (int)reader[0],
|
||||
ParentId = (int)reader[1],
|
||||
Name = (string)reader[2],
|
||||
Order = (int)reader[3],
|
||||
Icon = LgbConvert.ReadValue(reader[4], string.Empty),
|
||||
Url = LgbConvert.ReadValue(reader[5], string.Empty),
|
||||
Category = (string)reader[6],
|
||||
Active = (string)reader[7] == "" ? "" : "checked"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { ExceptionManager.Publish(ex); }
|
||||
return Menus;
|
||||
}, CacheSection.RetrieveDescByKey(RetrieveMenusByRoleIDDataKey));
|
||||
}
|
||||
/// <summary>
|
||||
/// 通过角色ID保存当前授权菜单
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="menuIds"></param>
|
||||
/// <returns></returns>
|
||||
public static bool SaveMenusByRoleId(int id, string menuIds)
|
||||
{
|
||||
bool ret = false;
|
||||
DataTable dt = new DataTable();
|
||||
dt.Columns.Add("RoleID", typeof(int));
|
||||
dt.Columns.Add("NavigationID", typeof(int));
|
||||
if (!string.IsNullOrEmpty(menuIds)) menuIds.Split(',').ToList().ForEach(menuId => dt.Rows.Add(id, Convert.ToInt32(menuId)));
|
||||
using (TransactionPackage transaction = DBAccessManager.SqlDBAccess.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
//删除菜单角色表该角色所有的菜单
|
||||
string sql = "delete from NavigationRole where RoleID=@RoleID";
|
||||
using (DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, sql))
|
||||
{
|
||||
cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@RoleID", id, ParameterDirection.Input));
|
||||
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd, transaction);
|
||||
//批插入菜单角色表
|
||||
using (SqlBulkCopy bulk = new SqlBulkCopy((SqlConnection)transaction.Transaction.Connection, SqlBulkCopyOptions.Default, (SqlTransaction)transaction.Transaction))
|
||||
{
|
||||
bulk.DestinationTableName = "NavigationRole";
|
||||
bulk.ColumnMappings.Add("RoleID", "RoleID");
|
||||
bulk.ColumnMappings.Add("NavigationID", "NavigationID");
|
||||
bulk.WriteToServer(dt);
|
||||
transaction.CommitTransaction();
|
||||
}
|
||||
}
|
||||
CacheCleanUtility.ClearCache(menuIds: menuIds, roleIds: id.ToString());
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExceptionManager.Publish(ex);
|
||||
transaction.RollbackTransaction();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,11 @@ namespace Bootstrap.DataAccess.Tests
|
|||
{
|
||||
Assert.IsTrue(MenuHelper.RetrieveMenusByUserId(1).Count() > 1, "根据用户ID查询菜单的MenuHelper.RetrieveMenusByUserId方法调用失败");
|
||||
}
|
||||
[TestMethod]
|
||||
public void RetrieveMenuByRoleIDTest()
|
||||
{
|
||||
Assert.IsTrue(MenuHelper.RetrieveMenusByRoleId(1).Count() >= 0, "根据角色ID查询菜单的MenuHelper.RetrieveMenusByRoleId方法调用失败");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SaveMenuTest()
|
||||
|
@ -85,5 +90,28 @@ namespace Bootstrap.DataAccess.Tests
|
|||
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
[TestMethod]
|
||||
public void SaveMenusByRoleIdTest()
|
||||
{
|
||||
var menu = MenuHelper.RetrieveMenus().FirstOrDefault(m => m.Name == Menu.Name);
|
||||
if (menu == null) MenuHelper.SaveMenu(Menu);
|
||||
menu = MenuHelper.RetrieveMenus().FirstOrDefault(m => m.Name == Menu.Name);
|
||||
var role = RoleHelper.RetrieveRoles().FirstOrDefault(r => r.RoleName == Role.RoleName);
|
||||
if (role == null) RoleHelper.SaveRole(Role);
|
||||
role = RoleHelper.RetrieveRoles().FirstOrDefault(r => r.RoleName == Role.RoleName);
|
||||
|
||||
Assert.IsTrue(MenuHelper.SaveMenusByRoleId(role.ID, menu.ID.ToString()), "存储角色菜单信息失败");
|
||||
int x = MenuHelper.RetrieveMenusByRoleId(role.ID).Count();
|
||||
Assert.IsTrue(x >= 1, string.Format("获取角色ID={0}的菜单信息失败", role.ID));
|
||||
|
||||
//删除数据
|
||||
string sql = "Delete from Navigations where Name = '__测试菜单__';";
|
||||
sql += "Delete from Roles where RoleName='_测试角色_';";
|
||||
sql += string.Format("Delete from NavigationRole where RoleID={0};", role.ID);
|
||||
using (DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, sql))
|
||||
{
|
||||
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue