diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs index b099b03..309d93b 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs @@ -50,7 +50,7 @@ namespace Ewide.Application.Service [HttpPost("/houseMember/page")] public async Task QueryMemberPageList([FromBody] UserInput input) { - var dataScopes = await _sysUserService.GetUserDataScopeIdList(_userManager.UserId); + var dataScopes = await _userManager.GetUserAllDataScopeList(); var sql = @"SELECT SU.*, diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs index 4b9d3f8..e5aac58 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs @@ -72,7 +72,7 @@ namespace Ewide.Application.Service [HttpPost("/houseZone/page")] public async Task QueryZonePageList([FromBody] PageOrgInput input) { - var dataScopeList = _sysOrgService.GetDataScopeList(await _sysOrgService.GetUserDataScopeIdList()); + var dataScopeList = _sysOrgService.GetDataScopeList(await _userManager.GetUserAllDataScopeList()); var name = !string.IsNullOrEmpty(input.Name?.Trim()); var id = !string.IsNullOrEmpty(input.Id?.Trim()); diff --git a/Api/Ewide.Core/Controller/AreaCodeController.cs b/Api/Ewide.Core/Controller/AreaCodeController.cs index 32b93f1..57908a7 100644 --- a/Api/Ewide.Core/Controller/AreaCodeController.cs +++ b/Api/Ewide.Core/Controller/AreaCodeController.cs @@ -19,8 +19,8 @@ namespace Ewide.Core.Controller public class AreaCodeController : IDynamicApiController { private readonly IAreaCodeService _areaCodeService; - private readonly ISysUserService _sysUserService; private readonly IUserManager _userManager; + private readonly ISysUserService _sysUserService; public AreaCodeController(IAreaCodeService areaCodeService, IUserManager userManager, ISysUserService sysUserService) { _areaCodeService = areaCodeService; @@ -88,8 +88,7 @@ namespace Ewide.Core.Controller List areaCodeList = null; if (!_userManager.SuperAdmin) { - var orgIdList = await _sysUserService.GetUserDataScopeIdList(_userManager.UserId); - areaCodeList = await _areaCodeService.GetAreaCodeListByOrgId(orgIdList); + areaCodeList = await _userManager.GetUserAllAreaList(); } return await _areaCodeService.GetAreaCodeTree(level, areaCodeList); } diff --git a/Api/Ewide.Core/Entity/SysOrg.cs b/Api/Ewide.Core/Entity/SysOrg.cs index 078bc89..f0a92c5 100644 --- a/Api/Ewide.Core/Entity/SysOrg.cs +++ b/Api/Ewide.Core/Entity/SysOrg.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; @@ -29,6 +30,7 @@ namespace Ewide.Core /// 名称 /// [Comment("名称")] + [MaxLength(20)] public string Name { get; set; } /// diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index daef599..8e83b57 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -2834,6 +2834,12 @@ + + + 获取用户可以访问的区域权限 + + + OAuth配置---此结构方便拓展 @@ -5829,12 +5835,6 @@ - - - 获取用户数据范围(机构Id集合) - - - 职位参数 @@ -6156,14 +6156,6 @@ - - - 根据角色Id集合获取数据范围Id集合 - - - - - 根据角色Id获取角色名称 @@ -6185,6 +6177,13 @@ + + + 获取角色拥有区域Id集合 + + + + 租户参数 @@ -6946,13 +6945,6 @@ - - - 获取用户的数据范围Id集合 - - - - 根据机构Id集合删除对应的用户-数据范围关联信息 @@ -6986,14 +6978,6 @@ - - - 获取用户所有角色的数据范围(组织机构Id集合) - - - - - 根据角色Id删除对应的用户-角色表关联信息 @@ -7147,19 +7131,6 @@ - - - 获取用户数据范围(机构Id集合)并缓存 - - - - - - - 获取用户数据范围(机构Id集合) - - - 检查普通用户数据范围 diff --git a/Api/Ewide.Core/Manager/IUserManager.cs b/Api/Ewide.Core/Manager/IUserManager.cs index a9c9f42..e213bf9 100644 --- a/Api/Ewide.Core/Manager/IUserManager.cs +++ b/Api/Ewide.Core/Manager/IUserManager.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Ewide.Core @@ -21,5 +22,23 @@ namespace Ewide.Core Task> GetUserRoleIdList(); Task> GetUserRoleList(string userId); Task> GetUserRoleList(); + Task> GetLoginPermissionList(); + //获取用户额外授权的组织信息 + Task> GetUserExtraDataScopeList(); + Task> GetUserExtraDataScopeList(string userId); + //获取用户额外授权的区域信息 + Task> GetUserExtraAreaScopeList(); + Task> GetUserExtraAreaScopeList(string userId); + //获取角色额外授权的组织信息 + Task> GetRoleExtraDataScopeList(string roleId); + //获取角色额外授权的区域信息 + Task> GetRoleExtraAreaScopeList(string roleId); + Task> GetUserAllAreaList(); + Task> GetUserAllAreaList(string userId); + + //获取用户的授权范围 + Task> GetUserAllDataScopeList(); + Task> GetUserAllDataScopeList(string userId); + } } \ No newline at end of file diff --git a/Api/Ewide.Core/Manager/UserManager.cs b/Api/Ewide.Core/Manager/UserManager.cs index 6512364..a2ec008 100644 --- a/Api/Ewide.Core/Manager/UserManager.cs +++ b/Api/Ewide.Core/Manager/UserManager.cs @@ -6,6 +6,9 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; +using Ewide.Core.Service; +using System; +using System.Data; namespace Ewide.Core { @@ -19,7 +22,15 @@ namespace Ewide.Core private readonly IRepository _sysUserRoleRep; private readonly IRepository _sysEmpRep; // 员工表 private readonly IRepository _sysOrgRep; + private readonly IRepository _sysRoleMenuRep; + private readonly IRepository _sysMenuRep; + private readonly IRepository _sysUserDataScopeRep; + private readonly IRepository _sysUserAreaRep; + private readonly IRepository _sysRoleDataRep; + private readonly IRepository _sysRoleAreaRep; + private readonly IRepository _sysAreaCodeRep; private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ISysCacheService _sysCacheService; public string UserId { @@ -47,12 +58,16 @@ namespace Ewide.Core } public UserManager( + IHttpContextAccessor httpContextAccessor, + ISysCacheService sysCacheService, IRepository sysUserRep, IRepository sysRoleRep, IRepository sysUserRoleRep, IRepository sysEmpRep, IRepository sysOrgRep, - IHttpContextAccessor httpContextAccessor) + IRepository sysRoleMenuRep, + IRepository sysMenuRep, + IRepository sysUserDataScopeRep, IRepository sysUserAreaRep, IRepository sysRoleDataRep, IRepository sysRoleAreaRep, IRepository sysAreaCodeRep) { _sysUserRep = sysUserRep; _sysRoleRep = sysRoleRep; @@ -60,6 +75,14 @@ namespace Ewide.Core _sysEmpRep = sysEmpRep; _sysOrgRep = sysOrgRep; _httpContextAccessor = httpContextAccessor; + _sysCacheService = sysCacheService; + _sysRoleMenuRep = sysRoleMenuRep; + _sysMenuRep = sysMenuRep; + _sysUserDataScopeRep = sysUserDataScopeRep; + _sysUserAreaRep = sysUserAreaRep; + _sysRoleDataRep = sysRoleDataRep; + _sysRoleAreaRep = sysRoleAreaRep; + _sysAreaCodeRep = sysAreaCodeRep; } /// @@ -163,5 +186,194 @@ namespace Ewide.Core { return await GetUserRoleList(UserId); } + + public async Task> GetLoginPermissionList() + { + var permissions = await _sysCacheService.GetPermission(UserId); // 先从缓存里面读取 + if (permissions == null || permissions.Count < 1) + { + var roleIdList = await GetUserRoleIdList(); + var menuIdList = await _sysRoleMenuRep.DetachedEntities + .Where(u => roleIdList.Contains(u.SysRoleId)) + .Select(u => u.SysMenuId).ToListAsync(); + permissions = await _sysMenuRep.DetachedEntities.Where(u => menuIdList.Contains(u.Id)) + .Where(u => u.Type == (int)MenuType.FUNCTION) + .Where(u => u.Status == (int)CommonStatus.ENABLE) + .Select(u => u.Permission).ToListAsync(); +#if DEBUG +#else + await _sysCacheService.SetPermission(userId, permissions); // 缓存结果 +#endif + } + return permissions; + } + + public Task> GetUserExtraDataScopeList() + { + return GetUserExtraDataScopeList(UserId); + } + + public async Task> GetUserExtraDataScopeList(string userId) + { + return await _sysUserDataScopeRep.DetachedEntities + .Where(u => u.SysUserId == userId) + .Select(u => u.SysOrgId).ToListAsync(); + } + + public Task> GetUserExtraAreaScopeList() + { + return GetUserExtraAreaScopeList(UserId); + } + + public async Task> GetUserExtraAreaScopeList(string userId) + { + return await _sysUserAreaRep.DetachedEntities.Where(u => u.SysUserId == userId).Select(u => u.AreaCode).ToListAsync(); + } + + public Task> GetRoleExtraDataScopeList(string roleId) + { + return _sysRoleDataRep.DetachedEntities.Where(u => u.SysRoleId == roleId).Select(u => u.SysOrgId).ToListAsync(); + } + + public Task> GetRoleExtraAreaScopeList(string roleId) + { + return _sysRoleAreaRep.DetachedEntities.Where(u => u.SysRoleId == roleId).Select(u => u.AreaCode).ToListAsync(); + } + public Task> GetUserAllDataScopeList() + { + return GetUserAllDataScopeList(UserId); + } + public async Task> GetDataScopeListByDataScopeType(int dataScopeType, string orgId) + { + var orgIdList = new List(); + if (string.IsNullOrEmpty(orgId)) + return orgIdList; + + // 如果是范围类型是全部数据,则获取当前所有的组织架构Id + if (dataScopeType == (int)DataScopeType.ALL) + { + orgIdList = await _sysOrgRep.DetachedEntities.Where(u => u.Status == (int)CommonStatus.ENABLE).Select(u => u.Id).ToListAsync(); + } + // 如果范围类型是本部门及以下部门,则查询本节点和子节点集合,包含本节点 + else if (dataScopeType == (int)DataScopeType.DEPT_WITH_CHILD) + { + orgIdList = await _sysOrgRep.DetachedEntities + .Where(u => u.Pids.Contains(orgId)) + .Select(u => u.Id).ToListAsync(); + orgIdList.Add(orgId); + } + // 如果数据范围是本部门,不含子节点,则直接返回本部门 + else if (dataScopeType == (int)DataScopeType.DEPT) + { + orgIdList.Add(orgId); + } + return orgIdList; + } + + public async Task> GetUserAllDataScopeList(string userId) + { + var dataScopes = await _sysCacheService.GetDataScope(userId); // 先从缓存里面读取 + if (dataScopes != null && dataScopes.Count > 0) + { + return dataScopes; + } + var orgId = await _sysEmpRep.DetachedEntities.Where(e => e.Id == userId).Select(u => u.OrgId).SingleAsync(); + var orgAreaCode = await _sysOrgRep.Where(o => o.Id == orgId).Select(o => o.AreaCode).SingleAsync(); + //获取用户额外授权数据 + var userExtraDataScope = await (from org in _sysOrgRep.DetachedEntities + join ua in _sysUserAreaRep.DetachedEntities on org.AreaCode equals ua.AreaCode + where ua.SysUserId == userId + select org.Id).Concat(from ud in _sysUserDataScopeRep.DetachedEntities + where ud.SysUserId == userId + select ud.SysOrgId).ToListAsync(); + //获取用户所有角色 + //获取其他类型中最大的角色 + var areaScopeTypes = new[] { DataScopeType.AREA, DataScopeType.AREA_WITH_CHILD }.Cast(); + var strongerDataScopeType = (int)DataScopeType.SELF; + var strongerAreaType = (int)DataScopeType.SELF; + + //获取区域相关的角色类型中最大的区域角色 + var customDataScopeRoleIdList = new List(); + var roleList = from role in _sysRoleRep.DetachedEntities + join ur in _sysUserRoleRep.DetachedEntities on role.Id equals ur.SysRoleId + where ur.SysUserId == userId + select role; + foreach (var role in await roleList.ToListAsync()) + { + if (role.DataScopeType == (int)DataScopeType.DEFINE) + customDataScopeRoleIdList.Add(role.Id); + if ((role.DataScopeType == (int)DataScopeType.AREA || role.DataScopeType == (int)DataScopeType.AREA_WITH_CHILD) && strongerAreaType < role.DataScopeType) + { + strongerAreaType = role.DataScopeType; + } + else if (role.DataScopeType <= strongerDataScopeType) + strongerDataScopeType = role.DataScopeType; + } + // 自定义数据范围的角色对应的数据范围 + var roleDataScopeIdList = await _sysRoleDataRep.DetachedEntities.Where(rd => customDataScopeRoleIdList.Contains(rd.SysRoleId)).Select(rd => orgId).ToListAsync(); + + // 角色中拥有最大数据范围类型的数据范围 + var dataScopeIdList = await GetDataScopeListByDataScopeType(strongerDataScopeType, orgId); + //角色区域数据范围 + var areaOrgIdList = new List(); + if (strongerAreaType == (int)DataScopeType.AREA_WITH_CHILD) + areaOrgIdList = await _sysOrgRep.DetachedEntities.Where(p => p.AreaCode.StartsWith(orgAreaCode)).Select(p => p.Id).ToListAsync(); + if (strongerAreaType == (int)DataScopeType.AREA) + areaOrgIdList = await _sysOrgRep.DetachedEntities.Where(p => p.AreaCode == orgAreaCode).Select(p => p.Id).ToListAsync(); + //获取 + var scope = userExtraDataScope.Concat(roleDataScopeIdList).Concat(dataScopeIdList).Concat(areaOrgIdList).Distinct().ToList(); +#if DEBUG +#else + await _sysCacheService.SetDataScope(userId, scope); +#endif + return scope; + } + /// + /// 获取用户可以访问的区域权限 + /// + /// + public Task> GetUserAllAreaList() + { + return GetUserAllAreaList(UserId); + } + + public async Task> GetUserAllAreaList(string userId) + { + var orgId = await _sysEmpRep.DetachedEntities.Where(e => e.Id == userId).Select(u => u.OrgId).SingleAsync(); + var orgAreaCode = await _sysOrgRep.Where(o => o.Id == orgId).Select(o => o.AreaCode).SingleAsync(); + //本部门 或者 本部门区域 树结构只显示本级区域 + //本部门及以下 或者 本部门区域及以下 树结构显示本级和以下所有区域 + var extraUserArea = await GetUserExtraAreaScopeList(userId); + var roles = await _sysUserRoleRep.DetachedEntities.Include(ur => ur.SysRole).Where(ur => ur.SysUserId == userId).Select(ur => ur.SysRole).ToListAsync(); + var extraRoleArea = await _sysRoleAreaRep.DetachedEntities.Where(ra => roles.Where(r => r.DataScopeType == (int)DataScopeType.DEFINE).Select(r => r.Id).Contains(ra.SysRoleId)).Select(ra => ra.AreaCode).ToListAsync(); + var roleTypeArea = await GetUserDataScopeTypeAreaList(orgAreaCode, roles.Select(r => r.DataScopeType).ToList()); + return extraRoleArea.Concat(extraUserArea).Concat(roleTypeArea).Distinct().ToList(); + } + private async Task> GetUserDataScopeTypeAreaList(string orgAreaCode, List roleDataTypeList) + { + var areaCode = await GetCachedAreaCode(); + if (roleDataTypeList.Any(r => r == (int)DataScopeType.ALL)) + { + return areaCode.Select(a => a.Code).ToList(); + } + if (roleDataTypeList.Any(r => new[] { DataScopeType.DEPT_WITH_CHILD, DataScopeType.AREA_WITH_CHILD }.Cast().Contains(r))) + { + return areaCode.Where(a => a.Code.StartsWith(orgAreaCode)).Select(a => a.Code).ToList(); + } + if (roleDataTypeList.Any(r => new[] { DataScopeType.DEPT, DataScopeType.AREA }.Cast().Contains(r))) + { + return areaCode.Where(a => a.Code == orgAreaCode).Select(a => a.Code).ToList(); + } + return new List(); + } + private async Task> GetCachedAreaCode() + { + var areaCodeList = await _sysCacheService.GetAreaCode(); + if (areaCodeList == null || areaCodeList.Count < 1) + { + areaCodeList = await _sysAreaCodeRep.DetachedEntities.ToListAsync(); + } + return areaCodeList; + } } } \ No newline at end of file diff --git a/Api/Ewide.Core/Service/Auth/AuthService.cs b/Api/Ewide.Core/Service/Auth/AuthService.cs index fba2662..0571c5f 100644 --- a/Api/Ewide.Core/Service/Auth/AuthService.cs +++ b/Api/Ewide.Core/Service/Auth/AuthService.cs @@ -169,7 +169,7 @@ namespace Ewide.Core.Service loginOutput.Permissions = await _sysMenuService.GetLoginPermissionList(userId); // 数据范围信息(机构Id集合) - loginOutput.DataScopes = await _sysUserService.GetUserDataScopeIdList(userId); + loginOutput.DataScopes = await _userManager.GetUserAllDataScopeList(); // 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统 loginOutput.Apps = await _sysAppService.GetLoginApps(userId); diff --git a/Api/Ewide.Core/Service/Org/ISysOrgService.cs b/Api/Ewide.Core/Service/Org/ISysOrgService.cs index e77023c..3917eb7 100644 --- a/Api/Ewide.Core/Service/Org/ISysOrgService.cs +++ b/Api/Ewide.Core/Service/Org/ISysOrgService.cs @@ -15,7 +15,6 @@ namespace Ewide.Core.Service Task GetOrgTree([FromQuery] OrgInput input); Task QueryOrgPageList([FromQuery] PageOrgInput input); Task UpdateOrg(UpdateOrgInput input); - Task> GetUserDataScopeIdList(); /// /// 根据区域信息获取单位id /// diff --git a/Api/Ewide.Core/Service/Org/SysOrgService.cs b/Api/Ewide.Core/Service/Org/SysOrgService.cs index da61185..7c15c46 100644 --- a/Api/Ewide.Core/Service/Org/SysOrgService.cs +++ b/Api/Ewide.Core/Service/Org/SysOrgService.cs @@ -51,7 +51,7 @@ namespace Ewide.Core.Service [HttpPost("/sysOrg/page")] public async Task QueryOrgPageList([FromBody] PageOrgInput input) { - var dataScopeList = GetDataScopeList(await GetUserDataScopeIdList()); + var dataScopeList = GetDataScopeList(await _userManager.GetUserAllDataScopeList()); var name = !string.IsNullOrEmpty(input.Name?.Trim()); var id = !string.IsNullOrEmpty(input.Id?.Trim()); @@ -107,7 +107,7 @@ namespace Ewide.Core.Service [HttpGet("/sysOrg/list")] public async Task> GetOrgList([FromQuery] OrgInput input) { - var dataScopeList = GetDataScopeList(await GetUserDataScopeIdList()); + var dataScopeList = GetDataScopeList(await _userManager.GetUserAllDataScopeList()); var pId = !string.IsNullOrEmpty(input.Pid?.Trim()); var orgs = await _sysOrgRep.DetachedEntities @@ -136,7 +136,7 @@ namespace Ewide.Core.Service if (input.Pid != "0" && !string.IsNullOrEmpty(input.Pid)) { // 新增组织机构的父机构不在自己的数据范围内 - var dataScopes = await GetUserDataScopeIdList(); + var dataScopes = await _userManager.GetUserAllDataScopeList(); if (dataScopes.Count < 1 || !dataScopes.Contains(input.Pid)) throw Oops.Oh(ErrorCode.D2003); } @@ -179,7 +179,7 @@ namespace Ewide.Core.Service var sysOrg = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id); // 检测数据范围能不能操作这个机构 - var dataScopes = await GetUserDataScopeIdList(); + var dataScopes = await _userManager.GetUserAllDataScopeList(); if (!_userManager.SuperAdmin && (dataScopes.Count < 1 || !dataScopes.Contains(sysOrg.Id))) throw Oops.Oh(ErrorCode.D2003); @@ -233,7 +233,7 @@ namespace Ewide.Core.Service var sysOrg = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id); // 检测数据范围能不能操作这个机构 - var dataScopes = await GetUserDataScopeIdList(); + var dataScopes = await _userManager.GetUserAllDataScopeList(); if (!_userManager.SuperAdmin && (dataScopes.Count < 1 || !dataScopes.Contains(sysOrg.Id))) throw Oops.Oh(ErrorCode.D2003); @@ -293,7 +293,7 @@ namespace Ewide.Core.Service var dataScopeList = new List(); if (!_userManager.SuperAdmin) { - var dataScopes = await GetUserDataScopeIdList(); + var dataScopes = await _userManager.GetUserAllDataScopeList(); if (dataScopes.Count < 1) return dataScopeList; dataScopeList = GetDataScopeList(dataScopes); @@ -344,17 +344,6 @@ namespace Ewide.Core.Service } return orgIdList; } - - /// - /// 获取用户数据范围(机构Id集合) - /// - /// - [NonAction] - public async Task> GetUserDataScopeIdList() - { - return await App.GetService().GetUserDataScopeIdList(); - } - public async Task> GetAreaDataScopeIdList(int dataScopeType, string orgId) { var org = await _sysOrgRep.FirstOrDefaultAsync(o => o.Id == orgId); diff --git a/Api/Ewide.Core/Service/Role/ISysRoleService.cs b/Api/Ewide.Core/Service/Role/ISysRoleService.cs index 828a2e4..c05d5e2 100644 --- a/Api/Ewide.Core/Service/Role/ISysRoleService.cs +++ b/Api/Ewide.Core/Service/Role/ISysRoleService.cs @@ -12,12 +12,12 @@ namespace Ewide.Core.Service Task GetRoleDropDown(); Task GetRoleInfo([FromQuery] QueryRoleInput input); Task GetRoleList([FromQuery] RoleInput input); - Task> GetUserDataScopeIdList(List roleIdList, string orgId); Task> GetUserRoleList(string userId); Task GrantData(GrantRoleDataInput input); Task GrantMenu(GrantRoleMenuInput input); Task> OwnData([FromQuery] QueryRoleInput input); Task> OwnMenu([FromQuery] QueryRoleInput input); + Task> OwnArea([FromQuery] QueryRoleInput input); Task QueryRolePageList([FromQuery] RoleInput input); Task UpdateRole(UpdateRoleInput input); } diff --git a/Api/Ewide.Core/Service/Role/SysRoleService.cs b/Api/Ewide.Core/Service/Role/SysRoleService.cs index 9646c1a..9df38fd 100644 --- a/Api/Ewide.Core/Service/Role/SysRoleService.cs +++ b/Api/Ewide.Core/Service/Role/SysRoleService.cs @@ -218,7 +218,7 @@ namespace Ewide.Core.Service //如果授权的角色数据范围类型为自定义,则要判断授权的数据范围是否在自己的数据范围内 if ((int)DataScopeType.DEFINE == dataScopeType) { - var dataScopes = await _sysOrgService.GetUserDataScopeIdList(); + var dataScopes = await _userManager.GetUserAllDataScopeList(); var grantOrgIdList = input.GrantOrgIdList; //要授权的数据范围列表 if (grantOrgIdList.Count > 0) { @@ -233,46 +233,6 @@ namespace Ewide.Core.Service await _sysRoleDataScopeService.GrantDataScope(input); } - /// - /// 根据角色Id集合获取数据范围Id集合 - /// - /// - /// - /// - [NonAction] - public async Task> GetUserDataScopeIdList(List roleIdList, string orgId) - { - // 定义角色中最大数据范围的类型,目前按最大范围策略来,如果你同时拥有ALL和SELF的权限,最后按ALL返回 - int strongerDataScopeType = (int)DataScopeType.SELF; - int strongerAreaType = (int)DataScopeType.SELF; - - var customDataScopeRoleIdList = new List(); - if (roleIdList != null && roleIdList.Count > 0) - { - var roles = await _sysRoleRep.DetachedEntities.Where(u => roleIdList.Contains(u.Id)).ToListAsync(); - roles.ForEach(u => - { - if (u.DataScopeType == (int)DataScopeType.DEFINE) - customDataScopeRoleIdList.Add(u.Id); - if ((u.DataScopeType == (int)DataScopeType.AREA || u.DataScopeType == (int)DataScopeType.AREA_WITH_CHILD) && strongerAreaType < u.DataScopeType) - { - strongerAreaType = u.DataScopeType; - } - else if (u.DataScopeType <= strongerDataScopeType) - strongerDataScopeType = u.DataScopeType; - }); - } - - // 自定义数据范围的角色对应的数据范围 - var roleDataScopeIdList = await _sysRoleDataScopeService.GetRoleDataScopeIdList(customDataScopeRoleIdList); - - // 角色中拥有最大数据范围类型的数据范围 - var dataScopeIdList = await _sysOrgService.GetDataScopeListByDataScopeType(strongerDataScopeType, orgId); - //角色区域数据范围 - var areaOrgIdList = await _sysOrgService.GetAreaDataScopeIdList(strongerAreaType, orgId); - return roleDataScopeIdList.Concat(dataScopeIdList).Concat(areaOrgIdList).Distinct().ToList(); //并集 - } - /// /// 根据角色Id获取角色名称 /// @@ -306,7 +266,17 @@ namespace Ewide.Core.Service [HttpGet("/sysRole/ownData")] public async Task> OwnData([FromQuery] QueryRoleInput input) { - return await _sysRoleDataScopeService.GetRoleDataScopeIdList(new List { input.Id }); + return await _userManager.GetRoleExtraDataScopeList(input.Id); + } + /// + /// 获取角色拥有区域Id集合 + /// + /// + /// + [HttpGet("/sysRole/ownArea")] + public Task> OwnArea([FromQuery] QueryRoleInput input) + { + return _userManager.GetRoleExtraAreaScopeList(input.Id); } } } diff --git a/Api/Ewide.Core/Service/User/Dto/OrgUserInput.cs b/Api/Ewide.Core/Service/User/Dto/OrgUserInput.cs new file mode 100644 index 0000000..254cf96 --- /dev/null +++ b/Api/Ewide.Core/Service/User/Dto/OrgUserInput.cs @@ -0,0 +1,6 @@ +namespace Ewide.Core.Service +{ + public class OrgUserInput + { + } +} \ No newline at end of file diff --git a/Api/Ewide.Core/Service/User/Dto/OrgUserTreeNode.cs b/Api/Ewide.Core/Service/User/Dto/OrgUserTreeNode.cs new file mode 100644 index 0000000..fa429d0 --- /dev/null +++ b/Api/Ewide.Core/Service/User/Dto/OrgUserTreeNode.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ewide.Core.Service.User.Dto +{ + public class OrgUserTreeNode : ITreeNode + { + public string Id { get; set; } + public string ParentId { get; set; } + public string Name { get; set; } + public int Type { get; set; } + public List Children { get; set; } + public string GetId() => Id; + public string GetPid() => ParentId; + public void SetChildren(IList children) + { + Children = (List)children; + } + } +} \ No newline at end of file diff --git a/Api/Ewide.Core/Service/User/ISysUserDataScopeService.cs b/Api/Ewide.Core/Service/User/ISysUserDataScopeService.cs index e311601..975ac65 100644 --- a/Api/Ewide.Core/Service/User/ISysUserDataScopeService.cs +++ b/Api/Ewide.Core/Service/User/ISysUserDataScopeService.cs @@ -7,7 +7,6 @@ namespace Ewide.Core.Service { Task DeleteUserDataScopeListByOrgIdList(List orgIdList); Task DeleteUserDataScopeListByUserId(string userId); - Task> GetUserDataScopeIdList(string userId); Task GrantData(UpdateUserInput input); } } \ No newline at end of file diff --git a/Api/Ewide.Core/Service/User/ISysUserRoleService.cs b/Api/Ewide.Core/Service/User/ISysUserRoleService.cs index 1c35421..203fce4 100644 --- a/Api/Ewide.Core/Service/User/ISysUserRoleService.cs +++ b/Api/Ewide.Core/Service/User/ISysUserRoleService.cs @@ -7,7 +7,6 @@ namespace Ewide.Core.Service { Task DeleteUserRoleListByRoleId(string roleId); Task DeleteUserRoleListByUserId(string userId); - Task> GetUserRoleDataScopeIdList(string userId, string orgId); Task> GetUserRoleIdList(string userId); Task GrantRole(UpdateUserInput input); } diff --git a/Api/Ewide.Core/Service/User/ISysUserService.cs b/Api/Ewide.Core/Service/User/ISysUserService.cs index a3bc80d..a021e77 100644 --- a/Api/Ewide.Core/Service/User/ISysUserService.cs +++ b/Api/Ewide.Core/Service/User/ISysUserService.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using Ewide.Core.Service.User.Dto; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks; @@ -12,9 +13,8 @@ namespace Ewide.Core.Service Task ExportUser([FromQuery] UserInput input); Task GetUser([FromQuery] QueryUserInput input); Task GetUserById(string userId); - Task> GetUserDataScopeIdList(); - Task> GetUserDataScopeIdList(string userId); Task GetUserOwnData([FromQuery] QueryUserInput input); + Task GetUserOwnArea([FromQuery] QueryUserInput input); Task GetUserOwnRole([FromQuery] QueryUserInput input); Task GetUserSelector([FromQuery] UserInput input); Task GrantUserData(UpdateUserInput input); @@ -29,5 +29,7 @@ namespace Ewide.Core.Service Task SendCode(Usermailphone input); Task CheckBindcode(Usermailphone input); + + Task GetOrgUserTree(OrgUserInput input); } } \ No newline at end of file diff --git a/Api/Ewide.Core/Service/User/SysUserDataScopeService.cs b/Api/Ewide.Core/Service/User/SysUserDataScopeService.cs index db02381..5742c62 100644 --- a/Api/Ewide.Core/Service/User/SysUserDataScopeService.cs +++ b/Api/Ewide.Core/Service/User/SysUserDataScopeService.cs @@ -63,26 +63,6 @@ namespace Ewide.Core.Service } - /// - /// 获取用户的数据范围Id集合 - /// - /// - /// - public async Task> GetUserDataScopeIdList(string userId) - { - var areaList = await _sysUserAreaRep.DetachedEntities.Where(u => u.SysUserId == userId).Select(u => u.AreaCode).ToListAsync(); - //用户自定义的区域权限所对应的全部组织机构id - List areaDataScopeIdList = new List(); - foreach (var areaNumberCode in areaList) - { - areaDataScopeIdList.AddRange(await _sysOrgRep.DetachedEntities.Where(p => p.AreaCode.StartsWith(areaNumberCode)).Select(p => p.Id).ToListAsync()); - } //用户自定义的组织权限 - var orgIdList = await _sysUserDataScopeRep.DetachedEntities - .Where(u => u.SysUserId == userId) - .Select(u => u.SysOrgId).ToListAsync(); - return areaDataScopeIdList.Concat(orgIdList).Distinct().ToList(); - } - /// /// 根据机构Id集合删除对应的用户-数据范围关联信息 /// diff --git a/Api/Ewide.Core/Service/User/SysUserRoleService.cs b/Api/Ewide.Core/Service/User/SysUserRoleService.cs index 4d34c90..a5a22f4 100644 --- a/Api/Ewide.Core/Service/User/SysUserRoleService.cs +++ b/Api/Ewide.Core/Service/User/SysUserRoleService.cs @@ -57,23 +57,6 @@ namespace Ewide.Core.Service }); } - /// - /// 获取用户所有角色的数据范围(组织机构Id集合) - /// - /// - /// - /// - public async Task> GetUserRoleDataScopeIdList(string userId, string orgId) - { - var roleIdList = await GetUserRoleIdList(userId); - - // 获取这些角色对应的数据范围 - if (roleIdList.Count > 0) - return await _sysRoleService.GetUserDataScopeIdList(roleIdList, orgId); - - return roleIdList; - } - /// /// 根据角色Id删除对应的用户-角色表关联信息 /// diff --git a/Api/Ewide.Core/Service/User/SysUserService.cs b/Api/Ewide.Core/Service/User/SysUserService.cs index f84661f..e32a508 100644 --- a/Api/Ewide.Core/Service/User/SysUserService.cs +++ b/Api/Ewide.Core/Service/User/SysUserService.cs @@ -1,4 +1,5 @@ using Ewide.Core.Service.Role; +using Ewide.Core.Service.User.Dto; using Ewide.Core.Util; using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; @@ -25,6 +26,8 @@ namespace Ewide.Core.Service public class SysUserService : ISysUserService, IDynamicApiController, ITransient { private readonly IRepository _sysUserRep; // 用户表仓储 + private readonly IRepository _sysOrgRep; + private readonly IRepository _sysEmpRep; private readonly IUserManager _userManager; private readonly ISysCacheService _sysCacheService; private readonly ISysEmpService _sysEmpService; @@ -34,6 +37,8 @@ namespace Ewide.Core.Service private readonly ISysUserAreaService _sysUserAreaService; public SysUserService(IRepository sysUserRep, + IRepository sysOrgRep, + IRepository sysEmpRep, IUserManager userManager, IMemoryCache memoryCache, ISysCacheService sysCacheService, @@ -43,6 +48,8 @@ namespace Ewide.Core.Service ISysUserAreaService sysUserAreaService) { _sysUserRep = sysUserRep; + _sysOrgRep = sysOrgRep; + _sysEmpRep = sysEmpRep; _userManager = userManager; _iMemoryCache = memoryCache; _sysCacheService = sysCacheService; @@ -51,7 +58,7 @@ namespace Ewide.Core.Service _sysUserRoleService = sysUserRoleService; _sysUserAreaService = sysUserAreaService; } - + /// /// 分页查询用户 /// @@ -65,11 +72,10 @@ namespace Ewide.Core.Service var pid = input.SysEmpParam.OrgId; var sysEmpRep = Db.GetRepository(); - var sysOrgRep = Db.GetRepository(); - var dataScopes = await GetUserDataScopeIdList(_userManager.UserId); + var dataScopes = await _userManager.GetUserAllDataScopeList(); var users = await _sysUserRep.DetachedEntities .Join(sysEmpRep.DetachedEntities, u => u.Id, e => e.Id, (u, e) => new { u, e }) - .Join(sysOrgRep.DetachedEntities, n => n.e.OrgId, o => o.Id, (n, o) => new { n, o }) + .Join(_sysOrgRep.DetachedEntities, n => n.e.OrgId, o => o.Id, (n, o) => new { n, o }) .Where(!string.IsNullOrEmpty(searchValue), x => (x.n.u.Account.Contains(input.SearchValue) || x.n.u.Name.Contains(input.SearchValue) || x.n.u.Phone.Contains(input.SearchValue))) @@ -170,9 +176,9 @@ namespace Ewide.Core.Service if (isExist) throw Oops.Oh(ErrorCode.D1003); var user = input.Adapt(); - await user.UpdateIncludeAsync(new[] { - nameof(SysUser.Account), - nameof(SysUser.NickName), + await user.UpdateIncludeAsync(new[] { + nameof(SysUser.Account), + nameof(SysUser.NickName), nameof(SysUser.Name), nameof(SysUser.Birthday), nameof(SysUser.Sex), @@ -304,7 +310,7 @@ namespace Ewide.Core.Service [HttpGet("/sysUser/ownData")] public async Task GetUserOwnData([FromQuery] QueryUserInput input) { - return await _sysUserDataScopeService.GetUserDataScopeIdList(input.Id); + return await _userManager.GetUserExtraDataScopeList(input.Id); } /// /// 获取用户拥有区域 @@ -314,7 +320,7 @@ namespace Ewide.Core.Service [HttpGet("/sysUser/ownArea")] public async Task GetUserOwnArea([FromQuery] QueryUserInput input) { - return await _sysUserAreaService.GetUserAreaIdList(input.Id); + return await _userManager.GetUserExtraAreaScopeList(input.Id); } /// /// 重置用户密码 @@ -405,47 +411,6 @@ namespace Ewide.Core.Service await user.InsertAsync(); } - /// - /// 获取用户数据范围(机构Id集合)并缓存 - /// - /// - /// - [NonAction] - [UnitOfWork] - public async Task> GetUserDataScopeIdList(string userId) - { - var dataScopes = await _sysCacheService.GetDataScope(userId); // 先从缓存里面读取 - if (dataScopes == null || dataScopes.Count < 1) - { - var orgId = await _sysEmpService.GetEmpOrgId(userId); - - // 获取该用户对应的数据范围集合 - var userDataScopeIdListForUser = await _sysUserDataScopeService.GetUserDataScopeIdList(userId); - - // 获取该用户的角色对应的数据范围集合 - var userDataScopeIdListForRole = await _sysUserRoleService.GetUserRoleDataScopeIdList(userId, orgId); - - dataScopes = userDataScopeIdListForUser.Concat(userDataScopeIdListForRole).Distinct().ToList(); // 并集 - -#if DEBUG -#else - await _sysCacheService.SetDataScope(userId, dataScopes); // 缓存结果 -#endif - } - return dataScopes; - } - - /// - /// 获取用户数据范围(机构Id集合) - /// - /// - [NonAction] - public async Task> GetUserDataScopeIdList() - { - var userId = _userManager.UserId; - var dataScopes = await GetUserDataScopeIdList(userId); - return dataScopes; - } /// /// 检查普通用户数据范围 @@ -457,7 +422,7 @@ namespace Ewide.Core.Service // 如果当前用户不是超级管理员,则进行数据范围校验 if (!_userManager.SuperAdmin) { - var dataScopes = await GetUserDataScopeIdList(_userManager.UserId); + var dataScopes = await _userManager.GetUserAllDataScopeList(); if (dataScopes == null || (userParam.SysEmpParam.OrgId != null && !dataScopes.Contains(userParam.SysEmpParam.OrgId))) throw Oops.Oh(ErrorCode.D1013); } @@ -476,7 +441,7 @@ namespace Ewide.Core.Service var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"; CodeHelper ch = new CodeHelper(_iMemoryCache); //Type为1时,给原手机号发送验证码 - if(input.Type == 1) + if (input.Type == 1) { try { @@ -486,12 +451,12 @@ namespace Ewide.Core.Service { throw Oops.Oh(ErrorCode.D1018); } - + } //Type为2时,给原邮箱发送验证码 - else if(input.Type == 2) + else if (input.Type == 2) { - if(new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").IsMatch(_userManager.User.Email)) + if (new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").IsMatch(_userManager.User.Email)) { try { @@ -508,20 +473,20 @@ namespace Ewide.Core.Service else { //通过正则判断绑定类型 - if(new Regex(Regex_phone).IsMatch(input.Target)) + if (new Regex(Regex_phone).IsMatch(input.Target)) { try { - + ch.SendSmscode(input.Target, Smscode_Key); return true; } - catch(Exception e) + catch (Exception e) { throw Oops.Oh(ErrorCode.D1018); } } - if(new Regex(Regex_Email).IsMatch(input.Target)) + if (new Regex(Regex_Email).IsMatch(input.Target)) { try { @@ -550,7 +515,7 @@ namespace Ewide.Core.Service var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"; var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId); CodeHelper ch = new CodeHelper(_iMemoryCache); - if(input.Type == 1) + if (input.Type == 1) { if (ch.Checkcode(_userManager.User.Phone, input.Orgcode, Orgcode_Key)) { @@ -558,9 +523,9 @@ namespace Ewide.Core.Service }; throw Oops.Oh("验证错误"); } - else if(input.Type == 2) + else if (input.Type == 2) { - if(ch.Checkcode(_userManager.User.Email, input.Orgcode, Orgcode_Key)) + if (ch.Checkcode(_userManager.User.Email, input.Orgcode, Orgcode_Key)) { return true; } @@ -569,11 +534,11 @@ namespace Ewide.Core.Service else { //为第一次绑定 - if(string.IsNullOrEmpty(_userManager.User.Phone) && string.IsNullOrEmpty(_userManager.User.Email)) + if (string.IsNullOrEmpty(_userManager.User.Phone) && string.IsNullOrEmpty(_userManager.User.Email)) { - if(new Regex(Regex_phone).IsMatch(input.Target)) + if (new Regex(Regex_phone).IsMatch(input.Target)) { - if (ch.Checkcode(input.Target,input.Code, Smscode_Key)) + if (ch.Checkcode(input.Target, input.Code, Smscode_Key)) { try { @@ -590,7 +555,7 @@ namespace Ewide.Core.Service } throw Oops.Oh("验证码失效"); } - if(new Regex(Regex_Email).IsMatch(input.Target)) + if (new Regex(Regex_Email).IsMatch(input.Target)) { if (ch.Checkcode(input.Target, input.Code, Mailcode_Key)) { @@ -659,7 +624,19 @@ namespace Ewide.Core.Service } throw Oops.Oh("验证码失效"); } - } + } + } + + [HttpPost("/sysUser/GetOrgUserTree")] + public async Task GetOrgUserTree(OrgUserInput input) + { + var list = await (from u in _sysUserRep.DetachedEntities + join e in _sysEmpRep.DetachedEntities on u.Id equals e.Id + select new OrgUserTreeNode { Id = u.Id, ParentId = e.OrgId, Type = 1, Name = u.Name }).Union( + from o in _sysOrgRep.DetachedEntities + select new OrgUserTreeNode { Id = o.Id, ParentId = o.Pid, Type = 0, Name = o.Name }).ToListAsync(); + + return new TreeBuildUtil(new TreeBuildSetting { AddEmptyChildren = false }).DoTreeBuild(list); } } } diff --git a/Api/Ewide.Core/Util/TreeBuildUtil.cs b/Api/Ewide.Core/Util/TreeBuildUtil.cs index 155bb81..b199517 100644 --- a/Api/Ewide.Core/Util/TreeBuildUtil.cs +++ b/Api/Ewide.Core/Util/TreeBuildUtil.cs @@ -27,6 +27,10 @@ namespace Ewide.Core /// void SetChildren(IList children); } + public class TreeBuildSetting + { + public bool AddEmptyChildren { get; set; } = true; + } /// /// 递归工具类,用于遍历有父子关系的节点,例如菜单树,字典树等等 @@ -34,10 +38,15 @@ namespace Ewide.Core /// public class TreeBuildUtil where T : ITreeNode { + TreeBuildSetting _setting; + public TreeBuildUtil(TreeBuildSetting setting = null) + { + _setting = setting ?? new TreeBuildSetting(); + } /// /// 顶级节点的父节点Id(默认0) /// - private readonly List _rootParentIds = new List {string.Empty,Guid.Empty.ToString() }; + private readonly List _rootParentIds = new List { string.Empty, Guid.Empty.ToString() }; /// /// 构造树节点 @@ -59,7 +68,8 @@ namespace Ewide.Core if (results.Count < 1) { var ids = new List(); - nodes.ForEach(u => { + nodes.ForEach(u => + { ids.Add(u.GetId()); }); @@ -89,7 +99,10 @@ namespace Ewide.Core }); nodeSubLists.ForEach(u => BuildChildNodes(totalNodes, u, new List())); childNodeLists.AddRange(nodeSubLists); - node.SetChildren(childNodeLists); + if (childNodeLists.Count > 0 || _setting.AddEmptyChildren) + { + node.SetChildren(childNodeLists); + } } } } diff --git a/Api/Ewide.Web.Core/Handlers/JwtHandler.cs b/Api/Ewide.Web.Core/Handlers/JwtHandler.cs index 443afe6..2e0bf42 100644 --- a/Api/Ewide.Web.Core/Handlers/JwtHandler.cs +++ b/Api/Ewide.Web.Core/Handlers/JwtHandler.cs @@ -69,7 +69,7 @@ namespace Ewide.Web.Core if (defalutRoute.Contains(routeName)) return true; // 获取用户权限集合(按钮或API接口) - var permissionList = await App.GetService().GetLoginPermissionList(userManager.UserId); + var permissionList = await userManager.GetLoginPermissionList(); // 检查授权 return permissionList.Contains(routeName); diff --git a/Api/Ewide.sln b/Api/Ewide.sln index c48a622..bb1280d 100644 --- a/Api/Ewide.sln +++ b/Api/Ewide.sln @@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ewide.Database.Migrations", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ewide.Web.Entry", "Ewide.Web.Entry\Ewide.Web.Entry.csproj", "{9826E365-EEE9-4721-A738-B02AB64D47E5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ewide.Test", "Ewide.Test\Ewide.Test.csproj", "{DECE4796-6B13-4607-9C27-C1FE093D4DC8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ewide.Test", "Ewide.Test\Ewide.Test.csproj", "{DECE4796-6B13-4607-9C27-C1FE093D4DC8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution