124 lines
3.8 KiB
C#
124 lines
3.8 KiB
C#
using System.Collections.Concurrent;
|
||
using HoneyBox.Admin.Data;
|
||
using HoneyBox.Admin.Models.Permission;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace HoneyBox.Admin.Services;
|
||
|
||
/// <summary>
|
||
/// 权限服务实现
|
||
/// </summary>
|
||
public class PermissionService : IPermissionService
|
||
{
|
||
private readonly AdminDbContext _dbContext;
|
||
private readonly ILogger<PermissionService> _logger;
|
||
|
||
// 简单的内存缓存(生产环境建议使用 Redis)
|
||
private static readonly ConcurrentDictionary<long, (List<string> Permissions, DateTime ExpireAt)> _permissionCache = new();
|
||
private const int CacheMinutes = 30;
|
||
|
||
public PermissionService(AdminDbContext dbContext, ILogger<PermissionService> logger)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<string>> GetUserPermissionsAsync(long adminUserId)
|
||
{
|
||
// 尝试从缓存获取
|
||
if (_permissionCache.TryGetValue(adminUserId, out var cached) && cached.ExpireAt > DateTime.Now)
|
||
{
|
||
return cached.Permissions;
|
||
}
|
||
|
||
// 从数据库获取
|
||
var permissions = await LoadUserPermissionsAsync(adminUserId);
|
||
|
||
// 存入缓存
|
||
_permissionCache[adminUserId] = (permissions, DateTime.Now.AddMinutes(CacheMinutes));
|
||
|
||
return permissions;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> HasPermissionAsync(long adminUserId, string permissionCode)
|
||
{
|
||
var permissions = await GetUserPermissionsAsync(adminUserId);
|
||
|
||
// 超级管理员拥有所有权限
|
||
if (permissions.Contains("*"))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return permissions.Contains(permissionCode);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public void InvalidateCache(long adminUserId)
|
||
{
|
||
_permissionCache.TryRemove(adminUserId, out _);
|
||
_logger.LogDebug("用户 {UserId} 权限缓存已失效", adminUserId);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<PermissionDto>> GetAllPermissionsAsync()
|
||
{
|
||
return await _dbContext.Permissions
|
||
.OrderBy(p => p.Module)
|
||
.ThenBy(p => p.Code)
|
||
.Select(p => new PermissionDto
|
||
{
|
||
Id = p.Id,
|
||
Name = p.Name,
|
||
Code = p.Code,
|
||
Module = p.Module,
|
||
Description = p.Description,
|
||
CreatedAt = p.CreatedAt
|
||
})
|
||
.ToListAsync();
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<Dictionary<string, List<PermissionDto>>> GetPermissionsByModuleAsync()
|
||
{
|
||
var permissions = await GetAllPermissionsAsync();
|
||
return permissions
|
||
.GroupBy(p => p.Module ?? "其他")
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从数据库加载用户权限
|
||
/// </summary>
|
||
private async Task<List<string>> LoadUserPermissionsAsync(long adminUserId)
|
||
{
|
||
// 获取用户的所有角色
|
||
var userRoles = await _dbContext.AdminUserRoles
|
||
.Where(ur => ur.AdminUserId == adminUserId)
|
||
.Include(ur => ur.Role)
|
||
.Where(ur => ur.Role.Status == 1)
|
||
.ToListAsync();
|
||
|
||
// 检查是否是超级管理员
|
||
if (userRoles.Any(ur => ur.Role.Code == "super_admin"))
|
||
{
|
||
return new List<string> { "*" }; // 超级管理员拥有所有权限
|
||
}
|
||
|
||
var roleIds = userRoles.Select(ur => ur.RoleId).ToList();
|
||
|
||
// 获取角色关联的权限
|
||
var permissions = await _dbContext.RolePermissions
|
||
.Where(rp => roleIds.Contains(rp.RoleId))
|
||
.Include(rp => rp.Permission)
|
||
.Select(rp => rp.Permission.Code)
|
||
.Distinct()
|
||
.ToListAsync();
|
||
|
||
return permissions;
|
||
}
|
||
}
|