feat: 重构 RBAC1 角色权限模型

This commit is contained in:
2025-12-02 16:21:46 +08:00
parent 3d69151426
commit b459c7edbe
21 changed files with 780 additions and 49 deletions

View File

@@ -1,3 +1,5 @@
using System;
using System.Linq;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
@@ -7,6 +9,10 @@ using Microsoft.Extensions.Options;
using TakeoutSaaS.Infrastructure.Identity.Options;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
using DomainIdentityUser = TakeoutSaaS.Domain.Identity.Entities.IdentityUser;
using DomainPermission = TakeoutSaaS.Domain.Identity.Entities.Permission;
using DomainRole = TakeoutSaaS.Domain.Identity.Entities.Role;
using DomainRolePermission = TakeoutSaaS.Domain.Identity.Entities.RolePermission;
using DomainUserRole = TakeoutSaaS.Domain.Identity.Entities.UserRole;
namespace TakeoutSaaS.Infrastructure.Identity.Persistence;
@@ -47,9 +53,7 @@ public sealed class IdentityDataSeeder(IServiceProvider serviceProvider, ILogger
DisplayName = userOptions.DisplayName,
TenantId = userOptions.TenantId,
MerchantId = userOptions.MerchantId,
Avatar = null,
Roles = roles,
Permissions = permissions,
Avatar = null
};
user.PasswordHash = passwordHasher.HashPassword(user, userOptions.Password);
context.IdentityUsers.Add(user);
@@ -60,11 +64,94 @@ public sealed class IdentityDataSeeder(IServiceProvider serviceProvider, ILogger
user.DisplayName = userOptions.DisplayName;
user.TenantId = userOptions.TenantId;
user.MerchantId = userOptions.MerchantId;
user.Roles = roles;
user.Permissions = permissions;
user.PasswordHash = passwordHasher.HashPassword(user, userOptions.Password);
logger.LogInformation("已更新后台账号 {Account}", user.Account);
}
// 确保角色存在
var existingRoles = await context.Roles
.Where(r => r.TenantId == userOptions.TenantId && roles.Contains(r.Code))
.ToListAsync(cancellationToken);
var existingRoleCodes = existingRoles.Select(r => r.Code).ToHashSet(StringComparer.OrdinalIgnoreCase);
foreach (var code in roles)
{
if (existingRoleCodes.Contains(code))
{
continue;
}
context.Roles.Add(new DomainRole
{
TenantId = userOptions.TenantId,
Code = code,
Name = code,
Description = $"Seed role {code}"
});
}
// 确保权限存在
var existingPermissions = await context.Permissions
.Where(p => p.TenantId == userOptions.TenantId && permissions.Contains(p.Code))
.ToListAsync(cancellationToken);
var existingPermissionCodes = existingPermissions.Select(p => p.Code).ToHashSet(StringComparer.OrdinalIgnoreCase);
foreach (var code in permissions)
{
if (existingPermissionCodes.Contains(code))
{
continue;
}
context.Permissions.Add(new DomainPermission
{
TenantId = userOptions.TenantId,
Code = code,
Name = code,
Description = $"Seed permission {code}"
});
}
await context.SaveChangesAsync(cancellationToken);
// 重新加载角色/权限以获取 Id
var roleEntities = await context.Roles
.Where(r => r.TenantId == userOptions.TenantId && roles.Contains(r.Code))
.ToListAsync(cancellationToken);
var permissionEntities = await context.Permissions
.Where(p => p.TenantId == userOptions.TenantId && permissions.Contains(p.Code))
.ToListAsync(cancellationToken);
// 重置用户角色
var existingUserRoles = await context.UserRoles
.Where(ur => ur.TenantId == userOptions.TenantId && ur.UserId == user.Id)
.ToListAsync(cancellationToken);
context.UserRoles.RemoveRange(existingUserRoles);
var roleIds = roleEntities.Select(r => r.Id).Distinct().ToArray();
var userRoles = roleIds.Select(roleId => new DomainUserRole
{
TenantId = userOptions.TenantId,
UserId = user.Id,
RoleId = roleId
});
await context.UserRoles.AddRangeAsync(userRoles, cancellationToken);
// 为种子角色绑定种子权限
if (permissions.Length > 0 && roleIds.Length > 0)
{
var permissionIds = permissionEntities.Select(p => p.Id).Distinct().ToArray();
var existingRolePermissions = await context.RolePermissions
.Where(rp => rp.TenantId == userOptions.TenantId && roleIds.Contains(rp.RoleId))
.ToListAsync(cancellationToken);
context.RolePermissions.RemoveRange(existingRolePermissions);
var newRolePermissions = roleIds.SelectMany(roleId => permissionIds.Select(permissionId => new DomainRolePermission
{
TenantId = userOptions.TenantId,
RoleId = roleId,
PermissionId = permissionId
}));
await context.RolePermissions.AddRangeAsync(newRolePermissions, cancellationToken);
}
}
await context.SaveChangesAsync(cancellationToken);