HaniBlindBox/server/HoneyBox/src/HoneyBox.Admin/Services/PermissionService.cs
2026-01-04 01:47:02 +08:00

124 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}