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); } } }