From f1a03e521adbb71e100bce79752084f05f0d32ba Mon Sep 17 00:00:00 2001 From: chfei Date: Fri, 9 Oct 2026 20:22:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=9F=E8=AE=A1=EF=BC=8C?= =?UTF-8?q?=20=E9=87=87=E8=B4=AD=E9=87=91=E9=A2=9D=3D=E6=9C=89=E6=95=88?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=9A=84=E9=87=87=E8=B4=AD=E9=87=91=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Model/WxModel/ShopRevenueStatistics.cs | 5 + .../Shops/ShopRevenueStatisticsService.cs | 136 ++++++++++++++---- test/WebServiceTest/ShopTest.cs | 10 +- 3 files changed, 119 insertions(+), 32 deletions(-) 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 {