using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using TakeoutSaaS.Domain.Membership.Entities; using TakeoutSaaS.Domain.Merchants.Entities; using TakeoutSaaS.Domain.Tenants.Entities; using TakeoutSaaS.Infrastructure.Common.Persistence; using TakeoutSaaS.Shared.Abstractions.Ids; using TakeoutSaaS.Shared.Abstractions.Security; using TakeoutSaaS.Shared.Abstractions.Tenancy; namespace TakeoutSaaS.Infrastructure.Logs.Persistence; /// /// 日志库 DbContext。 /// public sealed class TakeoutLogsDbContext( DbContextOptions options, ITenantProvider tenantProvider, ICurrentUserAccessor? currentUserAccessor = null, IIdGenerator? idGenerator = null) : TenantAwareDbContext(options, tenantProvider, currentUserAccessor, idGenerator) { /// /// 租户审计日志集合。 /// public DbSet TenantAuditLogs => Set(); /// /// 商户审计日志集合。 /// public DbSet MerchantAuditLogs => Set(); /// /// 商户变更日志集合。 /// public DbSet MerchantChangeLogs => Set(); /// /// 运营操作日志集合。 /// public DbSet OperationLogs => Set(); /// /// 操作日志消息去重集合。 /// public DbSet OperationLogInboxMessages => Set(); /// /// 成长值日志集合。 /// public DbSet MemberGrowthLogs => Set(); /// /// 配置实体模型。 /// /// 模型构建器。 protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); ConfigureTenantAuditLog(modelBuilder.Entity()); ConfigureMerchantAuditLog(modelBuilder.Entity()); ConfigureMerchantChangeLog(modelBuilder.Entity()); ConfigureOperationLog(modelBuilder.Entity()); ConfigureOperationLogInboxMessage(modelBuilder.Entity()); ConfigureMemberGrowthLog(modelBuilder.Entity()); ApplyTenantQueryFilters(modelBuilder); } private static void ConfigureTenantAuditLog(EntityTypeBuilder builder) { builder.ToTable("tenant_audit_logs"); builder.HasKey(x => x.Id); builder.Property(x => x.TenantId).IsRequired(); builder.Property(x => x.Title).HasMaxLength(128).IsRequired(); builder.Property(x => x.Description).HasMaxLength(1024); builder.Property(x => x.OperatorName).HasMaxLength(64); builder.HasIndex(x => x.TenantId); } private static void ConfigureMerchantAuditLog(EntityTypeBuilder builder) { builder.ToTable("merchant_audit_logs"); builder.HasKey(x => x.Id); builder.Property(x => x.MerchantId).IsRequired(); builder.Property(x => x.Action).HasConversion().IsRequired(); builder.Property(x => x.Title).HasMaxLength(200).IsRequired(); builder.Property(x => x.Description).HasMaxLength(1024); builder.Property(x => x.OperatorName).HasMaxLength(100); builder.Property(x => x.IpAddress).HasMaxLength(50); builder.HasIndex(x => new { x.TenantId, x.MerchantId }); builder.HasIndex(x => new { x.MerchantId, x.CreatedAt }); builder.HasIndex(x => new { x.TenantId, x.CreatedAt }); } private static void ConfigureMerchantChangeLog(EntityTypeBuilder builder) { builder.ToTable("merchant_change_logs"); builder.HasKey(x => x.Id); builder.Property(x => x.MerchantId).IsRequired(); builder.Property(x => x.FieldName).HasMaxLength(100).IsRequired(); builder.Property(x => x.OldValue).HasColumnType("text"); builder.Property(x => x.NewValue).HasColumnType("text"); builder.Property(x => x.ChangeType).HasMaxLength(20).IsRequired(); builder.Property(x => x.ChangedByName).HasMaxLength(100); builder.Property(x => x.ChangeReason).HasMaxLength(512); builder.HasIndex(x => new { x.MerchantId, x.CreatedAt }); builder.HasIndex(x => new { x.TenantId, x.CreatedAt }); } private static void ConfigureOperationLog(EntityTypeBuilder builder) { builder.ToTable("operation_logs"); builder.HasKey(x => x.Id); builder.Property(x => x.OperationType).HasMaxLength(64).IsRequired(); builder.Property(x => x.TargetType).HasMaxLength(64).IsRequired(); builder.Property(x => x.TargetIds).HasColumnType("text"); builder.Property(x => x.OperatorId).HasMaxLength(64); builder.Property(x => x.OperatorName).HasMaxLength(128); builder.Property(x => x.Parameters).HasColumnType("text"); builder.Property(x => x.Result).HasColumnType("text"); builder.Property(x => x.Success).IsRequired(); builder.HasIndex(x => new { x.OperationType, x.CreatedAt }); builder.HasIndex(x => x.CreatedAt); } private static void ConfigureOperationLogInboxMessage(EntityTypeBuilder builder) { builder.ToTable("operation_log_inbox_messages"); builder.HasKey(x => x.Id); builder.Property(x => x.MessageId).IsRequired(); builder.Property(x => x.ConsumedAt).IsRequired(); builder.HasIndex(x => x.MessageId).IsUnique(); } private static void ConfigureMemberGrowthLog(EntityTypeBuilder builder) { builder.ToTable("member_growth_logs"); builder.HasKey(x => x.Id); builder.Property(x => x.MemberId).IsRequired(); builder.Property(x => x.Notes).HasMaxLength(256); builder.HasIndex(x => new { x.TenantId, x.MemberId, x.OccurredAt }); } }