diff --git a/KJD_WebService/Model/WxModel/ShopRevenueStatistics.cs b/KJD_WebService/Model/WxModel/ShopRevenueStatistics.cs
index cb2c464..728a3b8 100644
--- a/KJD_WebService/Model/WxModel/ShopRevenueStatistics.cs
+++ b/KJD_WebService/Model/WxModel/ShopRevenueStatistics.cs
@@ -157,6 +157,11 @@ public class ShopRevenueStatistics
{
public long Id { get; set; }
///
+ /// 是否有效订单
+ /// 主订单未退款采用的买手订单
+ ///
+ public bool IsValid { get; set; }
+ ///
/// 采购类型
///
public PurchaseType PurchaseType { get; set; }
diff --git a/KJD_WebService/Services/Shops/ShopRevenueStatisticsService.cs b/KJD_WebService/Services/Shops/ShopRevenueStatisticsService.cs
index 2379c88..b20a29f 100644
--- a/KJD_WebService/Services/Shops/ShopRevenueStatisticsService.cs
+++ b/KJD_WebService/Services/Shops/ShopRevenueStatisticsService.cs
@@ -196,8 +196,8 @@ public class ShopRevenueStatisticsService : ITransientDependency
if (orders.Count == 0) return result;
// 加载买手订单(直拍和中转仓都要查),并回填商铺订单的退款金额
- LoadBuyerOrder(orders);
FillRefunds(orders);
+ LoadBuyerOrder(orders);
CalcProfit(orders);
foreach (var order in orders)
@@ -337,8 +337,8 @@ public class ShopRevenueStatisticsService : ITransientDependency
{
var orders = LoadOrders(date, shopId);
- LoadBuyerOrder(orders);
FillRefunds(orders);
+ LoadBuyerOrder(orders);
CalcProfit(orders);
SaveShopStats(date.Date, orders);
@@ -649,6 +649,15 @@ public class ShopRevenueStatisticsService : ITransientDependency
if (orders[i].BuyerOrders.Count == 0)
orders.RemoveAt(i);
}
+ //设置有效订单
+ foreach (var o in orders)
+ {
+ if (o.HasRefund == false)
+ {
+ if (o.BuyerOrders.Count > 0)
+ o.BuyerOrders.Last().IsValid = true;
+ }
+ }
}
/// 回填商铺订单的退款信息
@@ -763,31 +772,39 @@ public class ShopRevenueStatisticsService : ITransientDependency
// 按店铺分组,每个店铺下展开所有买手订单
foreach (var shopGroup in orders.GroupBy(o => o.ShopId))
{
- var buyerOrders = shopGroup
- .Where(o => o.BuyerOrders != null)
- .SelectMany(o => o.BuyerOrders)
- .ToList();
+ var valid = shopGroup.Where(a => !a.HasRefund).ToList();
+ var afterSale = shopGroup.Where(a => a.HasRefund).ToList();
- if (buyerOrders.Count == 0) continue;
- // 该店铺当天没有采购单,不写入
- // 同一个外部订单可能有多条记录,按 OutOrderSn 再分组
- // OutOrderSn 为空时用 SkuId 兜底,避免多个空单号被合并成一个
- var outOrderGroups = buyerOrders
+ // 有效订单:每单只有一条 IsValid 的采购单
+ var validBuyerOrders = valid
+ .Where(o => o.BuyerOrders != null)
+ .Select(o => o.BuyerOrders.FirstOrDefault(b => b.IsValid))
+ .Where(b => b != null)
+ .ToList();
+
+ // 售后订单下的采购单,按外部订单分组
+ var afterSaleGroups = afterSale
+ .Where(o => o.BuyerOrders != null)
+ .SelectMany(o => o.BuyerOrders)
.GroupBy(b => b.OutOrderSn)
.ToList();
- if (buyerOrders.Any(a => a.OutOrderSn == "261007-181907044681346"))
- {
- }
+ if (validBuyerOrders.Count == 0 && afterSaleGroups.Count == 0) continue; // 当天没有采购单,不写入
+ // 采购金额:直接累加每个有效订单的有效采购单
+ long totalPurchase = validBuyerOrders.Sum(b => (long)b.OutAmount);
+
+ // 外部订单数:有效 + 售后 去重
+ int purchaseCount = validBuyerOrders.Select(b => b.OutOrderSn)
+ .Union(afterSaleGroups.Select(g => g.Key))
+ .Count();
+
+ // 售后订单按退款状态分类
long done = 0, pending = 0, rejected = 0;
- long totalPurchase = 0;
- foreach (var g in outOrderGroups)
- {
- //购买金额:同一外部订单的多条记录可能是退款记录重复展开,购买金额只算一次
- totalPurchase += g.Max(x => x.OutAmount);
- // 只要有一条退款成功,整个外部订单视为退款成功
+ foreach (var g in afterSaleGroups)
+ {
+ // 已退款:只要有一条退款成功,整个外部订单视为已退款
var successRow = g.FirstOrDefault(x => IsRefundDone(x.RefundStatusText));
if (successRow != null)
{
@@ -795,34 +812,99 @@ public class ShopRevenueStatisticsService : ITransientDependency
continue;
}
- // 没有任何退款信息,说明没发生退款
+ // 未退款:取有退款信息的记录
var refundRows = g.Where(x => x.RefundAmount > 0 || !string.IsNullOrEmpty(x.RefundStatusText)).ToList();
if (refundRows.Count == 0) continue;
- // 没有成功记录:视为未成功,金额取该订单下最大的退款金额,避免重复累加
- long refundAmount = refundRows.Max(x => x.RefundAmount);
+ // 金额取该订单下最大退款金额,避免重复累加
+ long refundAmount = refundRows.Max(x => (long)x.RefundAmount);
+
if (refundRows.Any(x => IsRefundRejected(x.RefundStatusText)))
- rejected += refundAmount;
+ rejected += refundAmount; // 已拒绝
else
- pending += refundAmount;
+ pending += refundAmount; // 待处理
}
+
statsList.Add(new BuyerDailyStatsEntity
{
ShopId = shopGroup.Key.ToString(),
BuyerId = "",
StatDate = statDate.Date,
- PurchaseCount = outOrderGroups.Count, // 按外部订单数统计
+ PurchaseCount = purchaseCount,
TotalPurchase = totalPurchase,
DoneRefund = done,
PendingRefund = pending,
RejectedRefund = rejected,
});
}
- if (statsList.Count == 0) return;
+
+ if (statsList.Count == 0) return; // 空集合不要提交
_freeSql.InsertOrUpdate()
.SetSource(statsList, a => new { a.ShopId, a.StatDate })
.ExecuteAffrows();
+ // var buyerOrders = shopGroup
+ // .Where(o => o.BuyerOrders != null)
+ // .SelectMany(o => o.BuyerOrders)
+ // .ToList();
+
+ // if (buyerOrders.Count == 0) continue;
+ // // 该店铺当天没有采购单,不写入
+ // // 同一个外部订单可能有多条记录,按 OutOrderSn 再分组
+ // // OutOrderSn 为空时用 SkuId 兜底,避免多个空单号被合并成一个
+ // var outOrderGroups = buyerOrders
+ // .GroupBy(b => b.OutOrderSn)
+ // .ToList();
+ // if (buyerOrders.Any(a => a.OutOrderSn == "261007-181907044681346"))
+ // {
+
+ // }
+
+ // long done = 0, pending = 0, rejected = 0;
+ // long validTotalPurchase = 0;
+ // foreach (var g in outOrderGroups)
+ // {
+ // var validItems = g.Where(a => a.IsValid).ToList();
+ // if (validItems.Count > 0)
+ // {
+ // validTotalPurchase += validItems.Max(a => a.OutAmount);
+ // }
+ // // 只要有一条退款成功,整个外部订单视为退款成功
+ // var successRow = g.FirstOrDefault(x => IsRefundDone(x.RefundStatusText));
+ // if (successRow != null)
+ // {
+ // done += successRow.RefundAmount;
+ // continue;
+ // }
+
+ // // 没有任何退款信息,说明没发生退款
+ // var refundRows = g.Where(x => x.RefundAmount > 0 || !string.IsNullOrEmpty(x.RefundStatusText)).ToList();
+ // if (refundRows.Count == 0) continue;
+
+ // // 没有成功记录:视为未成功,金额取该订单下最大的退款金额,避免重复累加
+ // long refundAmount = refundRows.Max(x => x.RefundAmount);
+ // if (refundRows.Any(x => IsRefundRejected(x.RefundStatusText)))
+ // rejected += refundAmount;
+ // else
+ // pending += refundAmount;
+ // }
+ // statsList.Add(new BuyerDailyStatsEntity
+ // {
+ // ShopId = shopGroup.Key.ToString(),
+ // BuyerId = "",
+ // StatDate = statDate.Date,
+ // PurchaseCount = outOrderGroups.Count, // 按外部订单数统计
+ // TotalPurchase = validTotalPurchase,
+ // DoneRefund = done,
+ // PendingRefund = pending,
+ // RejectedRefund = rejected,
+ // });
+ //}
+ //if (statsList.Count == 0) return;
+
+ //_freeSql.InsertOrUpdate()
+ // .SetSource(statsList, a => new { a.ShopId, a.StatDate })
+ // .ExecuteAffrows();
}
diff --git a/test/WebServiceTest/ShopTest.cs b/test/WebServiceTest/ShopTest.cs
index 4ad254b..41faf9a 100644
--- a/test/WebServiceTest/ShopTest.cs
+++ b/test/WebServiceTest/ShopTest.cs
@@ -136,15 +136,15 @@ internal class ShopTest
[Test]
public void GetShopSalesOrderTest()
{
- var shopService = _container.Resolve();
- DateTime date = DateTime.Parse("2026/10/01");
+ var shopService = _container.Resolve();
+ var shopIds =shopService.GetShopIds("taiyuanqiji");
+ var shopStatsService = _container.Resolve();
+ DateTime date = DateTime.Parse("2026/09/10");
Console.WriteLine($"开始:{date.ToLongDateString()}");
try
{
- shopService.ShopDailyStats(date, [
- 1960967267443626508,
- ]);
+ shopStatsService.ShopDailyStats(date, shopIds);
}
catch
{