feat(member): implement points mall backend module

This commit is contained in:
2026-03-04 12:15:18 +08:00
parent 2970134200
commit bd418c5927
53 changed files with 5193 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换商品数据。
/// </summary>
public sealed class MemberPointMallProductDto
{
/// <summary>
/// 积分商城商品标识。
/// </summary>
public long PointMallProductId { get; set; }
/// <summary>
/// 门店标识。
/// </summary>
public long StoreId { get; set; }
/// <summary>
/// 展示名称。
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 展示图片。
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 兑换类型编码product/coupon/physical
/// </summary>
public string RedeemType { get; set; } = "product";
/// <summary>
/// 关联商品 ID。
/// </summary>
public long? ProductId { get; set; }
/// <summary>
/// 关联优惠券模板 ID。
/// </summary>
public long? CouponTemplateId { get; set; }
/// <summary>
/// 实物名称。
/// </summary>
public string? PhysicalName { get; set; }
/// <summary>
/// 领取方式编码store_pickup/delivery
/// </summary>
public string? PickupMethod { get; set; }
/// <summary>
/// 商品描述。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 兑换方式编码points/mixed
/// </summary>
public string ExchangeType { get; set; } = "points";
/// <summary>
/// 所需积分。
/// </summary>
public int RequiredPoints { get; set; }
/// <summary>
/// 现金部分。
/// </summary>
public decimal CashAmount { get; set; }
/// <summary>
/// 初始库存。
/// </summary>
public int StockTotal { get; set; }
/// <summary>
/// 剩余库存。
/// </summary>
public int StockAvailable { get; set; }
/// <summary>
/// 已兑换数量。
/// </summary>
public int RedeemedCount { get; set; }
/// <summary>
/// 每人限兑次数。
/// </summary>
public int? PerMemberLimit { get; set; }
/// <summary>
/// 通知渠道列表in_app/sms
/// </summary>
public IReadOnlyList<string> NotifyChannels { get; set; } = [];
/// <summary>
/// 状态enabled/disabled
/// </summary>
public string Status { get; set; } = "enabled";
/// <summary>
/// 更新时间UTC
/// </summary>
public DateTime UpdatedAt { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换商品列表结果。
/// </summary>
public sealed class MemberPointMallProductListResultDto
{
/// <summary>
/// 列表项。
/// </summary>
public IReadOnlyList<MemberPointMallProductDto> Items { get; set; } = [];
}

View File

@@ -0,0 +1,22 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换记录详情数据。
/// </summary>
public sealed class MemberPointMallRecordDetailDto : MemberPointMallRecordDto
{
/// <summary>
/// 核销方式scan/manual
/// </summary>
public string? VerifyMethod { get; set; }
/// <summary>
/// 核销备注。
/// </summary>
public string? VerifyRemark { get; set; }
/// <summary>
/// 核销人标识。
/// </summary>
public long? VerifiedBy { get; set; }
}

View File

@@ -0,0 +1,82 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换记录数据。
/// </summary>
public class MemberPointMallRecordDto
{
/// <summary>
/// 兑换记录标识。
/// </summary>
public long RecordId { get; set; }
/// <summary>
/// 兑换单号。
/// </summary>
public string RecordNo { get; set; } = string.Empty;
/// <summary>
/// 积分商城商品标识。
/// </summary>
public long PointMallProductId { get; set; }
/// <summary>
/// 商品名称。
/// </summary>
public string ProductName { get; set; } = string.Empty;
/// <summary>
/// 兑换类型product/coupon/physical
/// </summary>
public string RedeemType { get; set; } = "product";
/// <summary>
/// 兑换方式points/mixed
/// </summary>
public string ExchangeType { get; set; } = "points";
/// <summary>
/// 会员标识。
/// </summary>
public long MemberId { get; set; }
/// <summary>
/// 会员名称。
/// </summary>
public string MemberName { get; set; } = string.Empty;
/// <summary>
/// 会员手机号(脱敏)。
/// </summary>
public string MemberMobileMasked { get; set; } = string.Empty;
/// <summary>
/// 消耗积分。
/// </summary>
public int UsedPoints { get; set; }
/// <summary>
/// 现金部分。
/// </summary>
public decimal CashAmount { get; set; }
/// <summary>
/// 记录状态pending_pickup/issued/completed/canceled
/// </summary>
public string Status { get; set; } = "issued";
/// <summary>
/// 兑换时间UTC
/// </summary>
public DateTime RedeemedAt { get; set; }
/// <summary>
/// 发放时间UTC
/// </summary>
public DateTime? IssuedAt { get; set; }
/// <summary>
/// 核销时间UTC
/// </summary>
public DateTime? VerifiedAt { get; set; }
}

View File

@@ -0,0 +1,22 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换记录导出结果。
/// </summary>
public sealed class MemberPointMallRecordExportDto
{
/// <summary>
/// 文件名。
/// </summary>
public string FileName { get; set; } = string.Empty;
/// <summary>
/// Base64 文件内容。
/// </summary>
public string FileContentBase64 { get; set; } = string.Empty;
/// <summary>
/// 导出总条数。
/// </summary>
public int TotalCount { get; set; }
}

View File

@@ -0,0 +1,32 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换记录列表结果。
/// </summary>
public sealed class MemberPointMallRecordListResultDto
{
/// <summary>
/// 列表项。
/// </summary>
public IReadOnlyList<MemberPointMallRecordDto> Items { get; set; } = [];
/// <summary>
/// 页码。
/// </summary>
public int Page { get; set; }
/// <summary>
/// 每页条数。
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 总条数。
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// 页面统计。
/// </summary>
public MemberPointMallRecordStatsDto Stats { get; set; } = new();
}

View File

@@ -0,0 +1,22 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分商城兑换记录页统计。
/// </summary>
public sealed class MemberPointMallRecordStatsDto
{
/// <summary>
/// 今日兑换。
/// </summary>
public int TodayRedeemCount { get; set; }
/// <summary>
/// 待领取实物。
/// </summary>
public int PendingPhysicalCount { get; set; }
/// <summary>
/// 本月消耗积分。
/// </summary>
public int CurrentMonthUsedPoints { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分规则页详情结果。
/// </summary>
public sealed class MemberPointMallRuleDetailResultDto
{
/// <summary>
/// 规则配置。
/// </summary>
public MemberPointMallRuleDto Rule { get; set; } = new();
/// <summary>
/// 统计数据。
/// </summary>
public MemberPointMallRuleStatsDto Stats { get; set; } = new();
}

View File

@@ -0,0 +1,62 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分规则数据。
/// </summary>
public sealed class MemberPointMallRuleDto
{
/// <summary>
/// 门店标识。
/// </summary>
public long StoreId { get; set; }
/// <summary>
/// 是否启用消费获取。
/// </summary>
public bool IsConsumeRewardEnabled { get; set; }
/// <summary>
/// 每消费多少元触发一次积分计算。
/// </summary>
public int ConsumeAmountPerStep { get; set; }
/// <summary>
/// 每步获得积分。
/// </summary>
public int ConsumeRewardPointsPerStep { get; set; }
/// <summary>
/// 是否启用评价奖励。
/// </summary>
public bool IsReviewRewardEnabled { get; set; }
/// <summary>
/// 评价奖励积分。
/// </summary>
public int ReviewRewardPoints { get; set; }
/// <summary>
/// 是否启用注册奖励。
/// </summary>
public bool IsRegisterRewardEnabled { get; set; }
/// <summary>
/// 注册奖励积分。
/// </summary>
public int RegisterRewardPoints { get; set; }
/// <summary>
/// 是否启用签到奖励。
/// </summary>
public bool IsSigninRewardEnabled { get; set; }
/// <summary>
/// 签到奖励积分。
/// </summary>
public int SigninRewardPoints { get; set; }
/// <summary>
/// 有效期模式permanent/yearly_clear
/// </summary>
public string ExpiryMode { get; set; } = "yearly_clear";
}

View File

@@ -0,0 +1,27 @@
namespace TakeoutSaaS.Application.App.Members.PointsMall.Dto;
/// <summary>
/// 积分规则页统计数据。
/// </summary>
public sealed class MemberPointMallRuleStatsDto
{
/// <summary>
/// 累计发放积分。
/// </summary>
public int TotalIssuedPoints { get; set; }
/// <summary>
/// 已兑换积分。
/// </summary>
public int RedeemedPoints { get; set; }
/// <summary>
/// 积分用户。
/// </summary>
public int PointMembers { get; set; }
/// <summary>
/// 兑换率0-100
/// </summary>
public decimal RedeemRate { get; set; }
}