302 lines
9.6 KiB
C#
302 lines
9.6 KiB
C#
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);
|
||
}
|
||
}
|
||
} |