Files
TakeoutSaaS.TenantApi/src/Application/TakeoutSaaS.Application/App/Customers/Dto/CustomerAnalysisDtos.cs

432 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace TakeoutSaaS.Application.App.Customers.Dto;
/// <summary>
/// 客户分析增长趋势点 DTO。
/// </summary>
public sealed class CustomerAnalysisTrendPointDto
{
/// <summary>
/// 维度标签。
/// </summary>
public string Label { get; init; } = string.Empty;
/// <summary>
/// 数量值。
/// </summary>
public int Value { get; init; }
}
/// <summary>
/// 客户分析新老客构成项 DTO。
/// </summary>
public sealed class CustomerAnalysisCompositionItemDto
{
/// <summary>
/// 分群编码。
/// </summary>
public string SegmentCode { get; init; } = string.Empty;
/// <summary>
/// 分群名称。
/// </summary>
public string Label { get; init; } = string.Empty;
/// <summary>
/// 分群人数。
/// </summary>
public int Count { get; init; }
/// <summary>
/// 分群占比(百分比)。
/// </summary>
public decimal Percent { get; init; }
/// <summary>
/// 色调blue/green/orange/gray
/// </summary>
public string Tone { get; init; } = "blue";
}
/// <summary>
/// 客单价分布项 DTO。
/// </summary>
public sealed class CustomerAnalysisAmountDistributionItemDto
{
/// <summary>
/// 分群编码。
/// </summary>
public string SegmentCode { get; init; } = string.Empty;
/// <summary>
/// 区间标签。
/// </summary>
public string Label { get; init; } = string.Empty;
/// <summary>
/// 人数。
/// </summary>
public int Count { get; init; }
/// <summary>
/// 占比(百分比)。
/// </summary>
public decimal Percent { get; init; }
}
/// <summary>
/// RFM 分层单元 DTO。
/// </summary>
public sealed class CustomerAnalysisRfmCellDto
{
/// <summary>
/// 分群编码。
/// </summary>
public string SegmentCode { get; init; } = string.Empty;
/// <summary>
/// 分层标签。
/// </summary>
public string Label { get; init; } = string.Empty;
/// <summary>
/// 人数。
/// </summary>
public int Count { get; init; }
/// <summary>
/// 温度hot/warm/cool/cold
/// </summary>
public string Tone { get; init; } = "cold";
}
/// <summary>
/// RFM 分层行 DTO。
/// </summary>
public sealed class CustomerAnalysisRfmRowDto
{
/// <summary>
/// 行标签。
/// </summary>
public string Label { get; init; } = string.Empty;
/// <summary>
/// 单元格集合。
/// </summary>
public IReadOnlyList<CustomerAnalysisRfmCellDto> Cells { get; init; } = [];
}
/// <summary>
/// 高价值客户 DTO。
/// </summary>
public sealed class CustomerAnalysisTopCustomerDto
{
/// <summary>
/// 排名。
/// </summary>
public int Rank { get; init; }
/// <summary>
/// 客户标识。
/// </summary>
public string CustomerKey { get; init; } = string.Empty;
/// <summary>
/// 客户名称。
/// </summary>
public string Name { get; init; } = string.Empty;
/// <summary>
/// 手机号(脱敏)。
/// </summary>
public string PhoneMasked { get; init; } = string.Empty;
/// <summary>
/// 累计消费。
/// </summary>
public decimal TotalAmount { get; init; }
/// <summary>
/// 下单次数。
/// </summary>
public int OrderCount { get; init; }
/// <summary>
/// 客单价。
/// </summary>
public decimal AverageAmount { get; init; }
/// <summary>
/// 最近下单时间。
/// </summary>
public DateTime LastOrderAt { get; init; }
/// <summary>
/// 客户标签。
/// </summary>
public IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
}
/// <summary>
/// 客户分析总览 DTO。
/// </summary>
public sealed class CustomerAnalysisOverviewDto
{
/// <summary>
/// 统计周期编码。
/// </summary>
public string PeriodCode { get; init; } = "30d";
/// <summary>
/// 统计周期天数。
/// </summary>
public int PeriodDays { get; init; } = 30;
/// <summary>
/// 客户总数。
/// </summary>
public int TotalCustomers { get; init; }
/// <summary>
/// 周期新增客户数。
/// </summary>
public int NewCustomers { get; init; }
/// <summary>
/// 新增较上一周期增长百分比。
/// </summary>
public decimal GrowthRatePercent { get; init; }
/// <summary>
/// 周期内日均新增客户。
/// </summary>
public decimal NewCustomersDailyAverage { get; init; }
/// <summary>
/// 活跃客户数。
/// </summary>
public int ActiveCustomers { get; init; }
/// <summary>
/// 活跃率(百分比)。
/// </summary>
public decimal ActiveRatePercent { get; init; }
/// <summary>
/// 平均客户价值(累计消费均值)。
/// </summary>
public decimal AverageLifetimeValue { get; init; }
/// <summary>
/// 客户增长趋势。
/// </summary>
public IReadOnlyList<CustomerAnalysisTrendPointDto> GrowthTrend { get; init; } = [];
/// <summary>
/// 新老客占比。
/// </summary>
public IReadOnlyList<CustomerAnalysisCompositionItemDto> Composition { get; init; } = [];
/// <summary>
/// 客单价分布。
/// </summary>
public IReadOnlyList<CustomerAnalysisAmountDistributionItemDto> AmountDistribution { get; init; } = [];
/// <summary>
/// RFM 分层。
/// </summary>
public IReadOnlyList<CustomerAnalysisRfmRowDto> RfmRows { get; init; } = [];
/// <summary>
/// 高价值客户 Top10。
/// </summary>
public IReadOnlyList<CustomerAnalysisTopCustomerDto> TopCustomers { get; init; } = [];
}
/// <summary>
/// 客群明细行 DTO。
/// </summary>
public sealed class CustomerAnalysisSegmentListItemDto
{
/// <summary>
/// 客户标识。
/// </summary>
public string CustomerKey { get; init; } = string.Empty;
/// <summary>
/// 客户名称。
/// </summary>
public string Name { get; init; } = string.Empty;
/// <summary>
/// 手机号(脱敏)。
/// </summary>
public string PhoneMasked { get; init; } = string.Empty;
/// <summary>
/// 头像文案。
/// </summary>
public string AvatarText { get; init; } = string.Empty;
/// <summary>
/// 头像颜色。
/// </summary>
public string AvatarColor { get; init; } = string.Empty;
/// <summary>
/// 客户标签。
/// </summary>
public IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
/// <summary>
/// 是否会员。
/// </summary>
public bool IsMember { get; init; }
/// <summary>
/// 会员等级。
/// </summary>
public string MemberTierName { get; init; } = string.Empty;
/// <summary>
/// 累计消费。
/// </summary>
public decimal TotalAmount { get; init; }
/// <summary>
/// 下单次数。
/// </summary>
public int OrderCount { get; init; }
/// <summary>
/// 客单价。
/// </summary>
public decimal AverageAmount { get; init; }
/// <summary>
/// 注册时间。
/// </summary>
public DateTime RegisteredAt { get; init; }
/// <summary>
/// 最近下单时间。
/// </summary>
public DateTime LastOrderAt { get; init; }
/// <summary>
/// 是否弱化显示。
/// </summary>
public bool IsDimmed { get; init; }
}
/// <summary>
/// 客群明细结果 DTO。
/// </summary>
public sealed class CustomerAnalysisSegmentListResultDto
{
/// <summary>
/// 分群编码。
/// </summary>
public string SegmentCode { get; init; } = string.Empty;
/// <summary>
/// 分群标题。
/// </summary>
public string SegmentTitle { get; init; } = string.Empty;
/// <summary>
/// 分群说明。
/// </summary>
public string SegmentDescription { get; init; } = string.Empty;
/// <summary>
/// 列表项。
/// </summary>
public IReadOnlyList<CustomerAnalysisSegmentListItemDto> Items { get; init; } = [];
/// <summary>
/// 当前页。
/// </summary>
public int Page { get; init; }
/// <summary>
/// 每页条数。
/// </summary>
public int PageSize { get; init; }
/// <summary>
/// 总记录数。
/// </summary>
public int TotalCount { get; init; }
}
/// <summary>
/// 会员详情 DTO。
/// </summary>
public sealed class CustomerMemberDetailDto
{
/// <summary>
/// 客户标识。
/// </summary>
public string CustomerKey { get; init; } = string.Empty;
/// <summary>
/// 客户名称。
/// </summary>
public string Name { get; init; } = string.Empty;
/// <summary>
/// 手机号(脱敏)。
/// </summary>
public string PhoneMasked { get; init; } = string.Empty;
/// <summary>
/// 来源。
/// </summary>
public string Source { get; init; } = string.Empty;
/// <summary>
/// 注册时间。
/// </summary>
public DateTime RegisteredAt { get; init; }
/// <summary>
/// 最近下单时间。
/// </summary>
public DateTime LastOrderAt { get; init; }
/// <summary>
/// 会员摘要。
/// </summary>
public CustomerMemberSummaryDto Member { get; init; } = new();
/// <summary>
/// 客户标签。
/// </summary>
public IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
/// <summary>
/// 累计下单次数。
/// </summary>
public int TotalOrders { get; init; }
/// <summary>
/// 累计消费。
/// </summary>
public decimal TotalAmount { get; init; }
/// <summary>
/// 客单价。
/// </summary>
public decimal AverageAmount { get; init; }
/// <summary>
/// 复购率。
/// </summary>
public decimal RepurchaseRatePercent { get; init; }
/// <summary>
/// 最近订单。
/// </summary>
public IReadOnlyList<CustomerRecentOrderDto> RecentOrders { get; init; } = [];
}