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