386 lines
17 KiB
C#
386 lines
17 KiB
C#
using Furion.DatabaseAccessor;
|
||
using Furion.DependencyInjection;
|
||
using Furion.FriendlyException;
|
||
using Microsoft.AspNetCore.Http;
|
||
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
|
||
{
|
||
/// <summary>
|
||
/// 用户管理
|
||
/// </summary>
|
||
public class UserManager : IUserManager, IScoped
|
||
{
|
||
private readonly IRepository<SysUser> _sysUserRep; // 用户表仓储
|
||
private readonly IRepository<SysRole> _sysRoleRep;
|
||
private readonly IRepository<SysUserRole> _sysUserRoleRep;
|
||
private readonly IRepository<SysEmp> _sysEmpRep; // 员工表
|
||
private readonly IRepository<SysOrg> _sysOrgRep;
|
||
private readonly IRepository<SysRoleMenu> _sysRoleMenuRep;
|
||
private readonly IRepository<SysMenu> _sysMenuRep;
|
||
private readonly IRepository<SysUserDataScope> _sysUserDataScopeRep;
|
||
private readonly IRepository<SysUserArea> _sysUserAreaRep;
|
||
private readonly IRepository<SysRoleDataScope> _sysRoleDataRep;
|
||
private readonly IRepository<SysRoleArea> _sysRoleAreaRep;
|
||
private readonly IRepository<SysAreaCode> _sysAreaCodeRep;
|
||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||
private readonly ISysCacheService _sysCacheService;
|
||
|
||
public string UserId
|
||
{
|
||
get => _httpContextAccessor.HttpContext.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
|
||
}
|
||
|
||
public string Account
|
||
{
|
||
get => _httpContextAccessor.HttpContext.User.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value;
|
||
}
|
||
|
||
public string Name
|
||
{
|
||
get => _httpContextAccessor.HttpContext.User.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
|
||
}
|
||
|
||
public bool SuperAdmin
|
||
{
|
||
get => _httpContextAccessor.HttpContext.User.FindFirst(ClaimConst.CLAINM_SUPERADMIN)?.Value == ((int)AdminType.SuperAdmin).ToString();
|
||
}
|
||
|
||
public SysUser User
|
||
{
|
||
get => _sysUserRep.Find(UserId);
|
||
}
|
||
|
||
public UserManager(
|
||
IHttpContextAccessor httpContextAccessor,
|
||
ISysCacheService sysCacheService,
|
||
IRepository<SysUser> sysUserRep,
|
||
IRepository<SysRole> sysRoleRep,
|
||
IRepository<SysUserRole> sysUserRoleRep,
|
||
IRepository<SysEmp> sysEmpRep,
|
||
IRepository<SysOrg> sysOrgRep,
|
||
IRepository<SysRoleMenu> sysRoleMenuRep,
|
||
IRepository<SysMenu> sysMenuRep,
|
||
IRepository<SysUserDataScope> sysUserDataScopeRep, IRepository<SysUserArea> sysUserAreaRep, IRepository<SysRoleDataScope> sysRoleDataRep, IRepository<SysRoleArea> sysRoleAreaRep, IRepository<SysAreaCode> sysAreaCodeRep)
|
||
{
|
||
_sysUserRep = sysUserRep;
|
||
_sysRoleRep = sysRoleRep;
|
||
_sysUserRoleRep = sysUserRoleRep;
|
||
_sysEmpRep = sysEmpRep;
|
||
_sysOrgRep = sysOrgRep;
|
||
_httpContextAccessor = httpContextAccessor;
|
||
_sysCacheService = sysCacheService;
|
||
_sysRoleMenuRep = sysRoleMenuRep;
|
||
_sysMenuRep = sysMenuRep;
|
||
_sysUserDataScopeRep = sysUserDataScopeRep;
|
||
_sysUserAreaRep = sysUserAreaRep;
|
||
_sysRoleDataRep = sysRoleDataRep;
|
||
_sysRoleAreaRep = sysRoleAreaRep;
|
||
_sysAreaCodeRep = sysAreaCodeRep;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户信息
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
public async Task<SysUser> CheckUserAsync(string userId)
|
||
{
|
||
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == userId, false);
|
||
return user ?? throw Oops.Oh(ErrorCode.D1002);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<SysUser> CheckUserAsync()
|
||
{
|
||
return await CheckUserAsync(UserId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户员工信息
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
public async Task<SysEmp> GetUserEmpInfo(string userId)
|
||
{
|
||
var emp = await _sysEmpRep.FirstOrDefaultAsync(u => u.Id == userId, false);
|
||
return emp ?? throw Oops.Oh(ErrorCode.D1002);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户员工信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<SysEmp> GetUserEmpInfo()
|
||
{
|
||
return await GetUserEmpInfo(UserId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户部门信息
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
public async Task<SysOrg> GetUserOrgInfo(string userId)
|
||
{
|
||
var emp = await GetUserEmpInfo(userId);
|
||
var org = await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == emp.OrgId, false);
|
||
return org ?? throw Oops.Oh(ErrorCode.D1002);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户部门信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<SysOrg> GetUserOrgInfo()
|
||
{
|
||
return await GetUserOrgInfo(UserId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户角色Id列表
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
public async Task<List<string>> GetUserRoleIdList(string userId)
|
||
{
|
||
var roleIds = await _sysUserRoleRep.DetachedEntities.Where(u => u.SysUserId == userId).Select(u => u.SysRoleId).ToListAsync();
|
||
return roleIds;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户角色Id列表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<List<string>> GetUserRoleIdList()
|
||
{
|
||
return await GetUserRoleIdList(UserId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户角色列表
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
public async Task<List<SysRole>> GetUserRoleList(string userId)
|
||
{
|
||
var roleIds = await GetUserRoleIdList(userId);
|
||
var roles = await _sysRoleRep.DetachedEntities.Where(u => roleIds.Contains(u.Id)).ToListAsync();
|
||
return roles;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户角色列表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<List<SysRole>> GetUserRoleList()
|
||
{
|
||
return await GetUserRoleList(UserId);
|
||
}
|
||
|
||
public async Task<List<string>> 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<List<string>> GetUserExtraDataScopeList()
|
||
{
|
||
return GetUserExtraDataScopeList(UserId);
|
||
}
|
||
|
||
public async Task<List<string>> GetUserExtraDataScopeList(string userId)
|
||
{
|
||
return await _sysUserDataScopeRep.DetachedEntities
|
||
.Where(u => u.SysUserId == userId)
|
||
.Select(u => u.SysOrgId).ToListAsync();
|
||
}
|
||
|
||
public Task<List<string>> GetUserExtraAreaScopeList()
|
||
{
|
||
return GetUserExtraAreaScopeList(UserId);
|
||
}
|
||
|
||
public async Task<List<string>> GetUserExtraAreaScopeList(string userId)
|
||
{
|
||
return await _sysUserAreaRep.DetachedEntities.Where(u => u.SysUserId == userId).Select(u => u.AreaCode).ToListAsync();
|
||
}
|
||
|
||
public Task<List<string>> GetRoleExtraDataScopeList(string roleId)
|
||
{
|
||
return _sysRoleDataRep.DetachedEntities.Where(u => u.SysRoleId == roleId).Select(u => u.SysOrgId).ToListAsync();
|
||
}
|
||
|
||
public Task<List<string>> GetRoleExtraAreaScopeList(string roleId)
|
||
{
|
||
return _sysRoleAreaRep.DetachedEntities.Where(u => u.SysRoleId == roleId).Select(u => u.AreaCode).ToListAsync();
|
||
}
|
||
public Task<List<string>> GetUserAllDataScopeList()
|
||
{
|
||
return GetUserAllDataScopeList(UserId);
|
||
}
|
||
public async Task<List<string>> GetDataScopeListByDataScopeType(int dataScopeType, string orgId)
|
||
{
|
||
var orgIdList = new List<string>();
|
||
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<List<string>> 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<int>();
|
||
var strongerDataScopeType = (int)DataScopeType.SELF;
|
||
var strongerAreaType = (int)DataScopeType.SELF;
|
||
|
||
//获取区域相关的角色类型中最大的区域角色
|
||
var customDataScopeRoleIdList = new List<string>();
|
||
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<string>();
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 获取用户可以访问的区域权限
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public Task<List<string>> GetUserAllAreaList()
|
||
{
|
||
return GetUserAllAreaList(UserId);
|
||
}
|
||
|
||
public async Task<List<string>> 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 customAreaRole = roles.Where(r => r.DataScopeType == (int)DataScopeType.DEFINE).Select(r => r.Id);
|
||
var extraRoleArea = await _sysRoleAreaRep.DetachedEntities.Where(ra => customAreaRole.Contains(ra.SysRoleId)).Select(ra => ra.AreaCode).ToListAsync();
|
||
var roleTypeArea = await GetUserDataScopeTypeAreaList(orgAreaCode, roles.Select(r => r.DataScopeType).ToList());
|
||
var extraArea = await GetUserExtraAreaList(extraRoleArea.Concat(extraUserArea).Distinct().ToList());
|
||
return extraArea.Concat(roleTypeArea).Distinct().ToList();
|
||
}
|
||
private async Task<List<string>> GetUserExtraAreaList(List<string> extraAreaCode)
|
||
{
|
||
var cachedAreaCode = await GetCachedAreaCode();
|
||
return cachedAreaCode.Select(a => a.Code).Where(a => extraAreaCode.Any(e => a.StartsWith(e))).ToList();
|
||
}
|
||
private async Task<List<string>> GetUserDataScopeTypeAreaList(string orgAreaCode, List<int> 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<int>().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<int>().Contains(r)))
|
||
{
|
||
return areaCode.Where(a => a.Code == orgAreaCode).Select(a => a.Code).ToList();
|
||
}
|
||
return new List<string>();
|
||
}
|
||
private async Task<List<SysAreaCode>> GetCachedAreaCode()
|
||
{
|
||
var areaCodeList = await _sysCacheService.GetAreaCode();
|
||
if (areaCodeList == null || areaCodeList.Count < 1)
|
||
{
|
||
areaCodeList = await _sysAreaCodeRep.DetachedEntities.ToListAsync();
|
||
}
|
||
return areaCodeList;
|
||
}
|
||
}
|
||
} |