feat: implement tenant member stored card module
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 2m24s
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 2m24s
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
using TakeoutSaaS.Domain.Membership.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Membership.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 会员储值卡充值方案。
|
||||
/// </summary>
|
||||
public sealed class MemberStoredCardPlan : MultiTenantEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店标识。
|
||||
/// </summary>
|
||||
public long StoreId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值金额。
|
||||
/// </summary>
|
||||
public decimal RechargeAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 赠送金额。
|
||||
/// </summary>
|
||||
public decimal GiftAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序值(越小越靠前)。
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 启用状态。
|
||||
/// </summary>
|
||||
public MemberStoredCardPlanStatus Status { get; set; } = MemberStoredCardPlanStatus.Enabled;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using TakeoutSaaS.Domain.Payments.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Membership.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 会员储值卡充值记录。
|
||||
/// </summary>
|
||||
public sealed class MemberStoredCardRechargeRecord : MultiTenantEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店标识。
|
||||
/// </summary>
|
||||
public long StoreId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会员标识。
|
||||
/// </summary>
|
||||
public long MemberId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值方案标识(可空,表示非方案充值)。
|
||||
/// </summary>
|
||||
public long? PlanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值单号。
|
||||
/// </summary>
|
||||
public string RecordNo { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 会员名称快照。
|
||||
/// </summary>
|
||||
public string MemberName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 会员手机号快照(脱敏)。
|
||||
/// </summary>
|
||||
public string MemberMobileMasked { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 充值金额。
|
||||
/// </summary>
|
||||
public decimal RechargeAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 赠送金额。
|
||||
/// </summary>
|
||||
public decimal GiftAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 到账金额(充值+赠送)。
|
||||
/// </summary>
|
||||
public decimal ArrivedAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付方式。
|
||||
/// </summary>
|
||||
public PaymentMethod PaymentMethod { get; set; } = PaymentMethod.Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
public string? Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值时间(UTC)。
|
||||
/// </summary>
|
||||
public DateTime RechargedAt { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace TakeoutSaaS.Domain.Membership.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 储值卡方案状态。
|
||||
/// </summary>
|
||||
public enum MemberStoredCardPlanStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 已停用。
|
||||
/// </summary>
|
||||
Disabled = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 已启用。
|
||||
/// </summary>
|
||||
Enabled = 1
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using TakeoutSaaS.Domain.Membership.Entities;
|
||||
using TakeoutSaaS.Domain.Membership.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Membership.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// 储值卡模块仓储契约。
|
||||
/// </summary>
|
||||
public interface IStoredCardRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询门店下全部储值方案。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MemberStoredCardPlan>> GetPlansByStoreAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 按标识查询储值方案。
|
||||
/// </summary>
|
||||
Task<MemberStoredCardPlan?> FindPlanByIdAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
long planId,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 新增储值方案。
|
||||
/// </summary>
|
||||
Task AddPlanAsync(MemberStoredCardPlan entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 更新储值方案。
|
||||
/// </summary>
|
||||
Task UpdatePlanAsync(MemberStoredCardPlan entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 删除储值方案。
|
||||
/// </summary>
|
||||
Task DeletePlanAsync(MemberStoredCardPlan entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 按方案聚合充值次数与金额。
|
||||
/// </summary>
|
||||
Task<Dictionary<long, MemberStoredCardPlanAggregateSnapshot>> GetPlanAggregatesAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
IReadOnlyCollection<long> planIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 获取储值方案页统计快照。
|
||||
/// </summary>
|
||||
Task<MemberStoredCardPlanStatsSnapshot> GetPlanStatsAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
DateTime nowUtc,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 查询充值记录分页。
|
||||
/// </summary>
|
||||
Task<(IReadOnlyList<MemberStoredCardRechargeRecord> Items, int TotalCount)> SearchRechargeRecordsAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
DateTime? startUtc,
|
||||
DateTime? endUtc,
|
||||
string? keyword,
|
||||
int page,
|
||||
int pageSize,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 查询充值记录导出数据。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MemberStoredCardRechargeRecord>> ListRechargeRecordsForExportAsync(
|
||||
long tenantId,
|
||||
long storeId,
|
||||
DateTime? startUtc,
|
||||
DateTime? endUtc,
|
||||
string? keyword,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 新增充值记录。
|
||||
/// </summary>
|
||||
Task AddRechargeRecordAsync(MemberStoredCardRechargeRecord entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 持久化变更。
|
||||
/// </summary>
|
||||
Task SaveChangesAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 储值方案聚合快照。
|
||||
/// </summary>
|
||||
public sealed record MemberStoredCardPlanAggregateSnapshot
|
||||
{
|
||||
/// <summary>
|
||||
/// 方案标识。
|
||||
/// </summary>
|
||||
public required long PlanId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值次数。
|
||||
/// </summary>
|
||||
public int RechargeCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值总额。
|
||||
/// </summary>
|
||||
public decimal TotalRechargeAmount { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 储值卡统计快照。
|
||||
/// </summary>
|
||||
public sealed record MemberStoredCardPlanStatsSnapshot
|
||||
{
|
||||
/// <summary>
|
||||
/// 储值总额。
|
||||
/// </summary>
|
||||
public decimal TotalRechargeAmount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 赠金总额。
|
||||
/// </summary>
|
||||
public decimal TotalGiftAmount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 本月充值额。
|
||||
/// </summary>
|
||||
public decimal CurrentMonthRechargeAmount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 储值用户数。
|
||||
/// </summary>
|
||||
public int RechargeMemberCount { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user