using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using WIDESEA_Core.Extensions; using WIDESEA_Core.ManageUser; using WIDESEA_Core.Services; using WIDESEA_Core.UserManager; using WIDESEA_Core.Utilities; using WIDESEA_Entity; using WIDESEA_Entity.DomainModels; namespace WIDESEA_System.Services { public partial class Sys_RoleService { private WebResponseContent _responseContent = new WebResponseContent(); public override PageGridData GetPageData(PageDataOptions pageData) { //角色Id=1默认为超级管理员角色,界面上不显示此角色 QueryRelativeExpression = (IQueryable queryable) => { if (UserContext.Current.IsSuperAdmin) { return queryable; } List roleIds = GetAllChildrenRoleIdAndSelf(); return queryable.Where(x => roleIds.Contains(x.Role_Id)); }; return base.GetPageData(pageData); } /// /// 编辑权限时,获取当前用户的所有菜单权限 /// /// public async Task GetCurrentUserTreePermission() { return await GetUserTreePermission(UserContext.Current.RoleId); } /// /// 编辑权限时,获取指定角色的所有菜单权限 /// /// /// public async Task GetUserTreePermission(int roleId) { if (!UserContext.IsRoleIdSuperAdmin(roleId) && UserContext.Current.RoleId != roleId) { if (!(await GetAllChildrenAsync(UserContext.Current.RoleId)).Exists(x => x.Id == roleId)) { return _responseContent.Error("没有权限获取此角色的权限信息"); } } //获取用户权限 List permissions = UserContext.Current.GetPermissions(roleId); //权限用户权限查询所有的菜单信息 List menus = await Task.Run(() => Sys_MenuService.Instance.GetUserMenuList(roleId)); //获取当前用户权限如:(Add,Search)对应的显示文本信息如:Add:添加,Search:查询 var data = menus.Where(t => t.MenuType == 0/*wms系统*/ || t.MenuType == 99/*共用*/).Select(x => new { Id = x.Menu_Id, Pid = x.ParentId, Text = x.MenuName, IsApp = x.MenuType == 1, Actions = GetActions(x.Menu_Id, x.Actions, permissions, roleId) }); return _responseContent.OK(null, data); } private List GetActions(int menuId, List menuActions, List permissions, int roleId) { if (UserContext.IsRoleIdSuperAdmin(roleId)) { return menuActions; } return menuActions.Where(p => permissions .Exists(w => menuId == w.Menu_Id && w.UserAuthArr.Contains(p.Value))) .ToList(); } private List rolesChildren = new List(); /// /// 编辑权限时获取当前用户下的所有角色与当前用户的菜单权限 /// /// public async Task GetCurrentTreePermission() { _responseContent = await GetCurrentUserTreePermission(); int roleId = UserContext.Current.RoleId; return _responseContent.OK(null, new { tree = _responseContent.Data, roles = await GetAllChildrenAsync(roleId) }); } private List roles = null; /// /// 获取当前角色下的所有角色包括自己的角色Id /// /// public List GetAllChildrenRoleIdAndSelf() { int roleId = UserContext.Current.RoleId; List roleIds = GetAllChildren(roleId).Select(x => x.Id).ToList(); roleIds.Add(roleId); return roleIds; } /// /// 获取当前角色下的所有角色 /// /// /// public List GetAllChildren(int roleId) { roles = GetAllRoleQueryable(roleId).ToList(); return GetAllChildrenNodes(roleId); } public async Task> GetAllChildrenAsync(int roleId) { roles = await GetAllRoleQueryable(roleId).ToListAsync(); return GetAllChildrenNodes(roleId); } private IQueryable GetAllRoleQueryable(int roleId) { return repository .FindAsIQueryable( x => x.Enable == 1 && x.Role_Id > 1) .Select( s => new RoleNodes() { Id = s.Role_Id, ParentId = s.ParentId, RoleName = s.RoleName }); } public async Task> GetAllChildrenRoleIdAsync(int roleId) { return (await GetAllChildrenAsync(roleId)).Select(x => x.Id).ToList(); } public List GetAllChildrenRoleId(int roleId) { return GetAllChildren(roleId).Select(x => x.Id).ToList(); } private List GetAllChildrenNodes(int roleId) { return RoleContext.GetAllChildren(roleId); } /// /// 递归获取所有子节点权限 /// /// /// /// 保存角色权限 /// /// /// /// public async Task SavePermission(List userPermissions, int roleId) { string message = ""; try { UserInfo user = UserContext.Current.UserInfo; if (!(await GetAllChildrenAsync(user.Role_Id)).Exists(x => x.Id == roleId)) return _responseContent.Error("没有权限修改此角色的权限信息"); //当前用户的权限 List permissions = UserContext.Current.Permissions; List originalMeunIds = new List(); //被分配角色的权限 List roleAuths = await repository.FindAsync(x => x.Role_Id == roleId); List updateAuths = new List(); foreach (UserPermissions x in userPermissions) { Permissions per = permissions.Where(p => p.Menu_Id == x.Id).FirstOrDefault(); //不能分配超过当前用户的权限 if (per == null) continue; //per.UserAuthArr.Contains(a.Value)校验权限范围 string[] arr = x.Actions == null || x.Actions.Count == 0 ? new string[0] : x.Actions.Where(a => per.UserAuthArr.Contains(a.Value)) .Select(s => s.Value).ToArray(); //如果当前权限没有分配过,设置Auth_Id默认为0,表示新增的权限 var auth = roleAuths.Where(r => r.Menu_Id == x.Id).Select(s => new { s.Auth_Id, s.AuthValue, s.Menu_Id }).FirstOrDefault(); string newAuthValue = string.Join(",", arr); //权限没有发生变化则不处理 if (auth == null || auth.AuthValue != newAuthValue) { updateAuths.Add(new Sys_RoleAuth() { Role_Id = roleId, Menu_Id = x.Id, AuthValue = string.Join(",", arr), Auth_Id = auth == null ? 0 : auth.Auth_Id, ModifyDate = DateTime.Now, Modifier = user.UserTrueName, CreateDate = DateTime.Now, Creator = user.UserTrueName }); } else { originalMeunIds.Add(auth.Menu_Id); } } //更新权限 repository.UpdateRange(updateAuths.Where(x => x.Auth_Id > 0), x => new { x.Menu_Id, x.AuthValue, x.Modifier, x.ModifyDate }); //新增的权限 repository.AddRange(updateAuths.Where(x => x.Auth_Id <= 0)); //获取权限取消的权限 int[] authIds = roleAuths.Where(x => userPermissions.Select(u => u.Id) .ToList().Contains(x.Menu_Id) || originalMeunIds.Contains(x.Menu_Id)) .Select(s => s.Auth_Id) .ToArray(); List delAuths = roleAuths.Where(x => x.AuthValue != "" && !authIds.Contains(x.Auth_Id)).ToList(); delAuths.ForEach(x => { x.AuthValue = ""; }); //将取消的权限设置为"" repository.UpdateRange(delAuths, x => new { x.Menu_Id, x.AuthValue, x.Modifier, x.ModifyDate }); int addCount = updateAuths.Where(x => x.Auth_Id <= 0).Count(); int updateCount = updateAuths.Where(x => x.Auth_Id > 0).Count(); await repository.SaveChangesAsync(); string _version = DateTime.Now.ToString("yyyyMMddHHMMssfff"); //标识缓存已更新 base.CacheContext.Add(roleId.GetRoleIdKey(), _version); _responseContent.OK($"保存成功:新增加配菜单权限{addCount}条,更新菜单{updateCount}条,删除权限{delAuths.Count()}条"); } catch (Exception ex) { message = "异常信息:" + ex.Message + ex.StackTrace + ","; } finally { Logger.Info($"权限分配置:{message}{_responseContent.Message}"); } return _responseContent; } public override WebResponseContent Add(SaveModel saveDataModel) { AddOnExecuting = (Sys_Role role, object obj) => { if (!UserContext.Current.IsSuperAdmin && role.ParentId > 0 && !RoleContext.GetAllChildrenIds(UserContext.Current.RoleId).Contains(role.ParentId)) { return _responseContent.Error("不能添加此角色"); } return ValidateRoleName(role, x => x.RoleName == role.RoleName); }; return RemoveCache(base.Add(saveDataModel)); } public override WebResponseContent Del(object[] keys, bool delList = true) { if (!UserContext.Current.IsSuperAdmin) { var roleIds = RoleContext.GetAllChildrenIds(UserContext.Current.RoleId); var _keys = keys.Select(s => s.GetInt()); if (_keys.Any(x => !roleIds.Contains(x))) { return _responseContent.Error("没有权限删除此角色"); } } return RemoveCache(base.Del(keys, delList)); } private WebResponseContent ValidateRoleName(Sys_Role role, Expression> predicate) { if (repository.Exists(predicate)) { return _responseContent.Error($"角色名【{role.RoleName}】已存在,请设置其他角色名"); } return _responseContent.OK(); } public override WebResponseContent Update(SaveModel saveModel) { UpdateOnExecuting = (Sys_Role role, object obj1, object obj2, List obj3) => { //2020.05.07新增禁止选择上级角色为自己 if (role.Role_Id == role.ParentId) { return _responseContent.Error($"上级角色不能选择自己"); } if (role.Role_Id == UserContext.Current.RoleId) { return _responseContent.Error($"不能修改自己的角色"); } if (repository.Exists(x => x.Role_Id == role.ParentId && x.ParentId == role.Role_Id)) { return _responseContent.Error($"不能选择此上级角色,选择的上级角色与当前角色形成依赖关系"); } if (!UserContext.Current.IsSuperAdmin) { var roleIds = RoleContext.GetAllChildrenIds(UserContext.Current.RoleId); if (role.ParentId > 0) { if (!roleIds.Contains(role.ParentId)) { return _responseContent.Error($"不能选择此角色"); } } if (!roleIds.Contains(role.Role_Id)) { return _responseContent.Error($"不能选择此角色"); } return _responseContent.OK(""); } return ValidateRoleName(role, x => x.RoleName == role.RoleName && x.Role_Id != role.Role_Id); }; return RemoveCache(base.Update(saveModel)); } private WebResponseContent RemoveCache(WebResponseContent webResponse) { if (webResponse.Status) { RoleContext.Refresh(); } return webResponse; } } public class UserPermissions { public int Id { get; set; } public int Pid { get; set; } public string Text { get; set; } public bool IsApp { get; set; } public List Actions { get; set; } } }