feat(platform): add CRM SMS and payment settings

This commit is contained in:
2026-07-29 15:41:27 +08:00
parent 6db200a2fc
commit ead7bdc2e2
25 changed files with 23250 additions and 140 deletions

View File

@@ -187,6 +187,80 @@ internal sealed class SmsSendRateLimitConfiguration : IEntityTypeConfiguration<S
}
}
internal sealed class SmsChannelConfiguration : IEntityTypeConfiguration<SmsChannel>
{
public void Configure(EntityTypeBuilder<SmsChannel> builder)
{
builder.ConfigureTenantEntity("sms_channels");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Provider).HasMaxLength(80);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Signature).HasMaxLength(100);
builder.Property(entity => entity.Scene).HasMaxLength(100);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.SecretRef).HasMaxLength(300);
builder.Property(entity => entity.ConfigPublic).IsJson("{}");
builder.Property(entity => entity.Metadata).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.Provider, entity.Scene }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.Priority });
builder.ToTable(table => table.HasCheckConstraint("ck_sms_channels_quota", "monthly_quota >= 0"));
}
}
internal sealed class SmsTemplateConfiguration : IEntityTypeConfiguration<SmsTemplate>
{
public void Configure(EntityTypeBuilder<SmsTemplate> builder)
{
builder.ConfigureTenantEntity("sms_templates");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(120);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Type).HasSnakeCaseEnum();
builder.Property(entity => entity.AuditStatus).HasSnakeCaseEnum();
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.ProviderTemplateCode).HasMaxLength(120);
builder.Property(entity => entity.Content).HasMaxLength(1000);
builder.Property(entity => entity.Remark).HasMaxLength(500);
builder.Property(entity => entity.Metadata).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.Code }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.ChannelId, entity.Status });
builder.HasOne<SmsChannel>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.ChannelId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
}
}
internal sealed class SmsSendLogConfiguration : IEntityTypeConfiguration<SmsSendLog>
{
public void Configure(EntityTypeBuilder<SmsSendLog> builder)
{
builder.ToTable("sms_send_logs");
builder.HasKey(entity => entity.Id);
builder.Property(entity => entity.Id).HasDefaultValueSql("gen_random_uuid()");
builder.Property(entity => entity.Provider).HasMaxLength(80);
builder.Property(entity => entity.Scene).HasMaxLength(100);
builder.Property(entity => entity.PhoneMasked).HasMaxLength(40);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.ProviderMessageId).HasMaxLength(200);
builder.Property(entity => entity.ErrorCode).HasMaxLength(120);
builder.Property(entity => entity.ErrorMessage).HasMaxLength(1000);
builder.Property(entity => entity.Metadata).IsJson("{}");
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.TenantId, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.ChannelId, entity.CreatedAt });
builder.HasOne<Tenant>().WithMany().HasForeignKey(entity => entity.TenantId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<SmsChannel>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.ChannelId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.SetNull);
builder.HasOne<SmsTemplate>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.TemplateId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class TenantClassConfiguration : IEntityTypeConfiguration<TenantClass>
{
public void Configure(EntityTypeBuilder<TenantClass> builder)