角色配置菜单完成,处理了几个ToDo
This commit is contained in:
parent
3dffd04718
commit
6e1a306ac6
|
@ -264,6 +264,7 @@
|
||||||
<Content Include="Views\Admin\Profiles.cshtml" />
|
<Content Include="Views\Admin\Profiles.cshtml" />
|
||||||
<Content Include="Views\Shared\Footer.cshtml" />
|
<Content Include="Views\Shared\Footer.cshtml" />
|
||||||
<Content Include="Views\Shared\MenuTree.cshtml" />
|
<Content Include="Views\Shared\MenuTree.cshtml" />
|
||||||
|
<Content Include="Views\Shared\NavigatorConfig.cshtml" />
|
||||||
<Content Include="Views\Shared\SubNavigation.cshtml" />
|
<Content Include="Views\Shared\SubNavigation.cshtml" />
|
||||||
<Content Include="Views\Shared\SubMenu.cshtml" />
|
<Content Include="Views\Shared\SubMenu.cshtml" />
|
||||||
<Content Include="Views\Shared\SubMenuTree.cshtml" />
|
<Content Include="Views\Shared\SubMenuTree.cshtml" />
|
||||||
|
|
|
@ -310,4 +310,19 @@
|
||||||
Group.saveGroupsByRoleId = function (roleId, groupIds, callback) {
|
Group.saveGroupsByRoleId = function (roleId, groupIds, callback) {
|
||||||
processData.call(this, { Id: roleId, callback: callback, method: "PUT", data: { type: "role", groupIds: groupIds } });
|
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);
|
})(jQuery);
|
|
@ -1,5 +1,8 @@
|
||||||
using Bootstrap.Admin.Models;
|
using Bootstrap.Admin.Models;
|
||||||
using Bootstrap.DataAccess;
|
using Bootstrap.DataAccess;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
|
|
||||||
namespace Bootstrap.Admin.Controllers
|
namespace Bootstrap.Admin.Controllers
|
||||||
|
@ -34,5 +37,36 @@ namespace Bootstrap.Admin.Controllers
|
||||||
{
|
{
|
||||||
return MenuHelper.DeleteMenu(value);
|
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>();
|
var ret = new QueryData<Group>();
|
||||||
ret.total = data.Count();
|
ret.total = data.Count();
|
||||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
|
||||||
data = Order == "asc" ? data.OrderBy(t => t.GroupName) : data.OrderByDescending(t => t.GroupName);
|
data = Order == "asc" ? data.OrderBy(t => t.GroupName) : data.OrderByDescending(t => t.GroupName);
|
||||||
ret.rows = data.Skip(Offset).Take(Limit);
|
ret.rows = data.Skip(Offset).Take(Limit);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -32,7 +32,6 @@ namespace Bootstrap.Admin.Models
|
||||||
}
|
}
|
||||||
var ret = new QueryData<Role>();
|
var ret = new QueryData<Role>();
|
||||||
ret.total = data.Count();
|
ret.total = data.Count();
|
||||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
|
||||||
data = Order == "asc" ? data.OrderBy(t => t.RoleName) : data.OrderByDescending(t => t.RoleName);
|
data = Order == "asc" ? data.OrderBy(t => t.RoleName) : data.OrderByDescending(t => t.RoleName);
|
||||||
ret.rows = data.Skip(Offset).Take(Limit);
|
ret.rows = data.Skip(Offset).Take(Limit);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -32,8 +32,17 @@ namespace Bootstrap.Admin.Models
|
||||||
}
|
}
|
||||||
var ret = new QueryData<User>();
|
var ret = new QueryData<User>();
|
||||||
ret.total = data.Count();
|
ret.total = data.Count();
|
||||||
// TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序
|
switch (Sort)
|
||||||
|
{
|
||||||
|
case "UserName":
|
||||||
data = Order == "asc" ? data.OrderBy(t => t.UserName) : data.OrderByDescending(t => t.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);
|
ret.rows = data.Skip(Offset).Take(Limit);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,44 @@
|
||||||
return $(element).val();
|
return $(element).val();
|
||||||
}).toArray().join(',');
|
}).toArray().join(',');
|
||||||
Group.saveGroupsByRoleId(roleId, groupIds, { modal: 'dialogGroup' });
|
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({
|
$('table').smartTable({
|
||||||
url: '../api/Roles', //请求后台的URL(*)
|
url: '../api/Roles', //请求后台的URL(*)
|
||||||
sortName: 'RoleName',
|
sortName: 'RoleName',
|
||||||
|
|
|
@ -3,8 +3,14 @@
|
||||||
ViewBag.Title = "角色管理";
|
ViewBag.Title = "角色管理";
|
||||||
Layout = "~/Views/Shared/_Default.cshtml";
|
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 {
|
@section Javascript {
|
||||||
|
<script src="~/Content/js/jquery.nestable.js"></script>
|
||||||
<script src="~/scripts/Roles.js"></script>
|
<script src="~/scripts/Roles.js"></script>
|
||||||
|
|
||||||
}
|
}
|
||||||
@section header {
|
@section header {
|
||||||
@Html.Partial("Header", Model)
|
@Html.Partial("Header", Model)
|
||||||
|
@ -34,6 +40,9 @@
|
||||||
<button id="btn_assignGroup" type="button" class="btn btn-info">
|
<button id="btn_assignGroup" type="button" class="btn btn-info">
|
||||||
<span class="fa fa-home" aria-hidden="true"></span>指派部门
|
<span class="fa fa-home" aria-hidden="true"></span>指派部门
|
||||||
</button>
|
</button>
|
||||||
|
<button id="btn_assignMenu" type="button" class="btn btn-info">
|
||||||
|
<span class="fa fa-home" aria-hidden="true"></span>指派菜单
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
@section modal {
|
@section modal {
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
@ -57,4 +66,5 @@
|
||||||
@section customModal{
|
@section customModal{
|
||||||
@Html.Partial("UserConfig")
|
@Html.Partial("UserConfig")
|
||||||
@Html.Partial("GroupConfig")
|
@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>
|
<cacheManager>
|
||||||
<add key="MenuHelper-RetrieveMenus" interval="600" desc="所有菜单数据缓存" />
|
<add key="MenuHelper-RetrieveMenus" interval="600" desc="所有菜单数据缓存" />
|
||||||
<add key="MenuHelper-RetrieveMenusByUserId" 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-RetrieveUsers" interval="600" desc="所有用户数据缓存"/>
|
||||||
<add key="UserHelper-RetrieveUsersByName" interval="600" desc="指定用户名的用户数据缓存"/>
|
<add key="UserHelper-RetrieveUsersByName" interval="600" desc="指定用户名的用户数据缓存"/>
|
||||||
<add key="UserHelper-RetrieveUsersByRoleId" interval="600" desc="指定角色的用户数据缓存"/>
|
<add key="UserHelper-RetrieveUsersByRoleId" interval="600" desc="指定角色的用户数据缓存"/>
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ namespace Bootstrap.DataAccess
|
||||||
{
|
{
|
||||||
internal const string RetrieveMenusDataKey = "MenuHelper-RetrieveMenus";
|
internal const string RetrieveMenusDataKey = "MenuHelper-RetrieveMenus";
|
||||||
internal const string RetrieveMenusByUserIDDataKey = "MenuHelper-RetrieveMenusByUserId";
|
internal const string RetrieveMenusByUserIDDataKey = "MenuHelper-RetrieveMenusByUserId";
|
||||||
|
internal const string RetrieveMenusByRoleIDDataKey = "MenuHelper-RetrieveMenusByRoleId";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询所有菜单信息
|
/// 查询所有菜单信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -184,5 +186,88 @@ namespace Bootstrap.DataAccess
|
||||||
}
|
}
|
||||||
return ret;
|
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方法调用失败");
|
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]
|
[TestMethod]
|
||||||
public void SaveMenuTest()
|
public void SaveMenuTest()
|
||||||
|
@ -85,5 +90,28 @@ namespace Bootstrap.DataAccess.Tests
|
||||||
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd);
|
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