feat(marketing): add new customer gift backend module

This commit is contained in:
2026-03-02 15:58:06 +08:00
parent c9e2226b48
commit 6588c85f27
38 changed files with 12525 additions and 1 deletions

View File

@@ -354,6 +354,22 @@ public sealed class TakeoutAppDbContext(
/// </summary>
public DbSet<PromotionCampaign> PromotionCampaigns => Set<PromotionCampaign>();
/// <summary>
/// 新客有礼配置。
/// </summary>
public DbSet<NewCustomerGiftSetting> NewCustomerGiftSettings => Set<NewCustomerGiftSetting>();
/// <summary>
/// 新客有礼券规则。
/// </summary>
public DbSet<NewCustomerCouponRule> NewCustomerCouponRules => Set<NewCustomerCouponRule>();
/// <summary>
/// 新客邀请记录。
/// </summary>
public DbSet<NewCustomerInviteRecord> NewCustomerInviteRecords => Set<NewCustomerInviteRecord>();
/// <summary>
/// 新客成长记录。
/// </summary>
public DbSet<NewCustomerGrowthRecord> NewCustomerGrowthRecords => Set<NewCustomerGrowthRecord>();
/// <summary>
/// 会员档案。
/// </summary>
public DbSet<MemberProfile> MemberProfiles => Set<MemberProfile>();
@@ -520,6 +536,10 @@ public sealed class TakeoutAppDbContext(
ConfigureCouponTemplate(modelBuilder.Entity<CouponTemplate>());
ConfigureCoupon(modelBuilder.Entity<Coupon>());
ConfigurePromotionCampaign(modelBuilder.Entity<PromotionCampaign>());
ConfigureNewCustomerGiftSetting(modelBuilder.Entity<NewCustomerGiftSetting>());
ConfigureNewCustomerCouponRule(modelBuilder.Entity<NewCustomerCouponRule>());
ConfigureNewCustomerInviteRecord(modelBuilder.Entity<NewCustomerInviteRecord>());
ConfigureNewCustomerGrowthRecord(modelBuilder.Entity<NewCustomerGrowthRecord>());
ConfigureMemberProfile(modelBuilder.Entity<MemberProfile>());
ConfigureMemberTier(modelBuilder.Entity<MemberTier>());
ConfigureMemberPointLedger(modelBuilder.Entity<MemberPointLedger>());
@@ -1619,6 +1639,59 @@ public sealed class TakeoutAppDbContext(
builder.Property(x => x.BannerUrl).HasMaxLength(512);
}
private static void ConfigureNewCustomerGiftSetting(EntityTypeBuilder<NewCustomerGiftSetting> builder)
{
builder.ToTable("new_customer_gift_settings");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.GiftType).HasConversion<int>();
builder.Property(x => x.DirectReduceAmount).HasPrecision(18, 2);
builder.Property(x => x.DirectMinimumSpend).HasPrecision(18, 2);
builder.Property(x => x.ShareChannelsJson).HasColumnType("text").IsRequired();
builder.HasIndex(x => new { x.TenantId, x.StoreId }).IsUnique();
}
private static void ConfigureNewCustomerCouponRule(EntityTypeBuilder<NewCustomerCouponRule> builder)
{
builder.ToTable("new_customer_coupon_rules");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.Scene).HasConversion<int>();
builder.Property(x => x.CouponType).HasConversion<int>();
builder.Property(x => x.Value).HasPrecision(18, 2);
builder.Property(x => x.MinimumSpend).HasPrecision(18, 2);
builder.Property(x => x.ValidDays).IsRequired();
builder.Property(x => x.SortOrder).IsRequired();
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Scene, x.SortOrder });
}
private static void ConfigureNewCustomerInviteRecord(EntityTypeBuilder<NewCustomerInviteRecord> builder)
{
builder.ToTable("new_customer_invite_records");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.InviterName).HasMaxLength(64).IsRequired();
builder.Property(x => x.InviteeName).HasMaxLength(64).IsRequired();
builder.Property(x => x.InviteTime).IsRequired();
builder.Property(x => x.OrderStatus).HasConversion<int>();
builder.Property(x => x.RewardStatus).HasConversion<int>();
builder.Property(x => x.SourceChannel).HasMaxLength(32);
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.InviteTime });
}
private static void ConfigureNewCustomerGrowthRecord(EntityTypeBuilder<NewCustomerGrowthRecord> builder)
{
builder.ToTable("new_customer_growth_records");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.CustomerKey).HasMaxLength(64).IsRequired();
builder.Property(x => x.CustomerName).HasMaxLength(64);
builder.Property(x => x.RegisteredAt).IsRequired();
builder.Property(x => x.SourceChannel).HasMaxLength(32);
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.CustomerKey }).IsUnique();
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.RegisteredAt });
}
private static void ConfigureMemberProfile(EntityTypeBuilder<MemberProfile> builder)
{
builder.ToTable("member_profiles");