128 lines
5.4 KiB
C#
128 lines
5.4 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using TakeoutSaaS.Domain.Identity.Entities;
|
|
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
|
|
namespace TakeoutSaaS.Infrastructure.Identity.Persistence;
|
|
|
|
/// <summary>
|
|
/// 角色模板仓储实现。
|
|
/// </summary>
|
|
public sealed class EfRoleTemplateRepository(IdentityDbContext dbContext) : IRoleTemplateRepository
|
|
{
|
|
public Task<IReadOnlyList<RoleTemplate>> GetAllAsync(bool? isActive, CancellationToken cancellationToken = default)
|
|
{
|
|
var query = dbContext.RoleTemplates.AsNoTracking();
|
|
if (isActive.HasValue)
|
|
{
|
|
query = query.Where(x => x.IsActive == isActive.Value);
|
|
}
|
|
|
|
return query
|
|
.OrderBy(x => x.TemplateCode)
|
|
.ToListAsync(cancellationToken)
|
|
.ContinueWith(t => (IReadOnlyList<RoleTemplate>)t.Result, cancellationToken);
|
|
}
|
|
|
|
public Task<RoleTemplate?> FindByCodeAsync(string templateCode, CancellationToken cancellationToken = default)
|
|
{
|
|
var normalized = templateCode.Trim();
|
|
return dbContext.RoleTemplates.AsNoTracking().FirstOrDefaultAsync(x => x.TemplateCode == normalized, cancellationToken);
|
|
}
|
|
|
|
public Task<IReadOnlyList<RoleTemplatePermission>> GetPermissionsAsync(long roleTemplateId, CancellationToken cancellationToken = default)
|
|
{
|
|
return dbContext.RoleTemplatePermissions.AsNoTracking()
|
|
.Where(x => x.RoleTemplateId == roleTemplateId)
|
|
.ToListAsync(cancellationToken)
|
|
.ContinueWith(t => (IReadOnlyList<RoleTemplatePermission>)t.Result, cancellationToken);
|
|
}
|
|
|
|
public async Task<IDictionary<long, IReadOnlyList<RoleTemplatePermission>>> GetPermissionsAsync(IEnumerable<long> roleTemplateIds, CancellationToken cancellationToken = default)
|
|
{
|
|
var ids = roleTemplateIds.Distinct().ToArray();
|
|
if (ids.Length == 0)
|
|
{
|
|
return new Dictionary<long, IReadOnlyList<RoleTemplatePermission>>();
|
|
}
|
|
|
|
var permissions = await dbContext.RoleTemplatePermissions.AsNoTracking()
|
|
.Where(x => ids.Contains(x.RoleTemplateId))
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return permissions
|
|
.GroupBy(x => x.RoleTemplateId)
|
|
.ToDictionary(g => g.Key, g => (IReadOnlyList<RoleTemplatePermission>)g.ToList());
|
|
}
|
|
|
|
public async Task AddAsync(RoleTemplate template, IEnumerable<string> permissionCodes, CancellationToken cancellationToken = default)
|
|
{
|
|
template.TemplateCode = template.TemplateCode.Trim();
|
|
template.Name = template.Name.Trim();
|
|
await dbContext.RoleTemplates.AddAsync(template, cancellationToken);
|
|
await ReplacePermissionsInternalAsync(template, permissionCodes, cancellationToken);
|
|
}
|
|
|
|
public async Task UpdateAsync(RoleTemplate template, IEnumerable<string> permissionCodes, CancellationToken cancellationToken = default)
|
|
{
|
|
template.TemplateCode = template.TemplateCode.Trim();
|
|
template.Name = template.Name.Trim();
|
|
dbContext.RoleTemplates.Update(template);
|
|
await ReplacePermissionsInternalAsync(template, permissionCodes, cancellationToken);
|
|
}
|
|
|
|
public async Task DeleteAsync(long roleTemplateId, CancellationToken cancellationToken = default)
|
|
{
|
|
var entity = await dbContext.RoleTemplates.FirstOrDefaultAsync(x => x.Id == roleTemplateId, cancellationToken);
|
|
if (entity != null)
|
|
{
|
|
var permissions = dbContext.RoleTemplatePermissions.Where(x => x.RoleTemplateId == roleTemplateId);
|
|
dbContext.RoleTemplatePermissions.RemoveRange(permissions);
|
|
dbContext.RoleTemplates.Remove(entity);
|
|
}
|
|
}
|
|
|
|
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
|
=> dbContext.SaveChangesAsync(cancellationToken);
|
|
|
|
private async Task ReplacePermissionsInternalAsync(RoleTemplate template, IEnumerable<string> permissionCodes, CancellationToken cancellationToken)
|
|
{
|
|
var strategy = dbContext.Database.CreateExecutionStrategy();
|
|
await strategy.ExecuteAsync(async () =>
|
|
{
|
|
await using var trx = await dbContext.Database.BeginTransactionAsync(cancellationToken);
|
|
|
|
// 1. 确保模板已持久化,便于 FK 正确填充
|
|
if (!dbContext.Entry(template).IsKeySet || template.Id == 0)
|
|
{
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
}
|
|
|
|
// 2. 归一化权限编码
|
|
var normalized = permissionCodes
|
|
.Where(code => !string.IsNullOrWhiteSpace(code))
|
|
.Select(code => code.Trim())
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToArray();
|
|
|
|
// 3. 清空旧权限
|
|
var existing = await dbContext.RoleTemplatePermissions
|
|
.Where(x => x.RoleTemplateId == template.Id)
|
|
.ToListAsync(cancellationToken);
|
|
dbContext.RoleTemplatePermissions.RemoveRange(existing);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
|
|
// 4. 插入新权限
|
|
var toAdd = normalized.Select(code => new RoleTemplatePermission
|
|
{
|
|
RoleTemplateId = template.Id,
|
|
PermissionCode = code
|
|
});
|
|
|
|
await dbContext.RoleTemplatePermissions.AddRangeAsync(toAdd, cancellationToken);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
|
|
await trx.CommitAsync(cancellationToken);
|
|
});
|
|
}
|
|
}
|