using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using TakeoutSaaS.Domain.Identity.Entities;
using TakeoutSaaS.Infrastructure.Common.Persistence;
using TakeoutSaaS.Shared.Abstractions.Ids;
using TakeoutSaaS.Shared.Abstractions.Security;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Infrastructure.Identity.Persistence;
///
/// 身份认证 DbContext,带多租户过滤与审计字段处理。
///
public sealed class IdentityDbContext(
DbContextOptions options,
ITenantProvider tenantProvider,
ICurrentUserAccessor? currentUserAccessor = null,
IIdGenerator? idGenerator = null)
: TenantAwareDbContext(options, tenantProvider, currentUserAccessor, idGenerator)
{
///
/// 管理后台用户集合。
///
public DbSet IdentityUsers => Set();
///
/// 小程序用户集合。
///
public DbSet MiniUsers => Set();
///
/// 角色集合。
///
public DbSet Roles => Set();
///
/// 角色模板集合(平台级)。
///
public DbSet RoleTemplates => Set();
///
/// 角色模板权限集合。
///
public DbSet RoleTemplatePermissions => Set();
///
/// 权限集合。
///
public DbSet Permissions => Set();
///
/// 用户-角色关系。
///
public DbSet UserRoles => Set();
///
/// 角色-权限关系。
///
public DbSet RolePermissions => Set();
///
/// 配置实体模型。
///
/// 模型构建器。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
ConfigureIdentityUser(modelBuilder.Entity());
ConfigureMiniUser(modelBuilder.Entity());
ConfigureRole(modelBuilder.Entity());
ConfigureRoleTemplate(modelBuilder.Entity());
ConfigureRoleTemplatePermission(modelBuilder.Entity());
ConfigurePermission(modelBuilder.Entity());
ConfigureUserRole(modelBuilder.Entity());
ConfigureRolePermission(modelBuilder.Entity());
ApplyTenantQueryFilters(modelBuilder);
}
///
/// 配置管理后台用户实体。
///
/// 实体构建器。
private static void ConfigureIdentityUser(EntityTypeBuilder builder)
{
builder.ToTable("identity_users");
builder.HasKey(x => x.Id);
builder.Property(x => x.Account).HasMaxLength(64).IsRequired();
builder.Property(x => x.DisplayName).HasMaxLength(64).IsRequired();
builder.Property(x => x.PasswordHash).HasMaxLength(256).IsRequired();
builder.Property(x => x.Avatar).HasMaxLength(256);
builder.Property(x => x.TenantId).IsRequired();
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.Account }).IsUnique();
}
///
/// 配置小程序用户实体。
///
/// 实体构建器。
private static void ConfigureMiniUser(EntityTypeBuilder builder)
{
builder.ToTable("mini_users");
builder.HasKey(x => x.Id);
builder.Property(x => x.TenantId).IsRequired();
builder.Property(x => x.OpenId).HasMaxLength(128).IsRequired();
builder.Property(x => x.UnionId).HasMaxLength(128);
builder.Property(x => x.Nickname).HasMaxLength(64).IsRequired();
builder.Property(x => x.Avatar).HasMaxLength(256);
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.OpenId }).IsUnique();
}
private static void ConfigureRole(EntityTypeBuilder builder)
{
builder.ToTable("roles");
builder.HasKey(x => x.Id);
builder.Property(x => x.TenantId).IsRequired();
builder.Property(x => x.Name).HasMaxLength(64).IsRequired();
builder.Property(x => x.Code).HasMaxLength(64).IsRequired();
builder.Property(x => x.Description).HasMaxLength(256);
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.Code }).IsUnique();
}
private static void ConfigurePermission(EntityTypeBuilder builder)
{
builder.ToTable("permissions");
builder.HasKey(x => x.Id);
builder.Property(x => x.TenantId).IsRequired();
builder.Property(x => x.Name).HasMaxLength(64).IsRequired();
builder.Property(x => x.Code).HasMaxLength(128).IsRequired();
builder.Property(x => x.Description).HasMaxLength(256);
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.Code }).IsUnique();
}
private static void ConfigureRoleTemplate(EntityTypeBuilder builder)
{
builder.ToTable("role_templates");
builder.HasKey(x => x.Id);
builder.Property(x => x.TemplateCode).HasMaxLength(64).IsRequired();
builder.Property(x => x.Name).HasMaxLength(128).IsRequired();
builder.Property(x => x.Description).HasMaxLength(256);
builder.Property(x => x.IsActive).IsRequired();
ConfigureAuditableEntity(builder);
builder.HasIndex(x => x.TemplateCode).IsUnique();
}
private static void ConfigureRoleTemplatePermission(EntityTypeBuilder builder)
{
builder.ToTable("role_template_permissions");
builder.HasKey(x => x.Id);
builder.Property(x => x.RoleTemplateId).IsRequired();
builder.Property(x => x.PermissionCode).HasMaxLength(128).IsRequired();
ConfigureAuditableEntity(builder);
builder.HasIndex(x => new { x.RoleTemplateId, x.PermissionCode }).IsUnique();
}
private static void ConfigureUserRole(EntityTypeBuilder builder)
{
builder.ToTable("user_roles");
builder.HasKey(x => x.Id);
builder.Property(x => x.TenantId).IsRequired();
builder.Property(x => x.UserId).IsRequired();
builder.Property(x => x.RoleId).IsRequired();
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.UserId, x.RoleId }).IsUnique();
}
private static void ConfigureRolePermission(EntityTypeBuilder builder)
{
builder.ToTable("role_permissions");
builder.HasKey(x => x.Id);
builder.Property(x => x.TenantId).IsRequired();
builder.Property(x => x.RoleId).IsRequired();
builder.Property(x => x.PermissionId).IsRequired();
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);
builder.HasIndex(x => x.TenantId);
builder.HasIndex(x => new { x.TenantId, x.RoleId, x.PermissionId }).IsUnique();
}
}