Merge pull request #3 from msumshk/feature/member-points-mall-1to1

feat(member): implement points mall backend module
This commit is contained in:
2026-03-04 12:32:58 +08:00
committed by GitHub
53 changed files with 5193 additions and 0 deletions

View File

@@ -402,6 +402,18 @@ public sealed class TakeoutAppDbContext(
/// </summary>
public DbSet<MemberPointLedger> MemberPointLedgers => Set<MemberPointLedger>();
/// <summary>
/// 积分商城规则。
/// </summary>
public DbSet<MemberPointMallRule> MemberPointMallRules => Set<MemberPointMallRule>();
/// <summary>
/// 积分商城兑换商品。
/// </summary>
public DbSet<MemberPointMallProduct> MemberPointMallProducts => Set<MemberPointMallProduct>();
/// <summary>
/// 积分商城兑换记录。
/// </summary>
public DbSet<MemberPointMallRecord> MemberPointMallRecords => Set<MemberPointMallRecord>();
/// <summary>
/// 会员储值方案。
/// </summary>
public DbSet<MemberStoredCardPlan> MemberStoredCardPlans => Set<MemberStoredCardPlan>();
@@ -588,6 +600,9 @@ public sealed class TakeoutAppDbContext(
ConfigureMemberProfileTag(modelBuilder.Entity<MemberProfileTag>());
ConfigureMemberDaySetting(modelBuilder.Entity<MemberDaySetting>());
ConfigureMemberPointLedger(modelBuilder.Entity<MemberPointLedger>());
ConfigureMemberPointMallRule(modelBuilder.Entity<MemberPointMallRule>());
ConfigureMemberPointMallProduct(modelBuilder.Entity<MemberPointMallProduct>());
ConfigureMemberPointMallRecord(modelBuilder.Entity<MemberPointMallRecord>());
ConfigureMemberStoredCardPlan(modelBuilder.Entity<MemberStoredCardPlan>());
ConfigureMemberStoredCardRechargeRecord(modelBuilder.Entity<MemberStoredCardRechargeRecord>());
ConfigureMemberReachMessage(modelBuilder.Entity<MemberReachMessage>());
@@ -1871,6 +1886,80 @@ public sealed class TakeoutAppDbContext(
builder.HasIndex(x => new { x.TenantId, x.MemberId, x.OccurredAt });
}
private static void ConfigureMemberPointMallRule(EntityTypeBuilder<MemberPointMallRule> builder)
{
builder.ToTable("member_point_mall_rules");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.IsConsumeRewardEnabled).IsRequired();
builder.Property(x => x.ConsumeAmountPerStep).IsRequired();
builder.Property(x => x.ConsumeRewardPointsPerStep).IsRequired();
builder.Property(x => x.IsReviewRewardEnabled).IsRequired();
builder.Property(x => x.ReviewRewardPoints).IsRequired();
builder.Property(x => x.IsRegisterRewardEnabled).IsRequired();
builder.Property(x => x.RegisterRewardPoints).IsRequired();
builder.Property(x => x.IsSigninRewardEnabled).IsRequired();
builder.Property(x => x.SigninRewardPoints).IsRequired();
builder.Property(x => x.ExpiryMode).HasConversion<int>();
builder.HasIndex(x => new { x.TenantId, x.StoreId }).IsUnique();
}
private static void ConfigureMemberPointMallProduct(EntityTypeBuilder<MemberPointMallProduct> builder)
{
builder.ToTable("member_point_mall_products");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.Name).HasMaxLength(64).IsRequired();
builder.Property(x => x.ImageUrl).HasMaxLength(512);
builder.Property(x => x.RedeemType).HasConversion<int>();
builder.Property(x => x.ProductId);
builder.Property(x => x.CouponTemplateId);
builder.Property(x => x.PhysicalName).HasMaxLength(64);
builder.Property(x => x.PickupMethod).HasConversion<int?>();
builder.Property(x => x.Description).HasMaxLength(512);
builder.Property(x => x.ExchangeType).HasConversion<int>();
builder.Property(x => x.RequiredPoints).IsRequired();
builder.Property(x => x.CashAmount).HasPrecision(18, 2);
builder.Property(x => x.StockTotal).IsRequired();
builder.Property(x => x.StockAvailable).IsRequired();
builder.Property(x => x.PerMemberLimit);
builder.Property(x => x.NotifyChannelsJson).HasColumnType("text").IsRequired();
builder.Property(x => x.Status).HasConversion<int>();
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Status });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Name });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.ProductId });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.CouponTemplateId });
}
private static void ConfigureMemberPointMallRecord(EntityTypeBuilder<MemberPointMallRecord> builder)
{
builder.ToTable("member_point_mall_records");
builder.HasKey(x => x.Id);
builder.Property(x => x.StoreId).IsRequired();
builder.Property(x => x.RecordNo).HasMaxLength(32).IsRequired();
builder.Property(x => x.PointMallProductId).IsRequired();
builder.Property(x => x.MemberId).IsRequired();
builder.Property(x => x.MemberName).HasMaxLength(64).IsRequired();
builder.Property(x => x.MemberMobileMasked).HasMaxLength(32).IsRequired();
builder.Property(x => x.ProductName).HasMaxLength(128).IsRequired();
builder.Property(x => x.RedeemType).HasConversion<int>();
builder.Property(x => x.ExchangeType).HasConversion<int>();
builder.Property(x => x.UsedPoints).IsRequired();
builder.Property(x => x.CashAmount).HasPrecision(18, 2);
builder.Property(x => x.Status).HasConversion<int>();
builder.Property(x => x.RedeemedAt).IsRequired();
builder.Property(x => x.IssuedAt);
builder.Property(x => x.VerifiedAt);
builder.Property(x => x.VerifyMethod).HasConversion<int?>();
builder.Property(x => x.VerifyRemark).HasMaxLength(256);
builder.Property(x => x.VerifiedBy);
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.RecordNo }).IsUnique();
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.PointMallProductId, x.RedeemedAt });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.MemberId, x.RedeemedAt });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Status, x.RedeemedAt });
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.RedeemedAt });
}
private static void ConfigureMemberStoredCardPlan(EntityTypeBuilder<MemberStoredCardPlan> builder)
{
builder.ToTable("member_stored_card_plans");
@@ -2173,3 +2262,4 @@ public sealed class TakeoutAppDbContext(
builder.HasIndex(x => new { x.TenantId, x.QuotaPackageId, x.PurchasedAt });
}
}