feat: implement marketing punch card backend module
This commit is contained in:
@@ -370,6 +370,18 @@ public sealed class TakeoutAppDbContext(
|
||||
/// </summary>
|
||||
public DbSet<NewCustomerGrowthRecord> NewCustomerGrowthRecords => Set<NewCustomerGrowthRecord>();
|
||||
/// <summary>
|
||||
/// 次卡模板。
|
||||
/// </summary>
|
||||
public DbSet<PunchCardTemplate> PunchCardTemplates => Set<PunchCardTemplate>();
|
||||
/// <summary>
|
||||
/// 次卡实例。
|
||||
/// </summary>
|
||||
public DbSet<PunchCardInstance> PunchCardInstances => Set<PunchCardInstance>();
|
||||
/// <summary>
|
||||
/// 次卡使用记录。
|
||||
/// </summary>
|
||||
public DbSet<PunchCardUsageRecord> PunchCardUsageRecords => Set<PunchCardUsageRecord>();
|
||||
/// <summary>
|
||||
/// 会员档案。
|
||||
/// </summary>
|
||||
public DbSet<MemberProfile> MemberProfiles => Set<MemberProfile>();
|
||||
@@ -540,6 +552,9 @@ public sealed class TakeoutAppDbContext(
|
||||
ConfigureNewCustomerCouponRule(modelBuilder.Entity<NewCustomerCouponRule>());
|
||||
ConfigureNewCustomerInviteRecord(modelBuilder.Entity<NewCustomerInviteRecord>());
|
||||
ConfigureNewCustomerGrowthRecord(modelBuilder.Entity<NewCustomerGrowthRecord>());
|
||||
ConfigurePunchCardTemplate(modelBuilder.Entity<PunchCardTemplate>());
|
||||
ConfigurePunchCardInstance(modelBuilder.Entity<PunchCardInstance>());
|
||||
ConfigurePunchCardUsageRecord(modelBuilder.Entity<PunchCardUsageRecord>());
|
||||
ConfigureMemberProfile(modelBuilder.Entity<MemberProfile>());
|
||||
ConfigureMemberTier(modelBuilder.Entity<MemberTier>());
|
||||
ConfigureMemberPointLedger(modelBuilder.Entity<MemberPointLedger>());
|
||||
@@ -1692,6 +1707,77 @@ public sealed class TakeoutAppDbContext(
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.RegisteredAt });
|
||||
}
|
||||
|
||||
private static void ConfigurePunchCardTemplate(EntityTypeBuilder<PunchCardTemplate> builder)
|
||||
{
|
||||
builder.ToTable("punch_card_templates");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.StoreId).IsRequired();
|
||||
builder.Property(x => x.Name).HasMaxLength(64).IsRequired();
|
||||
builder.Property(x => x.CoverImageUrl).HasMaxLength(512);
|
||||
builder.Property(x => x.SalePrice).HasPrecision(18, 2);
|
||||
builder.Property(x => x.OriginalPrice).HasPrecision(18, 2);
|
||||
builder.Property(x => x.TotalTimes).IsRequired();
|
||||
builder.Property(x => x.ValidityType).HasConversion<int>();
|
||||
builder.Property(x => x.ValidityDays);
|
||||
builder.Property(x => x.ValidFrom);
|
||||
builder.Property(x => x.ValidTo);
|
||||
builder.Property(x => x.ScopeType).HasConversion<int>();
|
||||
builder.Property(x => x.ScopeCategoryIdsJson).HasColumnType("text").IsRequired();
|
||||
builder.Property(x => x.ScopeTagIdsJson).HasColumnType("text").IsRequired();
|
||||
builder.Property(x => x.ScopeProductIdsJson).HasColumnType("text").IsRequired();
|
||||
builder.Property(x => x.UsageMode).HasConversion<int>();
|
||||
builder.Property(x => x.UsageCapAmount).HasPrecision(18, 2);
|
||||
builder.Property(x => x.DailyLimit);
|
||||
builder.Property(x => x.PerOrderLimit);
|
||||
builder.Property(x => x.PerUserPurchaseLimit);
|
||||
builder.Property(x => x.AllowTransfer).IsRequired();
|
||||
builder.Property(x => x.ExpireStrategy).HasConversion<int>();
|
||||
builder.Property(x => x.Description).HasMaxLength(512);
|
||||
builder.Property(x => x.NotifyChannelsJson).HasColumnType("text").IsRequired();
|
||||
builder.Property(x => x.Status).HasConversion<int>();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Name }).IsUnique();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Status });
|
||||
}
|
||||
|
||||
private static void ConfigurePunchCardInstance(EntityTypeBuilder<PunchCardInstance> builder)
|
||||
{
|
||||
builder.ToTable("punch_card_instances");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.StoreId).IsRequired();
|
||||
builder.Property(x => x.PunchCardTemplateId).IsRequired();
|
||||
builder.Property(x => x.InstanceNo).HasMaxLength(32).IsRequired();
|
||||
builder.Property(x => x.MemberName).HasMaxLength(64).IsRequired();
|
||||
builder.Property(x => x.MemberPhoneMasked).HasMaxLength(32).IsRequired();
|
||||
builder.Property(x => x.PurchasedAt).IsRequired();
|
||||
builder.Property(x => x.ExpiresAt);
|
||||
builder.Property(x => x.TotalTimes).IsRequired();
|
||||
builder.Property(x => x.RemainingTimes).IsRequired();
|
||||
builder.Property(x => x.PaidAmount).HasPrecision(18, 2);
|
||||
builder.Property(x => x.Status).HasConversion<int>();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.InstanceNo }).IsUnique();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.PunchCardTemplateId });
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Status, x.ExpiresAt });
|
||||
}
|
||||
|
||||
private static void ConfigurePunchCardUsageRecord(EntityTypeBuilder<PunchCardUsageRecord> builder)
|
||||
{
|
||||
builder.ToTable("punch_card_usage_records");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.StoreId).IsRequired();
|
||||
builder.Property(x => x.PunchCardTemplateId).IsRequired();
|
||||
builder.Property(x => x.PunchCardInstanceId).IsRequired();
|
||||
builder.Property(x => x.RecordNo).HasMaxLength(32).IsRequired();
|
||||
builder.Property(x => x.ProductName).HasMaxLength(128).IsRequired();
|
||||
builder.Property(x => x.UsedAt).IsRequired();
|
||||
builder.Property(x => x.UsedTimes).IsRequired();
|
||||
builder.Property(x => x.RemainingTimesAfterUse).IsRequired();
|
||||
builder.Property(x => x.StatusAfterUse).HasConversion<int>();
|
||||
builder.Property(x => x.ExtraPayAmount).HasPrecision(18, 2);
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.RecordNo }).IsUnique();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.PunchCardTemplateId, x.UsedAt });
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.PunchCardInstanceId, x.UsedAt });
|
||||
}
|
||||
|
||||
private static void ConfigureMemberProfile(EntityTypeBuilder<MemberProfile> builder)
|
||||
{
|
||||
builder.ToTable("member_profiles");
|
||||
|
||||
Reference in New Issue
Block a user