Merge pull request '🍒 feat: 增强session功能' (#437) from jasondom/Admin.NET.Pro:v2 into v2
Reviewed-on: https://code.adminnet.top/Admin.NET/Admin.NET.Pro/pulls/437
This commit is contained in:
commit
7aa71cf95f
@ -171,8 +171,6 @@ public class AppAuthService : IDynamicApiController, ITransient
|
|||||||
.LeftJoin<SysRole>((u, a) => u.RoleId == a.Id)
|
.LeftJoin<SysRole>((u, a) => u.RoleId == a.Id)
|
||||||
.Where(u => u.UserId == user.Id)
|
.Where(u => u.UserId == user.Id)
|
||||||
.Select((u, a) => new RoleDto { Id = a.Id, Name = a.Name, Code = a.Code }).ToListAsync();
|
.Select((u, a) => new RoleDto { Id = a.Id, Name = a.Name, Code = a.Code }).ToListAsync();
|
||||||
// 接口集合
|
|
||||||
var apis = (await _sysRoleService.GetUserApiList())[0];
|
|
||||||
|
|
||||||
return new LoginUserOutput
|
return new LoginUserOutput
|
||||||
{
|
{
|
||||||
@ -190,8 +188,8 @@ public class AppAuthService : IDynamicApiController, ITransient
|
|||||||
OrgName = org?.Name,
|
OrgName = org?.Name,
|
||||||
OrgType = org?.Type,
|
OrgType = org?.Type,
|
||||||
PosName = pos?.Name,
|
PosName = pos?.Name,
|
||||||
Apis = apis,
|
Roles = roles,
|
||||||
Roles = roles
|
Apis = _appUserManager.Permissions,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,6 @@ namespace Admin.NET.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
||||||
{
|
{
|
||||||
private static readonly Lazy<SqlSugarRepository<SysUser>> _sysUserRep = new(() => App.GetService<SqlSugarRepository<SysUser>>());
|
|
||||||
private static readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
private readonly ILogger<DatabaseLoggingWriter> _logger;
|
private readonly ILogger<DatabaseLoggingWriter> _logger;
|
||||||
private readonly SysConfigService _sysConfigService;
|
private readonly SysConfigService _sysConfigService;
|
||||||
private readonly IEventPublisher _eventPublisher;
|
private readonly IEventPublisher _eventPublisher;
|
||||||
@ -190,6 +188,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private LoggingUserInfo GetUserInfo(LoggingMonitorDto loggingMonitor)
|
private LoggingUserInfo GetUserInfo(LoggingMonitorDto loggingMonitor)
|
||||||
{
|
{
|
||||||
|
var userManger = LazyHelper.GetService<UserManager>();
|
||||||
LoggingUserInfo result = new();
|
LoggingUserInfo result = new();
|
||||||
if (loggingMonitor.AuthorizationClaims != null)
|
if (loggingMonitor.AuthorizationClaims != null)
|
||||||
{
|
{
|
||||||
@ -198,7 +197,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
.GetValueOrDefault(ClaimConst.UserId) ?? ""
|
.GetValueOrDefault(ClaimConst.UserId) ?? ""
|
||||||
, out var temp) ? temp : null;
|
, out var temp) ? temp : null;
|
||||||
|
|
||||||
var userSession = _userManager.Value.GetSession(result.UserId);
|
var userSession = userManger.GetSession(result.UserId);
|
||||||
result.TenantId = long.TryParse(userSession?.TenantId?.ToString() ?? "", out temp) ? temp : null;
|
result.TenantId = long.TryParse(userSession?.TenantId?.ToString() ?? "", out temp) ? temp : null;
|
||||||
result.RealName = userSession?.RealName;
|
result.RealName = userSession?.RealName;
|
||||||
result.Account = userSession?.Account;
|
result.Account = userSession?.Account;
|
||||||
@ -207,7 +206,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
// 退出登陆时没有session,尝试从数据库中获取
|
// 退出登陆时没有session,尝试从数据库中获取
|
||||||
if (string.IsNullOrWhiteSpace(result.Account) && result.UserId != null)
|
if (string.IsNullOrWhiteSpace(result.Account) && result.UserId != null)
|
||||||
{
|
{
|
||||||
var user = _sysUserRep.Value.GetById(result.UserId);
|
var user = _db.Queryable<SysUser>().First(u => u.Id == result.UserId);
|
||||||
result.Account = user?.TenantId?.ToString();
|
result.Account = user?.TenantId?.ToString();
|
||||||
result.RealName = user?.RealName;
|
result.RealName = user?.RealName;
|
||||||
result.Account = user?.Account;
|
result.Account = user?.Account;
|
||||||
@ -221,7 +220,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
result.Account = (loggingMonitor.Parameters[0].Value as JObject)!.GetValue("account")?.ToString();
|
result.Account = (loggingMonitor.Parameters[0].Value as JObject)!.GetValue("account")?.ToString();
|
||||||
if (!string.IsNullOrEmpty(result.Account))
|
if (!string.IsNullOrEmpty(result.Account))
|
||||||
{
|
{
|
||||||
var user = _sysUserRep.Value.AsQueryable().First(u => u.Account == result.Account);
|
var user = _db.Queryable<SysUser>().First(u => u.Account == result.Account);
|
||||||
result.TenantId = user?.TenantId;
|
result.TenantId = user?.TenantId;
|
||||||
result.RealName = user?.RealName;
|
result.RealName = user?.RealName;
|
||||||
result.UserId = user?.Id;
|
result.UserId = user?.Id;
|
||||||
|
|||||||
@ -17,7 +17,6 @@ public class ElasticSearchLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
private readonly ElasticsearchClient _esClient;
|
private readonly ElasticsearchClient _esClient;
|
||||||
private readonly SysCacheService _sysCacheService;
|
private readonly SysCacheService _sysCacheService;
|
||||||
private readonly SysConfigService _sysConfigService;
|
private readonly SysConfigService _sysConfigService;
|
||||||
private static readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
|
|
||||||
public ElasticSearchLoggingWriter(IServiceScopeFactory scopeFactory)
|
public ElasticSearchLoggingWriter(IServiceScopeFactory scopeFactory)
|
||||||
{
|
{
|
||||||
@ -51,7 +50,7 @@ public class ElasticSearchLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
|||||||
{
|
{
|
||||||
if (item.type != ClaimConst.UserId) continue;
|
if (item.type != ClaimConst.UserId) continue;
|
||||||
userId = item.value;
|
userId = item.value;
|
||||||
userSession = _userManager.Value?.GetSession(userId);
|
userSession = LazyHelper.GetService<UserManager>().GetSessionOrRefresh(userId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tenantId = userSession?.TenantId.ToString();
|
tenantId = userSession?.TenantId.ToString();
|
||||||
|
|||||||
@ -11,7 +11,6 @@ namespace Admin.NET.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpLoggingHandler : DelegatingHandler, ITransient
|
public class HttpLoggingHandler : DelegatingHandler, ITransient
|
||||||
{
|
{
|
||||||
private static readonly Lazy<UserManager> UserManager = new(() => App.GetService<UserManager>());
|
|
||||||
private readonly Dictionary<string, HttpRemoteItem> _optionMap;
|
private readonly Dictionary<string, HttpRemoteItem> _optionMap;
|
||||||
private readonly SysConfigService _sysConfigService;
|
private readonly SysConfigService _sysConfigService;
|
||||||
private readonly IEventPublisher _eventPublisher;
|
private readonly IEventPublisher _eventPublisher;
|
||||||
@ -39,6 +38,7 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
if (!enabledLog || attr?.IgnoreLog == true) return await base.SendAsync(request, cancellationToken);
|
if (!enabledLog || attr?.IgnoreLog == true) return await base.SendAsync(request, cancellationToken);
|
||||||
|
|
||||||
var stopWatch = Stopwatch.StartNew();
|
var stopWatch = Stopwatch.StartNew();
|
||||||
|
var userManger = LazyHelper.GetService<UserManager>();
|
||||||
var urlList = request.RequestUri?.LocalPath.Split("/") ?? [];
|
var urlList = request.RequestUri?.LocalPath.Split("/") ?? [];
|
||||||
var sysLogHttp = new SysLogHttp
|
var sysLogHttp = new SysLogHttp
|
||||||
{
|
{
|
||||||
@ -49,9 +49,9 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
RequestUrl = request.RequestUri?.ToString(),
|
RequestUrl = request.RequestUri?.ToString(),
|
||||||
RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson(),
|
RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson(),
|
||||||
RequestBodyPlaintext = request.GetRequestBodyPlaintext(),
|
RequestBodyPlaintext = request.GetRequestBodyPlaintext(),
|
||||||
TenantId = UserManager.Value?.TenantId,
|
TenantId = userManger?.TenantId,
|
||||||
CreateUserId = UserManager.Value?.UserId,
|
CreateUserId = userManger?.UserId,
|
||||||
CreateUserName = UserManager.Value?.RealName,
|
CreateUserName = userManger?.RealName,
|
||||||
};
|
};
|
||||||
if (request.Content != null) sysLogHttp.RequestBody = await request.Content.ReadAsStringAsync(cancellationToken);
|
if (request.Content != null) sysLogHttp.RequestBody = await request.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
|
||||||
|
|||||||
@ -221,16 +221,15 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <param name="loginMode"></param>
|
/// <param name="loginMode"></param>
|
||||||
/// <param name="isRefresh"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode = LoginModeEnum.PC, bool isRefresh = false)
|
public async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode = LoginModeEnum.PC)
|
||||||
{
|
{
|
||||||
// 单用户登录
|
// 单用户登录
|
||||||
await App.GetRequiredService<SysOnlineUserService>().SingleLogin(user.Id, loginMode);
|
await App.GetRequiredService<SysOnlineUserService>().SingleLogin(user.Id, loginMode);
|
||||||
|
|
||||||
// 生成Token令牌
|
// 生成Token令牌
|
||||||
if(!isRefresh) user.TokenVersion += 1;
|
user.TokenVersion += 1;
|
||||||
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
||||||
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
@ -238,24 +237,6 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
{ ClaimConst.TokenVersion, user.TokenVersion },
|
{ ClaimConst.TokenVersion, user.TokenVersion },
|
||||||
}, tokenExpire);
|
}, tokenExpire);
|
||||||
|
|
||||||
// 缓存用户Session
|
|
||||||
_userManager.SetSession(new()
|
|
||||||
{
|
|
||||||
UserId = user.Id,
|
|
||||||
TenantId = user.TenantId,
|
|
||||||
Account = user.Account,
|
|
||||||
RealName = user.RealName,
|
|
||||||
AccountType = user.AccountType,
|
|
||||||
OrgId = user.OrgId,
|
|
||||||
OrgCode = user.SysOrg?.Code,
|
|
||||||
OrgName = user.SysOrg?.Name,
|
|
||||||
OrgType = user.SysOrg?.Type,
|
|
||||||
OrgLevel = user.SysOrg?.Level,
|
|
||||||
LoginMode = loginMode,
|
|
||||||
TokenVersion = user.TokenVersion,
|
|
||||||
ExtProps = App.GetServices<IUserSessionExtProps>().SelectMany(u => u.GetInitExtProps(user)).ToDictionary(u => u.Key, u => u.Value)
|
|
||||||
}, TimeSpan.FromMinutes(tokenExpire));
|
|
||||||
|
|
||||||
// 生成刷新Token令牌
|
// 生成刷新Token令牌
|
||||||
var refreshTokenExpire = await _sysConfigService.GetRefreshTokenExpire();
|
var refreshTokenExpire = await _sysConfigService.GetRefreshTokenExpire();
|
||||||
var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);
|
var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);
|
||||||
@ -267,27 +248,27 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);
|
// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);
|
||||||
|
|
||||||
// 更新用户登录信息
|
// 更新用户登录信息
|
||||||
if (!isRefresh)
|
user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true);
|
||||||
|
(user.LastLoginAddress, double? longitude, double? latitude) = CommonHelper.GetIpAddress(user.LastLoginIp);
|
||||||
|
user.LastLoginTime = DateTime.Now;
|
||||||
|
user.LastLoginDevice = CommonHelper.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent);
|
||||||
|
await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new
|
||||||
{
|
{
|
||||||
user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true);
|
u.TokenVersion,
|
||||||
(user.LastLoginAddress, double? longitude, double? latitude) = CommonHelper.GetIpAddress(user.LastLoginIp);
|
u.LastLoginIp,
|
||||||
user.LastLoginTime = DateTime.Now;
|
u.LastLoginAddress,
|
||||||
user.LastLoginDevice = CommonHelper.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent);
|
u.LastLoginTime,
|
||||||
await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new
|
u.LastLoginDevice,
|
||||||
{
|
}).ExecuteCommandAsync();
|
||||||
u.TokenVersion,
|
|
||||||
u.LastLoginIp,
|
|
||||||
u.LastLoginAddress,
|
|
||||||
u.LastLoginTime,
|
|
||||||
u.LastLoginDevice,
|
|
||||||
}).ExecuteCommandAsync();
|
|
||||||
|
|
||||||
// 缓存用户Token版本
|
// 缓存用户Token版本
|
||||||
_sysCacheService.Set($"{CacheConst.KeyUserToken}{user.Id}", $"{user.TokenVersion}");
|
_sysCacheService.Set($"{CacheConst.KeyUserToken}{user.Id}", $"{user.TokenVersion}");
|
||||||
|
|
||||||
// 发布系统登录事件
|
// 发布系统登录事件
|
||||||
await _eventPublisher.PublishAsync(UserEventTypeEnum.Login, user);
|
await _eventPublisher.PublishAsync(UserEventTypeEnum.Login, user);
|
||||||
}
|
|
||||||
|
// 缓存用户Session
|
||||||
|
await SetUserSession(user, loginMode);
|
||||||
|
|
||||||
return new LoginOutput
|
return new LoginOutput
|
||||||
{
|
{
|
||||||
@ -296,6 +277,56 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置用户Session
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="loginMode"></param>
|
||||||
|
private async Task SetUserSession(SysUser user, LoginModeEnum loginMode = LoginModeEnum.PC)
|
||||||
|
{
|
||||||
|
var db = _sysUserRep.Context.CopyNew();
|
||||||
|
user.SysPos ??= await db.Queryable<SysPos>().FirstAsync(u => u.Id == user.PosId);
|
||||||
|
user.SysOrg ??= await db.Queryable<SysOrg>().FirstAsync(u => u.Id == user.OrgId);
|
||||||
|
|
||||||
|
var permissions = await LazyHelper.GetService<SysRoleService>().GetUserApiList(user.Id);
|
||||||
|
var unauthorizedPermissions = await LazyHelper.GetService<SysRoleService>().GetUnAuthApiList(user.Id);
|
||||||
|
var orgIds = await LazyHelper.GetService<SysOrgService>().GetUserOrgIdList(user.Id, user.OrgId);
|
||||||
|
var roleIds = await db.Queryable<SysUserRole>().Where(u => u.UserId == user.Id).Select(u => u.RoleId).ToListAsync();
|
||||||
|
var postIds = await db.Queryable<SysUserExtOrg>().Where(u => u.UserId == user.Id).Select(u => u.PosId).ToListAsync() ?? [];
|
||||||
|
var maxDataScope = await db.Queryable<SysRole>().Where(u => roleIds.Contains(u.Id)).MinAsync(u => u.DataScope);
|
||||||
|
if (maxDataScope == 0) maxDataScope = DataScopeEnum.Self;
|
||||||
|
postIds.Add(user.PosId);
|
||||||
|
|
||||||
|
// 缓存用户Session
|
||||||
|
_userManager.SetSession(new()
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
TenantId = user.TenantId,
|
||||||
|
Account = user.Account,
|
||||||
|
RealName = user.RealName,
|
||||||
|
NickName = user.NickName,
|
||||||
|
AccountType = user.AccountType,
|
||||||
|
OrgId = user.OrgId,
|
||||||
|
OrgCode = user.SysOrg?.Code,
|
||||||
|
OrgName = user.SysOrg?.Name,
|
||||||
|
OrgType = user.SysOrg?.Type,
|
||||||
|
OrgLevel = user.SysOrg?.Level,
|
||||||
|
PosId = user.PosId,
|
||||||
|
PosName = user.SysPos?.Name,
|
||||||
|
PosCode = user.SysPos?.Code,
|
||||||
|
LoginMode = loginMode,
|
||||||
|
TokenVersion = user.TokenVersion,
|
||||||
|
OrgIds = orgIds,
|
||||||
|
PosIds = postIds,
|
||||||
|
RoleIds = roleIds,
|
||||||
|
Permissions = permissions,
|
||||||
|
UnauthorizedPermissions = unauthorizedPermissions,
|
||||||
|
AppPermissions = loginMode == LoginModeEnum.APP ? LazyHelper.GetService<SysCommonService>().GetAppApiList() : null,
|
||||||
|
MaxDataScope = user.AccountType == AccountTypeEnum.SuperAdmin ? DataScopeEnum.All : maxDataScope,
|
||||||
|
ExtProps = App.GetServices<IUserSessionExtProps>().SelectMany(u => u.GetInitExtProps(user)).ToDictionary(u => u.Key, u => u.Value)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前登陆用户信息 🔖
|
/// 获取当前登陆用户信息 🔖
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -313,8 +344,6 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
.LeftJoin<SysRole>((u, a) => u.RoleId == a.Id)
|
.LeftJoin<SysRole>((u, a) => u.RoleId == a.Id)
|
||||||
.Where(u => u.UserId == user.Id)
|
.Where(u => u.UserId == user.Id)
|
||||||
.Select((u, a) => new RoleDto { Id = a.Id, Name = a.Name, Code = a.Code }).ToListAsync();
|
.Select((u, a) => new RoleDto { Id = a.Id, Name = a.Name, Code = a.Code }).ToListAsync();
|
||||||
// 接口集合
|
|
||||||
var apis = (await App.GetRequiredService<SysRoleService>().GetUserApiList())[0];
|
|
||||||
// 个性化水印文字(若系统水印为空则不显示)
|
// 个性化水印文字(若系统水印为空则不显示)
|
||||||
var watermarkText = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().AsQueryable().Where(u => u.Id == user.TenantId).Select(u => u.Watermark).FirstAsync();
|
var watermarkText = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().AsQueryable().Where(u => u.Id == user.TenantId).Select(u => u.Watermark).FirstAsync();
|
||||||
if (!string.IsNullOrWhiteSpace(watermarkText))
|
if (!string.IsNullOrWhiteSpace(watermarkText))
|
||||||
@ -337,7 +366,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
OrgName = org?.Name,
|
OrgName = org?.Name,
|
||||||
OrgType = org?.Type,
|
OrgType = org?.Type,
|
||||||
PosName = pos?.Name,
|
PosName = pos?.Name,
|
||||||
Apis = apis,
|
Apis = _userManager.Permissions,
|
||||||
Roles = roles,
|
Roles = roles,
|
||||||
WatermarkText = watermarkText,
|
WatermarkText = watermarkText,
|
||||||
LastChangePasswordTime = user.LastChangePasswordTime
|
LastChangePasswordTime = user.LastChangePasswordTime
|
||||||
@ -447,13 +476,13 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 刷新token
|
/// 刷新Session
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId"></param>
|
/// <param name="userId"></param>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public async Task RefreshToken(long userId)
|
public async Task RefreshSession(long userId)
|
||||||
{
|
{
|
||||||
var user = await _sysUserRep.AsQueryable().IgnoreTenant().Includes(u => u.SysOrg).FirstAsync(u => u.Id == userId);
|
var user = await _sysUserRep.AsQueryable().IgnoreTenant().Includes(u => u.SysOrg).FirstAsync(u => u.Id == userId);
|
||||||
await CreateToken(user, CommonHelper.IsMobile(_httpContextAccessor.HttpContext?.Request.Headers.UserAgent ?? "") ? LoginModeEnum.APP : LoginModeEnum.PC, true);
|
await SetUserSession(user, CommonHelper.IsMobile(_httpContextAccessor.HttpContext?.Request.Headers.UserAgent ?? "") ? LoginModeEnum.APP : LoginModeEnum.PC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,7 +12,6 @@ namespace Admin.NET.Core.Service;
|
|||||||
[ApiDescriptionSettings(Order = 400, Description = "系统缓存")]
|
[ApiDescriptionSettings(Order = 400, Description = "系统缓存")]
|
||||||
public class SysCacheService : IDynamicApiController, ISingleton
|
public class SysCacheService : IDynamicApiController, ISingleton
|
||||||
{
|
{
|
||||||
private readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
private static ICacheProvider _cacheProvider;
|
private static ICacheProvider _cacheProvider;
|
||||||
private readonly CacheOptions _cacheOptions;
|
private readonly CacheOptions _cacheOptions;
|
||||||
|
|
||||||
@ -432,7 +431,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
|
|||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
// 超管用户操作,清空所有缓存
|
// 超管用户操作,清空所有缓存
|
||||||
if (_userManager.Value.SuperAdmin)
|
if (LazyHelper.GetService<UserManager>().SuperAdmin)
|
||||||
{
|
{
|
||||||
_cacheProvider.Cache.Clear();
|
_cacheProvider.Cache.Clear();
|
||||||
Cache.Default.Clear();
|
Cache.Default.Clear();
|
||||||
|
|||||||
@ -17,6 +17,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
|
|||||||
{
|
{
|
||||||
private readonly ISqlSugarClient _db;
|
private readonly ISqlSugarClient _db;
|
||||||
private readonly CodeGenOptions _codeGenOptions;
|
private readonly CodeGenOptions _codeGenOptions;
|
||||||
|
private readonly SysCacheService _sysCacheService;
|
||||||
private readonly DbConnectionOptions _dbConnectionOptions;
|
private readonly DbConnectionOptions _dbConnectionOptions;
|
||||||
private readonly SysCodeGenConfigService _codeGenConfigService;
|
private readonly SysCodeGenConfigService _codeGenConfigService;
|
||||||
private readonly IViewEngine _viewEngine;
|
private readonly IViewEngine _viewEngine;
|
||||||
@ -25,12 +26,14 @@ public class SysCodeGenService : IDynamicApiController, ITransient
|
|||||||
IOptions<CodeGenOptions> codeGenOptions,
|
IOptions<CodeGenOptions> codeGenOptions,
|
||||||
IOptions<DbConnectionOptions> dbConnectionOptions,
|
IOptions<DbConnectionOptions> dbConnectionOptions,
|
||||||
SysCodeGenConfigService codeGenConfigService,
|
SysCodeGenConfigService codeGenConfigService,
|
||||||
|
SysCacheService sysCacheService,
|
||||||
IViewEngine viewEngine)
|
IViewEngine viewEngine)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_dbConnectionOptions = dbConnectionOptions.Value;
|
_dbConnectionOptions = dbConnectionOptions.Value;
|
||||||
_codeGenOptions = codeGenOptions.Value;
|
_codeGenOptions = codeGenOptions.Value;
|
||||||
_codeGenConfigService = codeGenConfigService;
|
_codeGenConfigService = codeGenConfigService;
|
||||||
|
_sysCacheService = sysCacheService;
|
||||||
_viewEngine = viewEngine;
|
_viewEngine = viewEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +603,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
|
|||||||
await _db.Insertable(menus).ExecuteCommandAsync();
|
await _db.Insertable(menus).ExecuteCommandAsync();
|
||||||
|
|
||||||
// 删除角色菜单按钮缓存
|
// 删除角色菜单按钮缓存
|
||||||
App.GetRequiredService<SysCacheService>().RemoveByPrefixKey(CacheConst.KeyUserApi);
|
_sysCacheService.RemoveByPrefixKey(CacheConst.KeyUserSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -172,17 +172,14 @@ public class SysCommonService : IDynamicApiController, ITransient
|
|||||||
[DisplayName("获取所有移动端接口")]
|
[DisplayName("获取所有移动端接口")]
|
||||||
public List<string> GetAppApiList()
|
public List<string> GetAppApiList()
|
||||||
{
|
{
|
||||||
var apiList = _sysCacheService.Get<List<string>>(CacheConst.KeyAppApi);
|
List<string> apiList = [];
|
||||||
if (apiList == null)
|
var queue = new Queue<ApiOutput>(GetApiList());
|
||||||
|
var item = queue.Dequeue();
|
||||||
|
while (item != null)
|
||||||
{
|
{
|
||||||
apiList = [];
|
if (item.Children is { Count: > 0 }) queue.EnqueueRange(item.Children);
|
||||||
var allApiList = GetApiList("", true);
|
else apiList.Add(item.Route);
|
||||||
foreach (var apiOutput in allApiList)
|
item = queue.Count > 0 ? queue.Dequeue() : null;
|
||||||
{
|
|
||||||
foreach (var controller in apiOutput.Children)
|
|
||||||
apiList.AddRange(controller.Children.Select(u => u.Route));
|
|
||||||
}
|
|
||||||
_sysCacheService.Set(CacheConst.KeyAppApi, apiList, TimeSpan.FromDays(7));
|
|
||||||
}
|
}
|
||||||
return apiList;
|
return apiList;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -395,56 +395,67 @@ public class SysRoleService : IDynamicApiController, ITransient
|
|||||||
//return roleApis.Union(roleButtons).ToList();
|
//return roleApis.Union(roleButtons).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户接口集合 🔖
|
/// 获取用户接口集合
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[DisplayName("获取用户接口集合")]
|
[NonAction]
|
||||||
public async Task<List<List<string>>> GetUserApiList()
|
public async Task<List<string>> GetUserApiList(long userId)
|
||||||
{
|
{
|
||||||
var userId = _userManager.UserId;
|
List<string> apiList = [];
|
||||||
var apiList = _sysCacheService.Get<List<List<string>>>(CacheConst.KeyUserApi + userId);
|
|
||||||
if (apiList != null) return apiList;
|
|
||||||
|
|
||||||
apiList = [[], []];
|
|
||||||
// 所有按钮权限集合
|
|
||||||
var allButtonList = await GetButtonList();
|
|
||||||
// 超管账号获取所有接口
|
// 超管账号获取所有接口
|
||||||
if (_userManager.SuperAdmin)
|
if (await _sysRoleRep.Context.Queryable<SysUser>().IgnoreTenant().AnyAsync(u => u.Id == userId && u.AccountType == AccountTypeEnum.SuperAdmin))
|
||||||
{
|
{
|
||||||
var allApiList = _sysCommonService.GetApiList();
|
// 获取所有接口
|
||||||
foreach (var apiOutput in allApiList)
|
var queue = new Queue<ApiOutput>(_sysCommonService.GetApiList());
|
||||||
|
var item = queue.Dequeue();
|
||||||
|
while (item != null)
|
||||||
{
|
{
|
||||||
foreach (var controller in apiOutput.Children)
|
if (item.Children is { Count: > 0 }) queue.EnqueueRange(item.Children);
|
||||||
apiList[0].AddRange(controller.Children.Select(u => u.Route));
|
else apiList.Add(item.Route);
|
||||||
|
item = queue.Count > 0 ? queue.Dequeue() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 接口没有对应的按钮权限集合
|
|
||||||
var diffButtonList = allButtonList.Except(apiList[0]).ToList(); // 差集
|
|
||||||
apiList[0].AddRange(diffButtonList);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 当前账号所有角色集合
|
// 获取账号所有权限集
|
||||||
var roleIdList = await _sysUserRoleService.GetUserRoleIdList(_userManager.UserId);
|
var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(await _sysUserRoleService.GetUserRoleIdList(userId));
|
||||||
// 已有按钮权限集合
|
apiList = await GetButtonList(menuIdList, false);
|
||||||
var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIdList);
|
|
||||||
apiList[0] = await GetButtonList(menuIdList, false);
|
|
||||||
|
|
||||||
// 未有按钮权限集合(放到接口黑名单里面)
|
|
||||||
apiList[1] = allButtonList.Except(apiList[0]).ToList(); // 差集
|
|
||||||
// 接口黑名单集合
|
|
||||||
var roleApiList = await _sysRoleApiService.GetRoleApiList(roleIdList);
|
|
||||||
apiList[1].AddRange(roleApiList);
|
|
||||||
}
|
}
|
||||||
|
apiList = apiList.Distinct().ToList();
|
||||||
// 排序接口名称
|
apiList.Sort();
|
||||||
apiList[0].Sort();
|
|
||||||
apiList[1].Sort();
|
|
||||||
_sysCacheService.Set(CacheConst.KeyUserApi + userId, apiList, TimeSpan.FromDays(7)); // 缓存7天
|
|
||||||
return apiList;
|
return apiList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取无权访问接口集合 🔖
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public async Task<List<string>> GetUnAuthApiList(long userId)
|
||||||
|
{
|
||||||
|
if (await _sysRoleRep.Context.Queryable<SysUser>().IgnoreTenant().AnyAsync(u => u.Id == userId && u.AccountType == AccountTypeEnum.SuperAdmin)) return [];
|
||||||
|
|
||||||
|
// 所有按钮权限集合
|
||||||
|
var allButtonList = await GetButtonList();
|
||||||
|
|
||||||
|
// 当前账号所有角色集合
|
||||||
|
var roleIds = await _sysUserRoleService.GetUserRoleIdList(userId);
|
||||||
|
|
||||||
|
// 菜单中已有的权限集与当前用户的权限集差集,就是无权访问的权限集
|
||||||
|
var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIds);
|
||||||
|
var apiList = await GetButtonList(menuIdList, false);
|
||||||
|
var blackList = allButtonList.Except(apiList).ToList(); // 差集
|
||||||
|
|
||||||
|
// 角色接口黑名单集合
|
||||||
|
blackList.AddRange(await _sysRoleApiService.GetRoleApiList(roleIds));
|
||||||
|
blackList = blackList.Distinct().ToList();
|
||||||
|
|
||||||
|
blackList.Sort();
|
||||||
|
return blackList;
|
||||||
|
}
|
||||||
|
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// 获取用户按钮权限集合
|
///// 获取用户按钮权限集合
|
||||||
///// </summary>
|
///// </summary>
|
||||||
@ -485,7 +496,8 @@ public class SysRoleService : IDynamicApiController, ITransient
|
|||||||
.WhereIF(menuIds != null && menuIds.Count > 0, u => menuIds.Contains(u.Id))
|
.WhereIF(menuIds != null && menuIds.Count > 0, u => menuIds.Contains(u.Id))
|
||||||
.WhereIF(!isAll, u => u.Status == StatusEnum.Enable)
|
.WhereIF(!isAll, u => u.Status == StatusEnum.Enable)
|
||||||
.Where(u => u.Type == MenuTypeEnum.Btn)
|
.Where(u => u.Type == MenuTypeEnum.Btn)
|
||||||
.Select(u => u.Permission).ToListAsync();
|
.Select(u => u.Permission)
|
||||||
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -497,9 +509,6 @@ public class SysRoleService : IDynamicApiController, ITransient
|
|||||||
public async Task ClearUserApiCache(long roleId)
|
public async Task ClearUserApiCache(long roleId)
|
||||||
{
|
{
|
||||||
var userIdList = await _sysUserRoleService.GetUserIdList(roleId);
|
var userIdList = await _sysUserRoleService.GetUserIdList(roleId);
|
||||||
foreach (var userId in userIdList)
|
foreach (var userId in userIdList) _sysCacheService.Remove(CacheConst.KeyUserSession + userId);
|
||||||
{
|
|
||||||
_sysCacheService.Remove(CacheConst.KeyUserApi + userId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ public class SysUserRoleService : ITransient
|
|||||||
await _sysUserRoleRep.InsertRangeAsync(userRoles);
|
await _sysUserRoleRep.InsertRangeAsync(userRoles);
|
||||||
|
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
_sysCacheService.Remove(CacheConst.KeyUserApi + input.UserId);
|
_sysCacheService.Remove(CacheConst.KeyUserSession + input.UserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -61,7 +61,7 @@ public class SysUserRoleService : ITransient
|
|||||||
// 清除缓存
|
// 清除缓存
|
||||||
foreach (var userId in input.UserIdList)
|
foreach (var userId in input.UserIdList)
|
||||||
{
|
{
|
||||||
_sysCacheService.Remove(CacheConst.KeyUserApi + userId);
|
_sysCacheService.Remove(CacheConst.KeyUserSession + userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ public class SysUserRoleService : ITransient
|
|||||||
// 清除缓存
|
// 清除缓存
|
||||||
foreach (var userId in userIdList)
|
foreach (var userId in userIdList)
|
||||||
{
|
{
|
||||||
_sysCacheService.Remove(CacheConst.KeyUserApi + userId);
|
_sysCacheService.Remove(CacheConst.KeyUserSession + userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _sysUserRoleRep.DeleteAsync(u => u.RoleId == roleId);
|
await _sysUserRoleRep.DeleteAsync(u => u.RoleId == roleId);
|
||||||
@ -96,7 +96,7 @@ public class SysUserRoleService : ITransient
|
|||||||
await _sysUserRoleRep.DeleteAsync(u => u.UserId == userId);
|
await _sysUserRoleRep.DeleteAsync(u => u.UserId == userId);
|
||||||
|
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
_sysCacheService.Remove(CacheConst.KeyUserApi + userId);
|
_sysCacheService.Remove(CacheConst.KeyUserSession + userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -43,6 +43,13 @@ public class UserManager(
|
|||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
public override long UserId => (httpContextAccessor.HttpContext?.User.FindFirst(nameof(UserId))?.Value).ToLong();
|
public override long UserId => (httpContextAccessor.HttpContext?.User.FindFirst(nameof(UserId))?.Value).ToLong();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Token版本号
|
||||||
|
/// </summary>
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
public override int TokenVersion => (httpContextAccessor.HttpContext?.User.FindFirst(nameof(UserId))?.Value).ToInt();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用Id
|
/// 应用Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -88,6 +95,21 @@ public class UserManager(
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public override string OrgType => Session?.OrgType;
|
public override string OrgType => Session?.OrgType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位Id
|
||||||
|
/// </summary>
|
||||||
|
public override long? PosId => Session?.PosId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位名称
|
||||||
|
/// </summary>
|
||||||
|
public override string PosName => Session?.PosName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位编码
|
||||||
|
/// </summary>
|
||||||
|
public override string PosCode => Session?.PosCode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 组织机构级别
|
/// 组织机构级别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -103,6 +125,41 @@ public class UserManager(
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public override string OpenId => Session?.OpenId;
|
public override string OpenId => Session?.OpenId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大数据范围权限
|
||||||
|
/// </summary>
|
||||||
|
public override DataScopeEnum? MaxDataScope => Session?.MaxDataScope;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色Id集
|
||||||
|
/// </summary>
|
||||||
|
public override List<long> RoleIds => Session?.RoleIds;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机构Id集
|
||||||
|
/// </summary>
|
||||||
|
public override List<long> OrgIds => Session?.OrgIds;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位Id集
|
||||||
|
/// </summary>
|
||||||
|
public override List<long> PosIds => Session?.PosIds;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 权限集
|
||||||
|
/// </summary>
|
||||||
|
public override List<string> Permissions => Session?.Permissions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// App权限集
|
||||||
|
/// </summary>
|
||||||
|
public override List<string> AppPermissions => Session?.AppPermissions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 无权权限集
|
||||||
|
/// </summary>
|
||||||
|
public override List<string> UnauthorizedPermissions => Session?.UnauthorizedPermissions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展属性
|
/// 扩展属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -119,9 +176,9 @@ public class UserManager(
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置用户Session
|
/// 设置用户Session
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetSession(UserSessionDao userSession, TimeSpan expire)
|
public void SetSession(UserSessionDao userSession)
|
||||||
{
|
{
|
||||||
sysCacheService.Set(CacheConst.KeyUserSession + userSession.UserId, userSession, expire);
|
sysCacheService.Set(CacheConst.KeyUserSession + userSession.UserId, userSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -140,6 +197,25 @@ public class UserManager(
|
|||||||
return sysCacheService.Get<UserSessionDao>(CacheConst.KeyUserSession + userId);
|
return sysCacheService.Get<UserSessionDao>(CacheConst.KeyUserSession + userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定用户Session,如果不存在则刷新
|
||||||
|
/// </summary>
|
||||||
|
public UserSessionDao GetSessionOrRefresh(dynamic userId = null)
|
||||||
|
{
|
||||||
|
userId ??= UserId;
|
||||||
|
var session = sysCacheService.Get<UserSessionDao>(CacheConst.KeyUserSession + userId);
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
if ((Nullable.GetUnderlyingType(userId.GetType()) ?? userId.GetType()) != typeof(long))
|
||||||
|
{
|
||||||
|
if (long.TryParse(userId.ToString(), out long tempId)) userId = tempId;
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
LazyHelper.GetService<SysAuthService>().RefreshSession(userId).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
return sysCacheService.Get<UserSessionDao>(CacheConst.KeyUserSession + userId);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取扩展属性
|
/// 获取扩展属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -9,13 +9,20 @@ namespace Admin.NET.Core;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户会话信息
|
/// 用户会话信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class UserSessionDao
|
public class UserSessionDao
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户Id
|
/// 用户Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual long UserId { get; set; }
|
public virtual long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// token版本
|
||||||
|
/// </summary>
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
public virtual int TokenVersion { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 平台应用Id
|
/// 平台应用Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -60,6 +67,11 @@ public partial class UserSessionDao
|
|||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
public bool SysAdmin => AccountType == AccountTypeEnum.SysAdmin;
|
public bool SysAdmin => AccountType == AccountTypeEnum.SysAdmin;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大数据范围权限
|
||||||
|
/// </summary>
|
||||||
|
public virtual DataScopeEnum? MaxDataScope { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 组织机构Id
|
/// 组织机构Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -85,6 +97,51 @@ public partial class UserSessionDao
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual int? OrgLevel { get; set; }
|
public virtual int? OrgLevel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位Id
|
||||||
|
/// </summary>
|
||||||
|
public virtual long? PosId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位名称
|
||||||
|
/// </summary>
|
||||||
|
public virtual string PosName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位编码
|
||||||
|
/// </summary>
|
||||||
|
public virtual string PosCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色Id集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<long> RoleIds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机构Id集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<long> OrgIds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位Id集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<long> PosIds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动端权限集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<string> AppPermissions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 权限集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<string> Permissions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 无权-权限集
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<string> UnauthorizedPermissions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录模式
|
/// 登录模式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -95,11 +152,6 @@ public partial class UserSessionDao
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string OpenId { get; set; }
|
public virtual string OpenId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// token版本
|
|
||||||
/// </summary>
|
|
||||||
public virtual long TokenVersion { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展属性
|
/// 扩展属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -522,11 +522,6 @@ public static class SqlSugarExtension
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly ConcurrentDictionary<Type, Dictionary<string, (PropertyInfo Prop, BindTextAbbrAttribute Attr)>?> _textAbbrPropCache = new();
|
private static readonly ConcurrentDictionary<Type, Dictionary<string, (PropertyInfo Prop, BindTextAbbrAttribute Attr)>?> _textAbbrPropCache = new();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统通用服务
|
|
||||||
/// </summary>
|
|
||||||
private static readonly Lazy<SysCommonService> _lazySysCommonService = new(() => App.GetService<SysCommonService>());
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化文本简称数据
|
/// 初始化文本简称数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -588,7 +583,7 @@ public static class SqlSugarExtension
|
|||||||
if (string.IsNullOrWhiteSpace(value)) return;
|
if (string.IsNullOrWhiteSpace(value)) return;
|
||||||
|
|
||||||
// 使用线程安全的延迟初始化服务实例获取文本缩写
|
// 使用线程安全的延迟初始化服务实例获取文本缩写
|
||||||
var abbrValue = _lazySysCommonService.Value
|
var abbrValue = LazyHelper.GetService<SysCommonService>()
|
||||||
.GetNameAbbr(new() { Text = value, All = attribute.SaveFullAbbr })
|
.GetNameAbbr(new() { Text = value, All = attribute.SaveFullAbbr })
|
||||||
.GetAwaiter()
|
.GetAwaiter()
|
||||||
.GetResult();
|
.GetResult();
|
||||||
@ -604,11 +599,6 @@ public static class SqlSugarExtension
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly ConcurrentDictionary<Type, Dictionary<string, (PropertyInfo Prop, BindSerialAttribute Attr)>?> _serialPropCache = new();
|
private static readonly ConcurrentDictionary<Type, Dictionary<string, (PropertyInfo Prop, BindSerialAttribute Attr)>?> _serialPropCache = new();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统通用服务
|
|
||||||
/// </summary>
|
|
||||||
private static readonly Lazy<SysSerialService> _lazySysSerialService = new(() => App.GetService<SysSerialService>());
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自动生成流水号到绑定字段
|
/// 自动生成流水号到绑定字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -643,7 +633,7 @@ public static class SqlSugarExtension
|
|||||||
var (_, attribute) = propData;
|
var (_, attribute) = propData;
|
||||||
|
|
||||||
// 使用线程安全的延迟初始化服务实例获取流水号
|
// 使用线程安全的延迟初始化服务实例获取流水号
|
||||||
var serial = _lazySysSerialService.Value
|
var serial = LazyHelper.GetService<SysSerialService>()
|
||||||
.NextSeqNo(attribute.Type, attribute.IsGlobal)
|
.NextSeqNo(attribute.Type, attribute.IsGlobal)
|
||||||
.GetAwaiter()
|
.GetAwaiter()
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|||||||
@ -28,6 +28,10 @@ public static class SqlSugarFilter
|
|||||||
sysCacheService.Remove($"{CacheConst.KeyRoleMaxDataScope}{userId}");
|
sysCacheService.Remove($"{CacheConst.KeyRoleMaxDataScope}{userId}");
|
||||||
// 用户权限缓存(接口集合)
|
// 用户权限缓存(接口集合)
|
||||||
sysCacheService.Remove($"{CacheConst.KeyUserApi}{userId}");
|
sysCacheService.Remove($"{CacheConst.KeyUserApi}{userId}");
|
||||||
|
|
||||||
|
// 清除用户session
|
||||||
|
sysCacheService.Remove($"{CacheConst.KeyUserSession}{userId}");
|
||||||
|
|
||||||
// 删除用户机构(数据范围)缓存——过滤器
|
// 删除用户机构(数据范围)缓存——过滤器
|
||||||
_cache.Remove($"db:{dbConfigId}:orgList:{userId}");
|
_cache.Remove($"db:{dbConfigId}:orgList:{userId}");
|
||||||
}
|
}
|
||||||
@ -54,6 +58,10 @@ public static class SqlSugarFilter
|
|||||||
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
||||||
if (string.IsNullOrWhiteSpace(userId)) return;
|
if (string.IsNullOrWhiteSpace(userId)) return;
|
||||||
|
|
||||||
|
// 获取用户session
|
||||||
|
var session = LazyHelper.GetService<UserManager>().GetSessionOrRefresh(userId);
|
||||||
|
if (session == null) return;
|
||||||
|
|
||||||
// 配置用户机构集合缓存
|
// 配置用户机构集合缓存
|
||||||
var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:orgList:{userId}";
|
var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:orgList:{userId}";
|
||||||
var orgFilter = _cache.Get<ConcurrentDictionary<Type, LambdaExpression>>(cacheKey);
|
var orgFilter = _cache.Get<ConcurrentDictionary<Type, LambdaExpression>>(cacheKey);
|
||||||
@ -63,12 +71,7 @@ public static class SqlSugarFilter
|
|||||||
if (maxDataScope == (int)DataScopeEnum.All) return;
|
if (maxDataScope == (int)DataScopeEnum.All) return;
|
||||||
|
|
||||||
// 获取用户所属机构,保证同一作用域
|
// 获取用户所属机构,保证同一作用域
|
||||||
var orgIds = new List<long>();
|
var orgIds = session.OrgIds;
|
||||||
Scoped.Create((factory, scope) =>
|
|
||||||
{
|
|
||||||
var services = scope.ServiceProvider;
|
|
||||||
orgIds = services.GetRequiredService<SysOrgService>().GetUserOrgIdList().GetAwaiter().GetResult();
|
|
||||||
});
|
|
||||||
if (orgIds == null || orgIds.Count == 0) return;
|
if (orgIds == null || orgIds.Count == 0) return;
|
||||||
|
|
||||||
// 获取业务实体数据表
|
// 获取业务实体数据表
|
||||||
@ -109,19 +112,12 @@ public static class SqlSugarFilter
|
|||||||
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
||||||
if (string.IsNullOrWhiteSpace(userId)) return maxDataScope;
|
if (string.IsNullOrWhiteSpace(userId)) return maxDataScope;
|
||||||
|
|
||||||
|
// 获取用户session
|
||||||
|
var session = LazyHelper.GetService<UserManager>().GetSessionOrRefresh(userId);
|
||||||
|
if (session == null) return (int)DataScopeEnum.Self;
|
||||||
|
|
||||||
// 获取用户最大数据范围---仅本人数据
|
// 获取用户最大数据范围---仅本人数据
|
||||||
maxDataScope = App.GetRequiredService<SysCacheService>().Get<int>(CacheConst.KeyRoleMaxDataScope + userId);
|
maxDataScope = (int)session.MaxDataScope!;
|
||||||
// 若为0则获取用户机构组织集合建立缓存
|
|
||||||
if (maxDataScope == 0)
|
|
||||||
{
|
|
||||||
// 获取用户所属机构,保证同一作用域
|
|
||||||
Scoped.Create((factory, scope) =>
|
|
||||||
{
|
|
||||||
var services = scope.ServiceProvider;
|
|
||||||
services.GetRequiredService<SysOrgService>().GetUserOrgIdList().GetAwaiter().GetResult();
|
|
||||||
maxDataScope = services.GetRequiredService<SysCacheService>().Get<int>(CacheConst.KeyRoleMaxDataScope + userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (maxDataScope != (int)DataScopeEnum.Self) return maxDataScope;
|
if (maxDataScope != (int)DataScopeEnum.Self) return maxDataScope;
|
||||||
|
|
||||||
// 配置用户数据范围缓存
|
// 配置用户数据范围缓存
|
||||||
@ -130,8 +126,7 @@ public static class SqlSugarFilter
|
|||||||
if (dataScopeFilter == null)
|
if (dataScopeFilter == null)
|
||||||
{
|
{
|
||||||
// 获取业务实体数据表
|
// 获取业务实体数据表
|
||||||
var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
|
var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsSubclassOf(typeof(EntityBaseData))).ToList();
|
||||||
&& u.IsSubclassOf(typeof(EntityBaseData)));
|
|
||||||
if (!entityTypes.Any()) return maxDataScope;
|
if (!entityTypes.Any()) return maxDataScope;
|
||||||
|
|
||||||
dataScopeFilter = new ConcurrentDictionary<Type, LambdaExpression>();
|
dataScopeFilter = new ConcurrentDictionary<Type, LambdaExpression>();
|
||||||
@ -139,8 +134,7 @@ public static class SqlSugarFilter
|
|||||||
{
|
{
|
||||||
// 排除非当前数据库实体
|
// 排除非当前数据库实体
|
||||||
var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
|
var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
|
||||||
if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()))
|
if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString())) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
//var lambda = DynamicExpressionParser.ParseLambda(new[] {
|
//var lambda = DynamicExpressionParser.ParseLambda(new[] {
|
||||||
// Expression.Parameter(entityType, "u") }, typeof(bool), $"u.{nameof(EntityBaseData.CreateUserId)}=@0", userId);
|
// Expression.Parameter(entityType, "u") }, typeof(bool), $"u.{nameof(EntityBaseData.CreateUserId)}=@0", userId);
|
||||||
@ -172,7 +166,8 @@ public static class SqlSugarFilter
|
|||||||
{
|
{
|
||||||
// 获取自定义实体过滤器
|
// 获取自定义实体过滤器
|
||||||
var entityFilterTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
|
var entityFilterTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
|
||||||
&& u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(IEntityFilter))));
|
&& u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(IEntityFilter))))
|
||||||
|
.ToList();
|
||||||
if (!entityFilterTypes.Any()) return;
|
if (!entityFilterTypes.Any()) return;
|
||||||
|
|
||||||
var tableFilterItems = new List<TableFilterItem<object>>();
|
var tableFilterItems = new List<TableFilterItem<object>>();
|
||||||
@ -186,9 +181,9 @@ public static class SqlSugarFilter
|
|||||||
foreach (var u in entityFilters)
|
foreach (var u in entityFilters)
|
||||||
{
|
{
|
||||||
var tableFilterItem = (TableFilterItem<object>)u;
|
var tableFilterItem = (TableFilterItem<object>)u;
|
||||||
var entityType = tableFilterItem.GetType().GetProperty("type", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tableFilterItem, null) as Type;
|
var entityType = tableFilterItem.GetType().GetProperty("type", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(tableFilterItem, null) as Type;
|
||||||
// 排除非当前数据库实体
|
// 排除非当前数据库实体
|
||||||
var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
|
var tAtt = entityType?.GetCustomAttribute<TenantAttribute>();
|
||||||
if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()) ||
|
if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()) ||
|
||||||
(tAtt == null && db.CurrentConnectionConfig.ConfigId.ToString() != SqlSugarConst.MainConfigId))
|
(tAtt == null && db.CurrentConnectionConfig.ConfigId.ToString() != SqlSugarConst.MainConfigId))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -12,8 +12,6 @@ namespace Admin.NET.Core;
|
|||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> where T : class, new()
|
public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> where T : class, new()
|
||||||
{
|
{
|
||||||
private static readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
|
|
||||||
public SqlSugarRepository()
|
public SqlSugarRepository()
|
||||||
{
|
{
|
||||||
var iTenant = SqlSugarSetup.ITenant;
|
var iTenant = SqlSugarSetup.ITenant;
|
||||||
@ -39,7 +37,7 @@ public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> whe
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// 若未贴任何表特性或当前未登录或是默认租户Id,则返回默认库连接
|
// 若未贴任何表特性或当前未登录或是默认租户Id,则返回默认库连接
|
||||||
var tenantId = _userManager.Value.TenantId?.ToString();
|
var tenantId = LazyHelper.GetService<UserManager>().TenantId?.ToString();
|
||||||
if (string.IsNullOrWhiteSpace(tenantId) || tenantId == SqlSugarConst.MainConfigId) return;
|
if (string.IsNullOrWhiteSpace(tenantId) || tenantId == SqlSugarConst.MainConfigId) return;
|
||||||
|
|
||||||
// 根据租户Id切换库连接, 为空则返回默认库连接
|
// 根据租户Id切换库连接, 为空则返回默认库连接
|
||||||
|
|||||||
@ -215,8 +215,8 @@ public static class SqlSugarSetup
|
|||||||
Log.Warning(log);
|
Log.Warning(log);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var userManager = LazyHelper.GetService<UserManager>();
|
||||||
// 数据审计
|
// 数据审计
|
||||||
Lazy<UserManager> userManager = new(() => App.GetService<UserManager>());
|
|
||||||
dbProvider.Aop.DataExecuting = (oldValue, entityInfo) =>
|
dbProvider.Aop.DataExecuting = (oldValue, entityInfo) =>
|
||||||
{
|
{
|
||||||
// 新增/插入 操作
|
// 新增/插入 操作
|
||||||
@ -249,7 +249,7 @@ public static class SqlSugarSetup
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 若当前用户非空(web线程时)
|
// 若当前用户非空(web线程时)
|
||||||
if (App.User == null || userManager.Value == null) return;
|
if (App.User == null) return;
|
||||||
|
|
||||||
dynamic entityValue = entityInfo.EntityValue;
|
dynamic entityValue = entityInfo.EntityValue;
|
||||||
// 若应用Id为空则赋值当前用户应用Id,若当前用户应用Id为空,则取默认应用Id
|
// 若应用Id为空则赋值当前用户应用Id,若当前用户应用Id为空,则取默认应用Id
|
||||||
@ -257,33 +257,33 @@ public static class SqlSugarSetup
|
|||||||
{
|
{
|
||||||
var appId = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue)!;
|
var appId = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue)!;
|
||||||
if (appId == null || appId.Equals(0))
|
if (appId == null || appId.Equals(0))
|
||||||
entityInfo.SetValue(userManager.Value?.AppId ?? SqlSugarConst.DefaultAppId);
|
entityInfo.SetValue(userManager.AppId ?? SqlSugarConst.DefaultAppId);
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName == nameof(EntityTenantId.TenantId))
|
else if (entityInfo.PropertyName == nameof(EntityTenantId.TenantId))
|
||||||
{
|
{
|
||||||
if (entityValue.TenantId == null || entityValue.TenantId == 0)
|
if (entityValue.TenantId == null || entityValue.TenantId == 0)
|
||||||
entityInfo.SetValue(userManager.Value.TenantId?.ToString() ??
|
entityInfo.SetValue(userManager.TenantId?.ToString() ??
|
||||||
SqlSugarConst.DefaultTenantId.ToString());
|
SqlSugarConst.DefaultTenantId.ToString());
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserId))
|
else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserId))
|
||||||
{
|
{
|
||||||
if (entityValue.CreateUserId == null || entityValue.CreateUserId == 0)
|
if (entityValue.CreateUserId == null || entityValue.CreateUserId == 0)
|
||||||
entityInfo.SetValue(userManager.Value.UserId);
|
entityInfo.SetValue(userManager.UserId);
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserName))
|
else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserName))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(entityValue.CreateUserName))
|
if (string.IsNullOrWhiteSpace(entityValue.CreateUserName))
|
||||||
entityInfo.SetValue(userManager.Value.RealName);
|
entityInfo.SetValue(userManager.RealName);
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgId))
|
else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgId))
|
||||||
{
|
{
|
||||||
if (entityValue.CreateOrgId == null || entityValue.CreateOrgId == 0)
|
if (entityValue.CreateOrgId == null || entityValue.CreateOrgId == 0)
|
||||||
entityInfo.SetValue(userManager.Value.OrgId);
|
entityInfo.SetValue(userManager.OrgId);
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgName))
|
else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgName))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(entityValue.CreateOrgName))
|
if (string.IsNullOrWhiteSpace(entityValue.CreateOrgName))
|
||||||
entityInfo.SetValue(userManager.Value.OrgName);
|
entityInfo.SetValue(userManager.OrgName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 编辑/更新 操作
|
// 编辑/更新 操作
|
||||||
@ -294,7 +294,7 @@ public static class SqlSugarSetup
|
|||||||
else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserId))
|
else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserId))
|
||||||
entityInfo.SetValue(App.User?.FindFirst(ClaimConst.UserId)?.Value);
|
entityInfo.SetValue(App.User?.FindFirst(ClaimConst.UserId)?.Value);
|
||||||
else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserName))
|
else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserName))
|
||||||
entityInfo.SetValue(userManager.Value.RealName);
|
entityInfo.SetValue(userManager.RealName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置绑定简称字段数据
|
// 设置绑定简称字段数据
|
||||||
@ -308,13 +308,13 @@ public static class SqlSugarSetup
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 超管不受任何过滤器限制
|
// 超管不受任何过滤器限制
|
||||||
if (userManager.Value.AccountType == AccountTypeEnum.SuperAdmin) return;
|
if (userManager.AccountType == AccountTypeEnum.SuperAdmin) return;
|
||||||
|
|
||||||
// 配置假删除过滤器
|
// 配置假删除过滤器
|
||||||
dbProvider.QueryFilter.AddTableFilter<IDeletedFilter>(u => u.IsDelete == false);
|
dbProvider.QueryFilter.AddTableFilter<IDeletedFilter>(u => u.IsDelete == false);
|
||||||
|
|
||||||
// 配置租户过滤器
|
// 配置租户过滤器
|
||||||
var tenantId = userManager.Value.TenantId?.ToString();
|
var tenantId = userManager.TenantId?.ToString();
|
||||||
if (!string.IsNullOrWhiteSpace(tenantId))
|
if (!string.IsNullOrWhiteSpace(tenantId))
|
||||||
dbProvider.QueryFilter.AddTableFilter<ITenantIdFilter>(u => u.TenantId == long.Parse(tenantId));
|
dbProvider.QueryFilter.AddTableFilter<ITenantIdFilter>(u => u.TenantId == long.Parse(tenantId));
|
||||||
|
|
||||||
|
|||||||
23
Admin.NET/Admin.NET.Core/Utils/LazyHelper.cs
Normal file
23
Admin.NET/Admin.NET.Core/Utils/LazyHelper.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||||
|
//
|
||||||
|
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||||
|
//
|
||||||
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
|
public class LazyHelper
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Type, Lazy<object>> _cache = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取服务
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetService<T>() where T : class
|
||||||
|
{
|
||||||
|
if (_cache.TryGetValue(typeof(T), out var lazy)) return (T)lazy.Value;
|
||||||
|
return (T)(_cache[typeof(T)] = new Lazy<object>(() => App.GetService<T>())).Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,7 +23,6 @@ namespace Admin.NET.Web.Core
|
|||||||
public class JwtHandler : AppAuthorizeHandler
|
public class JwtHandler : AppAuthorizeHandler
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private static readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
|
|
||||||
public JwtHandler(IServiceProvider serviceProvider)
|
public JwtHandler(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
@ -74,7 +73,7 @@ namespace Admin.NET.Web.Core
|
|||||||
if (sysCacheService.NotExistKey($"{CacheConst.KeyUserSession}{userId}"))
|
if (sysCacheService.NotExistKey($"{CacheConst.KeyUserSession}{userId}"))
|
||||||
{
|
{
|
||||||
var sysAuthService = serviceScope.ServiceProvider.GetRequiredService<SysAuthService>();
|
var sysAuthService = serviceScope.ServiceProvider.GetRequiredService<SysAuthService>();
|
||||||
await sysAuthService.RefreshToken(long.Parse(userId!));
|
await sysAuthService.RefreshSession(long.Parse(userId!));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +92,7 @@ namespace Admin.NET.Web.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证租户有效期
|
// 验证租户有效期
|
||||||
var tenantId = _userManager.Value.TenantId?.ToString();
|
var tenantId = LazyHelper.GetService<UserManager>().TenantId?.ToString();
|
||||||
if (!string.IsNullOrWhiteSpace(tenantId))
|
if (!string.IsNullOrWhiteSpace(tenantId))
|
||||||
{
|
{
|
||||||
var tenant = sysCacheService.Get<List<SysTenant>>(CacheConst.KeyTenant)?.FirstOrDefault(u => u.Id == long.Parse(tenantId));
|
var tenant = sysCacheService.Get<List<SysTenant>>(CacheConst.KeyTenant)?.FirstOrDefault(u => u.Id == long.Parse(tenantId));
|
||||||
@ -119,32 +118,31 @@ namespace Admin.NET.Web.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static async Task<bool> CheckAuthorizeAsync(DefaultHttpContext httpContext)
|
private static async Task<bool> CheckAuthorizeAsync(DefaultHttpContext httpContext)
|
||||||
{
|
{
|
||||||
// 排除超管权限判断
|
var userManager = LazyHelper.GetService<UserManager>();
|
||||||
if (_userManager.Value?.AccountType == AccountTypeEnum.SuperAdmin)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var serviceScope = httpContext.RequestServices.CreateScope();
|
// 排除超管权限判断
|
||||||
|
if (userManager?.AccountType == AccountTypeEnum.SuperAdmin) return true;
|
||||||
|
|
||||||
// 当前接口路由
|
// 当前接口路由
|
||||||
var path = httpContext.Request.Path.ToString();
|
var path = httpContext.Request.Path.ToString();
|
||||||
|
|
||||||
// 移动端接口权限判断
|
// 移动端接口权限判断
|
||||||
if (_userManager.Value?.LoginMode == LoginModeEnum.APP)
|
if (userManager?.LoginMode == LoginModeEnum.APP)
|
||||||
{
|
{
|
||||||
var appApiList = serviceScope.ServiceProvider.GetRequiredService<SysCommonService>().GetAppApiList();
|
var appPermissions = userManager.AppPermissions ?? [];
|
||||||
return appApiList.Exists(u => path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase));
|
return appPermissions.Exists(u => path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前用户按钮权限集合和接口黑名单
|
// 获取当前用户按钮权限集合和接口黑名单
|
||||||
var sysRoleService = serviceScope.ServiceProvider.GetRequiredService<SysRoleService>();
|
var unauthorizedPermissions = userManager?.UnauthorizedPermissions ?? [];
|
||||||
var roleApis = await sysRoleService.GetUserApiList();
|
var permissions = userManager?.Permissions ?? [];
|
||||||
|
|
||||||
// 若当前路由在按钮权限集合里面则放行
|
// 若当前路由在按钮权限集合里面则放行
|
||||||
if (roleApis[0].Exists(u => path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase)))
|
if (permissions.Exists(u => path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// 若当前路由在已接口黑名单里面则禁止
|
// 若当前路由在已接口黑名单里面则禁止
|
||||||
return roleApis[1].TrueForAll(u => !path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase));
|
return unauthorizedPermissions.TrueForAll(u => !path.EndsWith(u, StringComparison.CurrentCultureIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,8 +17,6 @@ namespace Admin.NET.Plugin.ReZero.Service;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class SuperApiAop : DefaultSuperApiAop
|
public class SuperApiAop : DefaultSuperApiAop
|
||||||
{
|
{
|
||||||
private static readonly Lazy<UserManager> _userManager = new(() => App.GetService<UserManager>());
|
|
||||||
|
|
||||||
public override async Task OnExecutingAsync(InterfaceContext aopContext)
|
public override async Task OnExecutingAsync(InterfaceContext aopContext)
|
||||||
{
|
{
|
||||||
////if (aopContext.InterfaceType == InterfaceType.DynamicApi)
|
////if (aopContext.InterfaceType == InterfaceType.DynamicApi)
|
||||||
@ -60,33 +58,34 @@ public class SuperApiAop : DefaultSuperApiAop
|
|||||||
var api = aopContext.InterfaceInfo;
|
var api = aopContext.InterfaceInfo;
|
||||||
var context = aopContext.HttpContext;
|
var context = aopContext.HttpContext;
|
||||||
|
|
||||||
var paths = api.Url.Split('/');
|
var paths = api?.Url?.Split('/');
|
||||||
var actionName = paths[paths.Length - 1];
|
var actionName = paths?[^1];
|
||||||
|
|
||||||
|
var userManager = LazyHelper.GetService<UserManager>();
|
||||||
var apiInfo = new
|
var apiInfo = new
|
||||||
{
|
{
|
||||||
requestUrl = api.Url,
|
requestUrl = api?.Url,
|
||||||
httpMethod = api.HttpMethod,
|
httpMethod = api?.HttpMethod,
|
||||||
displayTitle = api.Name,
|
displayTitle = api?.Name,
|
||||||
actionTypeName = actionName,
|
actionTypeName = actionName,
|
||||||
controllerName = aopContext.InterfaceType == InterfaceType.DynamicApi ? $"ReZero动态-{api.GroupName}" : $"ReZero系统-{api.GroupName}",
|
controllerName = aopContext.InterfaceType == InterfaceType.DynamicApi ? $"ReZero动态-{api?.GroupName}" : $"ReZero系统-{api?.GroupName}",
|
||||||
remoteIPv4 = context.GetRemoteIpAddressToIPv4(),
|
remoteIPv4 = context.GetRemoteIpAddressToIPv4(),
|
||||||
userAgent = context.Request.Headers["User-Agent"],
|
userAgent = context?.Request.Headers["User-Agent"],
|
||||||
returnInformation = new
|
returnInformation = new
|
||||||
{
|
{
|
||||||
httpStatusCode = context.Response.StatusCode,
|
httpStatusCode = context?.Response.StatusCode,
|
||||||
},
|
},
|
||||||
authorizationClaims = new[]
|
authorizationClaims = new[]
|
||||||
{
|
{
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
type = _userManager.Value?.Account,
|
type = userManager?.Account,
|
||||||
value = _userManager.Value?.RealName
|
value = userManager?.RealName
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
type = _userManager.Value?.RealName,
|
type = userManager?.RealName,
|
||||||
value = _userManager.Value?.RealName
|
value = userManager?.RealName
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
exception = aopContext.Exception == null ? null : JSON.Serialize(aopContext.Exception)
|
exception = aopContext.Exception == null ? null : JSON.Serialize(aopContext.Exception)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user