feat(customer): 完成客户画像会员摘要与权限链路
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 2m2s
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 2m2s
This commit is contained in:
@@ -0,0 +1,462 @@
|
||||
namespace TakeoutSaaS.Application.App.Customers.Dto;
|
||||
|
||||
/// <summary>
|
||||
/// 客户标签 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerTagDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 标签编码。
|
||||
/// </summary>
|
||||
public string Code { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标签文案。
|
||||
/// </summary>
|
||||
public string Label { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标签色调(orange/blue/green/gray/red)。
|
||||
/// </summary>
|
||||
public string Tone { get; init; } = "blue";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户列表行 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerListItemDto
|
||||
{
|
||||
/// <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 int OrderCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 下单次数条形宽度百分比。
|
||||
/// </summary>
|
||||
public int OrderCountBarPercent { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计消费。
|
||||
/// </summary>
|
||||
public decimal TotalAmount { 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 IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 是否弱化展示。
|
||||
/// </summary>
|
||||
public bool IsDimmed { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户列表统计 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerListStatsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户总数。
|
||||
/// </summary>
|
||||
public int TotalCustomers { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 本月新增客户数。
|
||||
/// </summary>
|
||||
public int MonthlyNewCustomers { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 本月较上月增长百分比。
|
||||
/// </summary>
|
||||
public decimal MonthlyGrowthRatePercent { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 活跃客户数(近 30 天有下单)。
|
||||
/// </summary>
|
||||
public int ActiveCustomers { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 近 30 天客均消费(按订单均值)。
|
||||
/// </summary>
|
||||
public decimal AverageAmountLast30Days { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户偏好 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerPreferenceDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 偏好品类。
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> PreferredCategories { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 偏好下单时段。
|
||||
/// </summary>
|
||||
public string PreferredOrderPeaks { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 偏好履约方式。
|
||||
/// </summary>
|
||||
public string PreferredDelivery { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 偏好支付方式。
|
||||
/// </summary>
|
||||
public string PreferredPaymentMethod { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 平均配送距离文案。
|
||||
/// </summary>
|
||||
public string AverageDeliveryDistance { get; init; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户常购商品 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerTopProductDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 排名。
|
||||
/// </summary>
|
||||
public int Rank { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品名称。
|
||||
/// </summary>
|
||||
public string ProductName { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 购买次数。
|
||||
/// </summary>
|
||||
public int Count { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 占比(0-100)。
|
||||
/// </summary>
|
||||
public decimal ProportionPercent { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户趋势点 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerTrendPointDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 月份标签。
|
||||
/// </summary>
|
||||
public string Label { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 消费金额。
|
||||
/// </summary>
|
||||
public decimal Amount { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户最近订单 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerRecentOrderDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号。
|
||||
/// </summary>
|
||||
public string OrderNo { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 下单时间。
|
||||
/// </summary>
|
||||
public DateTime OrderedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单金额。
|
||||
/// </summary>
|
||||
public decimal Amount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品摘要。
|
||||
/// </summary>
|
||||
public string ItemsSummary { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 履约方式文案。
|
||||
/// </summary>
|
||||
public string DeliveryType { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 状态文案。
|
||||
/// </summary>
|
||||
public string Status { get; init; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户会员摘要 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerMemberSummaryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否会员。
|
||||
/// </summary>
|
||||
public bool IsMember { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 会员等级名称。
|
||||
/// </summary>
|
||||
public string TierName { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 积分余额。
|
||||
/// </summary>
|
||||
public int PointsBalance { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 成长值。
|
||||
/// </summary>
|
||||
public int GrowthValue { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 入会时间。
|
||||
/// </summary>
|
||||
public DateTime? JoinedAt { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户详情 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerDetailDto
|
||||
{
|
||||
/// <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 DateTime RegisteredAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 首次下单时间。
|
||||
/// </summary>
|
||||
public DateTime FirstOrderAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户来源。
|
||||
/// </summary>
|
||||
public string Source { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 客户标签。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 会员摘要。
|
||||
/// </summary>
|
||||
public CustomerMemberSummaryDto Member { get; init; } = new();
|
||||
|
||||
/// <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 CustomerPreferenceDto Preference { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 常购商品 Top 5。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTopProductDto> TopProducts { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 趋势数据。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTrendPointDto> Trend { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 最近订单。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerRecentOrderDto> RecentOrders { get; init; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户画像 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerProfileDto
|
||||
{
|
||||
/// <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 DateTime RegisteredAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 首次下单时间。
|
||||
/// </summary>
|
||||
public DateTime FirstOrderAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户来源。
|
||||
/// </summary>
|
||||
public string Source { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 客户标签。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTagDto> Tags { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 会员摘要。
|
||||
/// </summary>
|
||||
public CustomerMemberSummaryDto Member { get; init; } = new();
|
||||
|
||||
/// <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 decimal AverageOrderIntervalDays { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 偏好数据。
|
||||
/// </summary>
|
||||
public CustomerPreferenceDto Preference { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 常购商品 Top 5。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTopProductDto> TopProducts { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 趋势数据。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerTrendPointDto> Trend { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 最近订单。
|
||||
/// </summary>
|
||||
public IReadOnlyList<CustomerRecentOrderDto> RecentOrders { get; init; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户导出 DTO。
|
||||
/// </summary>
|
||||
public sealed class CustomerExportDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件名。
|
||||
/// </summary>
|
||||
public string FileName { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 文件 Base64。
|
||||
/// </summary>
|
||||
public string FileContentBase64 { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 导出总数。
|
||||
/// </summary>
|
||||
public int TotalCount { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user