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

400 lines
12 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 列表;空/Null 表示全部店铺</summary>
public List<string> ShopKeys { get; set; }
}
/// <summary>
/// 店铺营收统计 - 接口返回的原始明细行。
/// 与后端 WXOrderAmountInfo 保持一致(camelCase JSON):
/// shopName, createTime, orderId, status, productPrice, orderPrice, purchasePrice, freight,
/// predictCommissionFee, commissionAmount, discountedPrice, profit, purchaseStatus,
/// outAmount, refundStatus, refundStatusString, refundAmount, externalProcurement
/// 金额字段单位均为分(显示时需除以 100)。
/// </summary>
public class ShopRevenueStatisticsRow
{
/// <summary>
/// 店铺名称
/// </summary>
[JsonProperty("shop_name")]
public string ShopName { get; set; }
/// <summary>
/// 下单时间(秒级时间戳)
/// </summary>
[JsonProperty("create_time")]
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime CreateTime { get; set; }
/// <summary>
/// 订单号
/// </summary>
[JsonProperty("order_id")]
public string OrderId { get; set; }
/// <summary>
/// 订单状态
/// </summary>
[JsonProperty("status")]
public int Status { get; set; }
/// <summary>
/// 商品总价(分)
/// </summary>
[JsonProperty("product_price")]
public int ProductPrice { get; set; }
/// <summary>
/// 订单金额(分)
/// </summary>
[JsonProperty("order_price")]
public int OrderPrice { get; set; }
/// <summary>
/// 采购价(分)
/// </summary>
[JsonProperty("purchase_price")]
public int PurchasePrice { get; set; }
/// <summary>
/// 运费(分)
/// </summary>
[JsonProperty("freight")]
public int Freight { get; set; }
/// <summary>
/// 平台服务费(预计技术服务费,分)
/// </summary>
[JsonProperty("predict_commission_fee")]
public int PredictCommissionFee { get; set; }
/// <summary>
/// 达人佣金(分)
/// </summary>
[JsonProperty("commission_amount")]
public int CommissionAmount { get; set; }
/// <summary>
/// 优惠金额(分)
/// </summary>
[JsonProperty("discounted_price")]
public int DiscountedPrice { get; set; }
/// <summary>
/// 利润(分)
/// </summary>
[JsonProperty("profit")]
public int Profit { get; set; }
/// <summary>
/// 采购状态
/// </summary>
[JsonProperty("purchase_status")]
public int PurchaseStatus { get; set; }
/// <summary>
/// 外采金额(分),out_amount为空或0时从中转仓订单表补全
/// </summary>
[JsonProperty("out_amount")]
public int OutAmount { get; set; }
/// <summary>
/// 售后状态(订单明细 refund_status)
/// </summary>
[JsonProperty("refund_status")]
public int RefundStatus { get; set; }
/// <summary>
/// 售后状态(退款单 status)
/// </summary>
[JsonProperty("refund_status_string")]
public string RefundStatusString { get; set; }
/// <summary>
/// 售后退款金额(分)
/// </summary>
[JsonProperty("refund_amount")]
public int RefundAmount { get; set; }
/// <summary>
/// 是否外采:0=未从中转仓订单表查到,1=查到
/// </summary>
[JsonProperty("external_procurement")]
public int ExternalProcurement { get; set; }
/// <summary>
/// 买手退款金额
/// </summary>
[JsonProperty("buyer_refund_amount")]
public int BuyerRefundAmount { get; set; }
/// <summary>
/// 买手退款状态
/// </summary>
[JsonProperty("buyer_refund_status")]
public string BuyerRefundStatus { 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 RefundOrderCount { get; set; }
/// <summary>平台服务费总额(元)</summary>
public decimal PlatformFeeTotal { get; set; }
/// <summary>达人佣金(元)</summary>
public decimal Commission { get; set; }
/// <summary>客单价(平均每单金额)</summary>
public decimal AvgOrderAmount { get; set; }
/// <summary>退款率(退款订单占比,百分数,如 2.31 表示 2.31%)</summary>
public decimal RefundRate { get; set; }
/// <summary>平均利润率(利润 / 采购金额,百分数,如 12.34 表示 12.34%)</summary>
public decimal AverageProfitRate { get; set; }
/// <summary>买手号付款金额(采购金额,元)</summary>
public decimal BuyerPaymentAmount { get; set; }
/// <summary>买手号退款金额(采购退款金额,元)</summary>
public decimal BuyerRefundAmount { get; set; }
/// <summary>买手号退款成功金额(采购退款金额,元)</summary>
public decimal BuyerRefundSuccessedAmount { get; set; }
/// <summary>买手号剩余退款金额(尚未成功退款的金额,元)</summary>
public decimal BuyerRefundRemainingAmount => BuyerRefundAmount - BuyerRefundSuccessedAmount;
}
/// <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 BuyerPaymentAmount { get; set; }
/// <summary>利润(元)</summary>
public decimal Profit { get; set; }
/// <summary>退款金额(元)</summary>
public decimal RefundAmount { get; set; }
/// <summary>平台服务费总额(元)</summary>
public decimal PlatformFeeTotal { get; set; }
/// <summary>达人佣金(元)</summary>
public decimal Commission { get; set; }
/// <summary>客单价(元)</summary>
public decimal AvgOrderAmount { get; set; }
/// <summary>平均利润率(利润 / 采购金额,百分数,如 12.34 表示 12.34%)</summary>
public decimal AverageProfitRate { 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 BuyerPaymentAmount { get; set; }
/// <summary>利润(元)</summary>
public decimal Profit { get; set; }
/// <summary>退款金额(元)</summary>
public decimal RefundAmount { get; set; }
/// <summary>平台服务费总额(元)</summary>
public decimal PlatformFeeTotal { get; set; }
/// <summary>达人佣金(元)</summary>
public decimal Commission { get; set; }
/// <summary>平均利润率(利润 / 采购金额,百分数,如 12.34 表示 12.34%)</summary>
public decimal AverageProfitRate { 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; }
public string ShopId { 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);
DateTime epoch = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
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);
DateTime epoch = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
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);
DateTime epoch = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long milliseconds = (long)((DateTime)value - epoch).TotalMilliseconds;
writer.WriteValue(milliseconds);
}
}
}