Files
29WxOrder/29WxOrderWpf/Ctrls/Statistics/Models/ShopRevenueStatisticsModels.cs
T

302 lines
9.6 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.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace _29WxOrderWpf.Ctrls.Statistics.Models
{
/// <summary>
/// 店铺营收统计 - 查询参数
/// </summary>
public class ShopRevenueStatisticsQuery
{
/// <summary>开始时间</summary>
public DateTime StartDate { get; set; }
/// <summary>结束时间</summary>
public DateTime EndDate { get; set; }
/// <summary>店铺 app_key(A.app_key),空/Null 表示全部店铺</summary>
public string ShopKey { get; set; }
}
/// <summary>
/// 店铺营收统计 - 接口返回的原始明细行。
/// 对应接口返回字段:
/// A.app_key, B.create_time, B.order_id, B.status,
/// B.product_price, B.order_price, B.purchase_price, B.freight,
/// B.predict_commission_fee, B.commission_amount, B.discounted_price, B.profit,
/// B.purchase_status, c.refund_status
/// 其中 A 为店铺表,B 为订单表,c 为售后/退款表。
/// 金额字段单位均为“分”,展示时需除以 100。
/// </summary>
public class ShopRevenueStatisticsRow
{
/// <summary>A.app_key 店铺 app_key</summary>
[JsonProperty("app_key")]
public string AppKey { get; set; }
/// <summary>B.create_time 订单创建时间(接口为秒级时间戳,由 UnixDateTimeConverter 转换为 DateTime)</summary>
[JsonProperty("create_time")]
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime CreateTime { get; set; }
/// <summary>B.order_id 订单号</summary>
[JsonProperty("order_id")]
public string OrderId { get; set; }
/// <summary>B.status 订单状态:10-待付款;20-待发货;21-部分发货;30-待收货;100-完成;200-全部商品售后之后订单取消;250-未付款用户主动取消或超时未付款订单自动取消</summary>
public int Status { get; set; }
/// <summary>B.product_price 商品总价(分)</summary>
[JsonProperty("product_price")]
public int ProductPrice { get; set; }
/// <summary>B.order_price 订单金额(分),计算公式:order_price = original_order_price - discounted_price - deduction_price - change_down_price</summary>
[JsonProperty("order_price")]
public int OrderPrice { get; set; }
/// <summary>B.purchase_price 采购价(分)</summary>
[JsonProperty("purchase_price")]
public int PurchasePrice { get; set; }
/// <summary>B.freight 运费(分)</summary>
public int Freight { get; set; }
/// <summary>B.predict_commission_fee 平台服务费(微信小店:预计技术服务费)(分)</summary>
[JsonProperty("predict_commission_fee")]
public int PredictCommissionFee { get; set; }
/// <summary>B.commission_amount 达人佣金(微信小店:分账金额)(分)</summary>
[JsonProperty("commission_amount")]
public int CommissionAmount { get; set; }
/// <summary>B.discounted_price 优惠券优惠金额(分)</summary>
[JsonProperty("discounted_price")]
public int DiscountedPrice { get; set; }
/// <summary>B.profit 利润(分),计算公式:实付金额 - 采购价 - 平台服务费 - 达人佣金(采购价、达人佣金为空值则按 0)</summary>
public int Profit { get; set; }
/// <summary>B.purchase_status 采购状态:0-未采购;1-采购(默认值 0,推送仓库时修改为 1)</summary>
[JsonProperty("purchase_status")]
public int PurchaseStatus { get; set; }
/// <summary>c.refund_status 退款状态(4/11 视为已退款,与 RevenueStatisticsAggregator.IsRefunded 保持一致)</summary>
[JsonProperty("refund_status")]
public int RefundStatus { get; set; }
/// <summary>店铺名称(由 app_key 关联店铺表得到,展示用,非接口原始字段)</summary>
[JsonProperty("shop_name")]
public string ShopName { get; set; }
}
/// <summary>
/// 顶部汇总卡片数据(金额单位:元)
/// </summary>
public class ShopRevenueSummary
{
/// <summary>销售额(最终有效销售额)</summary>
public decimal SalesAmount { get; set; }
/// <summary>有效订单数(已扣除退款订单)</summary>
public int ValidOrderCount { get; set; }
/// <summary>利润(实际利润)</summary>
public decimal Profit { get; set; }
/// <summary>退款金额(统计期间退款)</summary>
public decimal RefundAmount { get; set; }
/// <summary>商品销量(有效销量)</summary>
public int ProductSalesVolume { get; set; }
/// <summary>客户数(成交客户)</summary>
public int CustomerCount { get; set; }
/// <summary>客单价(平均每单金额)</summary>
public decimal AvgOrderAmount { get; set; }
/// <summary>退款率(退款订单占比,百分数,如 2.31 表示 2.31%)</summary>
public decimal RefundRate { get; set; }
}
/// <summary>
/// 销售趋势数据点(金额单位:元)
/// </summary>
public class RevenueTrendPoint
{
/// <summary>日期</summary>
public DateTime Date { get; set; }
/// <summary>日期文本(MM-dd)</summary>
public string DateText { get { return Date.ToString("MM-dd"); } }
/// <summary>当日销售额(元)</summary>
public decimal SalesAmount { get; set; }
/// <summary>当日有效订单数</summary>
public int OrderCount { get; set; }
}
/// <summary>
/// 店铺销售占比数据(金额单位:元)
/// </summary>
public class ShopSalesProportionItem
{
/// <summary>店铺名称</summary>
public string ShopName { get; set; }
/// <summary>销售额(元)</summary>
public decimal SalesAmount { get; set; }
/// <summary>占比(0~100)</summary>
public double Percentage { get; set; }
}
/// <summary>
/// 店铺统计表格行(金额单位:元)
/// </summary>
public class ShopStatisticsItem
{
/// <summary>店铺名称</summary>
public string ShopName { get; set; }
/// <summary>订单数</summary>
public int OrderCount { get; set; }
/// <summary>销售额(元)</summary>
public decimal SalesAmount { get; set; }
/// <summary>利润(元)</summary>
public decimal Profit { get; set; }
/// <summary>退款金额(元)</summary>
public decimal RefundAmount { get; set; }
/// <summary>客户数</summary>
public int CustomerCount { get; set; }
/// <summary>客单价(元)</summary>
public decimal AvgOrderAmount { get; set; }
}
/// <summary>
/// 统计周期类型:天 / 周 / 月
/// </summary>
public enum PeriodStatisticType
{
/// <summary>按天统计</summary>
Day = 0,
/// <summary>按周统计(周一起始)</summary>
Week = 1,
/// <summary>按月统计</summary>
Month = 2
}
/// <summary>
/// 天/周/月周期统计表格行(金额单位:元)。
/// 按所选店铺(或全部店铺)统计:天统计每天一行;周统计每周一行;月统计每月一行。
/// </summary>
public class ShopPeriodStatisticsItem
{
/// <summary>周期开始日期(用于排序)</summary>
public DateTime PeriodStart { get; set; }
/// <summary>周期显示文本(天:yyyy-MM-dd;周:yyyy-MM-dd ~ yyyy-MM-dd;月:yyyy-MM)</summary>
public string Period { get; set; }
/// <summary>订单数</summary>
public int OrderCount { get; set; }
/// <summary>销售额(元)</summary>
public decimal SalesAmount { get; set; }
/// <summary>利润(元)</summary>
public decimal Profit { get; set; }
/// <summary>退款金额(元)</summary>
public decimal RefundAmount { get; set; }
/// <summary>客户数</summary>
public int CustomerCount { get; set; }
/// <summary>客单价(元)</summary>
public decimal AvgOrderAmount { get; set; }
}
/// <summary>
/// 店铺下拉选项
/// </summary>
public class ShopOption
{
/// <summary>店铺 app_key(A.app_key)</summary>
public string AppKey { get; set; }
/// <summary>店铺名称</summary>
public string ShopName { get; set; }
}
/// <summary>
/// 时间范围下拉选项
/// </summary>
public class TimeRangeOption
{
/// <summary>显示文本(如:今天、昨天、本周、本月、最近10天、自定义)</summary>
public string Text { get; set; }
/// <summary>值(today / yesterday / week / month / last10 / custom)</summary>
public string Value { get; set; }
}
class UnixDateTimeConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// 读取数值(支持 long 和 int 类型)
if (reader.TokenType == JsonToken.Integer)
{
long milliseconds = (long)reader.Value;
// Unix 纪元:1970-01-01 UTC
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
if (milliseconds.ToString().Length == 13)
{
return epoch.AddMilliseconds(milliseconds);
}
return epoch.AddSeconds(milliseconds);
}
// 如果传入的是字符串(如 "1700000000000"),也支持
else if (reader.TokenType == JsonToken.String)
{
if (long.TryParse((string)reader.Value, out long milliseconds))
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
if (milliseconds.ToString().Length == 13)
{
return epoch.AddMilliseconds(milliseconds);
}
return epoch.AddSeconds(milliseconds);
}
}
throw new JsonSerializationException($"无法将 {reader.Value} 转换为 DateTime");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// 序列化时转回时间戳
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long milliseconds = (long)((DateTime)value - epoch).TotalMilliseconds;
writer.WriteValue(milliseconds);
}
}
}