From 5ed1b58660626dd6b7955c6ff344ab0e376fc3a6 Mon Sep 17 00:00:00 2001 From: sanji Date: Mon, 18 Mar 2024 02:37:45 +0800 Subject: [PATCH] ROI --- SiNan.Business/AggregationBusiness.cs | 31 ++++-- SiNan.Business/GOIBusiness.cs | 98 ++++++++++++++++++- SiNan.Model/Core/ROI/ROIByAdSku.cs | 9 ++ SiNan.Model/Core/ROI/ROIBySku.cs | 7 ++ SiNan.Model/Core/ROI/ROICore.cs | 26 +++++ .../AggregationJDPopularizeAdSkuDaily.cs | 6 ++ .../Aggregation/AggregationJDPopularizeSku.cs | 7 ++ .../AggregationJDPopularizeSkuDaily.cs | 12 +++ 8 files changed, 187 insertions(+), 9 deletions(-) create mode 100644 SiNan.Model/Core/ROI/ROIByAdSku.cs create mode 100644 SiNan.Model/Core/ROI/ROIBySku.cs create mode 100644 SiNan.Model/Core/ROI/ROICore.cs diff --git a/SiNan.Business/AggregationBusiness.cs b/SiNan.Business/AggregationBusiness.cs index aaeb7ef..580283d 100644 --- a/SiNan.Business/AggregationBusiness.cs +++ b/SiNan.Business/AggregationBusiness.cs @@ -3,6 +3,7 @@ using SiNan.Common.Log; using SiNan.Common.Models; using SiNan.Model; using SiNan.Model.Core; +using SiNan.Model.Core.ROI; using SiNan.Model.Db; using SiNan.Model.Dto; using Yitter.IdGenerator; @@ -165,10 +166,13 @@ namespace SiNan.Business var aggregationDate_ProductLevelList = goiBusiness.StatisticsProductLevelGOI(currentGroupSkuIdList, startDate_aggregationDate, endDate_aggregationDate); var aggregationDate_PopularizeLevelList = goiBusiness.StatisticsPopularizeLevelGOI(currentGroupSkuIdList, startDate_aggregationDate, endDate_aggregationDate); var aggregationDate_SkuActualAmountList = StatisticsActualAmountBySku(currentGroupSkuIdList, startDate_aggregationDate, endDate_aggregationDate); + var aggregationDate_PopularizeLevelROIList = goiBusiness.StatisticsPopluarizeLvelROI(currentGroupSkuIdList, startDate_aggregationDate, endDate_aggregationDate); + IList recent7d_ProductLevelList = null; IList recent7d_PopularizeLevelList = null; IList recent30d_ProductLevelList = null; IList recent30d_PopularizeLevelList = null; + IList recent7d_PopluarizeLevelROIList = null; if (isLastDate && (DateTime.Now.Date - startDate_aggregationDate).TotalDays <= 31) @@ -184,6 +188,7 @@ namespace SiNan.Business recent7d_PopularizeLevelList = goiBusiness.StatisticsPopularizeLevelGOI(currentGroupSkuIdList, startDate_Recent7day, endDate_Recent7day); recent30d_ProductLevelList = goiBusiness.StatisticsProductLevelGOI(currentGroupSkuIdList, startDate_Recent30day, endDate_Recent30day); ; recent30d_PopularizeLevelList = goiBusiness.StatisticsPopularizeLevelGOI(currentGroupSkuIdList, startDate_Recent30day, endDate_Recent30day); + recent7d_PopluarizeLevelROIList = goiBusiness.StatisticsPopluarizeLvelROI(currentGroupSkuIdList, startDate_Recent7day, endDate_Recent7day); } foreach (var spuId in spuGroup) @@ -196,6 +201,8 @@ namespace SiNan.Business IList currentSpu_Recent30d_ProductLevelList = recent30d_ProductLevelList?.Where(x => currentSpuSkuIdList.Contains(x.Sku)).ToList(); IList currentSpu_Recent30d_PopularizeLevelList = recent30d_PopularizeLevelList?.Where(x => currentSpuSkuIdList.Contains(x.Sku)).ToList(); + var currentSpu_AggregationDate_PopularizeLevelROIList = aggregationDate_PopularizeLevelROIList.Where(x => currentSpuSkuIdList.Contains(x.Sku)).ToList(); + #region 处理SPU每日聚合 var spugoi_AggregationDate_ProductLevel = new GOIBySpu() { @@ -312,10 +319,12 @@ namespace SiNan.Business #region 处理SKU每日聚合 var skugoi_AggregationDate_ProductLevel = currentSpu_AggregationDate_ProductLevelList.FirstOrDefault(x => x.Sku == skuId); var skugoi_AggregationDate_PopularizeLevel = currentSpu_AggregationDate_PopularizeLevelList.FirstOrDefault(x => x.Sku == skuId); + var skuroi_aggregationDate_PopularizeLevelROI = currentSpu_AggregationDate_PopularizeLevelROIList.FirstOrDefault(x => x.Sku == skuId); var skugoi_Recent7d_ProductLevel = currentSpu_Recent7d_ProductLevelList?.FirstOrDefault(x => x.Sku == skuId); var skugoi_Recent7d_PopularizeLevel = currentSpu_Recent7d_PopularizeLevelList?.FirstOrDefault(x => x.Sku == skuId); var skugoi_Recent30d_ProductLevel = currentSpu_Recent30d_ProductLevelList?.FirstOrDefault(x => x.Sku == skuId); var skugoi_Recent30d_PopularizeLevel = currentSpu_Recent30d_PopularizeLevelList?.FirstOrDefault(x => x.Sku == skuId); + var skuroi_Recent7d_PopularizeLevel = recent7d_PopluarizeLevelROIList?.FirstOrDefault(x => x.Sku == skuId); var skuDailyAggregation = new AggregationJDPopularizeSkuDaily() { @@ -330,7 +339,9 @@ namespace SiNan.Business ProductLevelGOI = skugoi_AggregationDate_ProductLevel?.GOI ?? 0M, PopularizeLevelProfit = skugoi_AggregationDate_PopularizeLevel?.Profit ?? 0M, PopularizeLevelGOI = skugoi_AggregationDate_PopularizeLevel?.GOI ?? 0M, - ActualAmount = aggregationDate_SkuActualAmountList.FirstOrDefault(x => x.Sku == skuId)?.ActualAmount ?? 0M + ActualAmount = aggregationDate_SkuActualAmountList.FirstOrDefault(x => x.Sku == skuId)?.ActualAmount ?? 0M, + PopularizeAmount = skuroi_aggregationDate_PopularizeLevelROI?.Amount ?? 0M, + PopluarizeLevelROI = skuroi_aggregationDate_PopularizeLevelROI?.ROI ?? 0M }; insertAggregationSkuDailyList.Add(skuDailyAggregation); #endregion @@ -360,7 +371,8 @@ namespace SiNan.Business Recent30dProductLevelProfit = skugoi_Recent30d_ProductLevel?.Profit ?? 0M, Recent30dProductLevelGOI = skugoi_Recent30d_ProductLevel?.GOI ?? 0M, Recent30dPopularizeLevelProfit = skugoi_Recent30d_PopularizeLevel?.Profit ?? 0M, - Recent30dPopularizeLevelGOI = skugoi_Recent30d_PopularizeLevel?.GOI ?? 0M + Recent30dPopularizeLevelGOI = skugoi_Recent30d_PopularizeLevel?.GOI ?? 0M, + Recent7dPopluarizeLevelROI = skuroi_Recent7d_PopularizeLevel?.ROI ?? 0M }); } else @@ -804,7 +816,8 @@ namespace SiNan.Business List insertAggregationAdSkuDailyList = new List(); var aggregationDate_PopularizeLevelList = goiBusiness.CalculationAdSkuLevelGOI(adSkuIdList, startDate_aggregationDate, endDate_aggregationDate); var aggregationDate_ProductLevelList = goiBusiness.CalculationAdSkuProductLevelGOI(adSkuIdList, startDate_aggregationDate, endDate_aggregationDate); - var aggregationDate_SkuPopularizeAmountList = StatisticsPopularizeAmountBySku(adSkuIdList, startDate_aggregationDate, endDate_aggregationDate); + //var aggregationDate_SkuPopularizeAmountList = StatisticsPopularizeAmountBySku(adSkuIdList, startDate_aggregationDate, endDate_aggregationDate); + var aggregationDate_PopularizeLevelROIList = goiBusiness.StatisticsAdSkuLvelROI(adSkuIdList, startDate_aggregationDate, endDate_aggregationDate); var adSkuIndex = 0; foreach (var adSku in adSkuList) @@ -818,9 +831,10 @@ namespace SiNan.Business x.CampaignId == adSku.CampaignId); var adSkuGoi_AggregationDate_ProductLevel = aggregationDate_ProductLevelList.FirstOrDefault(x => x.Sku == adSku.Sku && x.BusinessType == adSku.BusinessType); - var adSkuPoplarizeAmount = aggregationDate_SkuPopularizeAmountList.FirstOrDefault(x => x.Sku == adSku.Sku && - x.BusinessType == adSku.BusinessType && - x.CampaignId == adSku.CampaignId); + //var adSkuPoplarizeAmount = aggregationDate_SkuPopularizeAmountList.FirstOrDefault(x => x.Sku == adSku.Sku && x.BusinessType == adSku.BusinessType && x.CampaignId == adSku.CampaignId); + var adSkuPopularizeROI = aggregationDate_PopularizeLevelROIList.FirstOrDefault(x => x.Sku == adSku.Sku && + x.BusinessType == adSku.BusinessType && + x.CampaignId == adSku.CampaignId); var adSkuDailyAggregation = new AggregationJDPopularizeAdSkuDaily() { @@ -838,8 +852,9 @@ namespace SiNan.Business BusinessType = adSku.BusinessType, SkuId = adSku.Sku, AdId = adSku.AdId, - PopularizeAmount = adSkuPoplarizeAmount?.ActualAmount ?? 0M, - Clicks = adSkuGoi_AggregationDate_PopularizeLevel?.Clicks ?? 0 + PopularizeAmount = adSkuPopularizeROI?.Amount ?? 0M, + Clicks = adSkuGoi_AggregationDate_PopularizeLevel?.Clicks ?? 0, + PopluarizeLevelROI = adSkuPopularizeROI?.ROI ?? 0M }; insertAggregationAdSkuDailyList.Add(adSkuDailyAggregation); diff --git a/SiNan.Business/GOIBusiness.cs b/SiNan.Business/GOIBusiness.cs index c705f3a..5668957 100644 --- a/SiNan.Business/GOIBusiness.cs +++ b/SiNan.Business/GOIBusiness.cs @@ -6,6 +6,7 @@ using SiNan.Common.Log; using SiNan.Common.Models; using SiNan.Model; using SiNan.Model.Core; +using SiNan.Model.Core.ROI; using SiNan.Model.Db; using SiNan.Model.Dto; using Yitter.IdGenerator; @@ -96,6 +97,45 @@ namespace SiNan.Business return list; } + public IList StatisticsPopluarizeLvelROI(IList skuIdList, DateTime? startDate, DateTime? endDate) + { + var costs = fsql.Select() + .Where(jas => skuIdList.Contains(jas.Sku)) // &&jas.Date >= startDate && jas.Date <= endDate + .WhereIf(startDate != null, jas => jas.Date >= startDate) + .WhereIf(endDate != null, jas => jas.Date <= endDate) + .GroupBy(jas => jas.Sku) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + Sku = g.Key + }); + + var amounts = fsql.Select() + .InnerJoin((jr, o, osku) => jr.OrderId == o.Id) + .InnerJoin((jr, o, osku) => o.Id == osku.OrderId) + .Where((jr, o, osku) => o.OrderState != Enums.OrderState.已取消 && + o.IsGift == false && + jr.CookieTime >= startDate && + jr.CookieTime <= endDate && + osku.Price > 0 && + skuIdList.Contains(osku.SkuId)) + .GroupBy((jr, o, osku) => osku.SkuId) + .ToList(g => new PopularizeAmountBySku + { + ActualAmount = g.Sum(g.Value.Item3.ActualAmount * g.Value.Item3.ItemTotal), + Sku = g.Key + }); + IList list = new List(); + foreach (var skuId in skuIdList) + { + var cost = costs.FirstOrDefault(x => x.Sku == skuId)?.Cost ?? 0M; + var amount = amounts.FirstOrDefault(x => x.Sku == skuId)?.ActualAmount ?? 0M; + var skuroi = new ROIBySku() { Sku = skuId, Cost = cost, Amount = amount }; + list.Add(skuroi); + } + return list; + } + private GOIByShop StatisticsProductLevelGOI(long shopId, DateTime? startDate, DateTime? endDate) { var cost = fsql.Select() @@ -251,6 +291,62 @@ namespace SiNan.Business return list; } + public IList StatisticsAdSkuLvelROI(IList skuIdList, DateTime? startDate, DateTime? endDate) + { + var costs = fsql.Select() + .Where(jas => skuIdList.Contains(jas.Sku)) // &&jas.Date >= startDate && jas.Date <= endDate + .WhereIf(startDate != null, jas => jas.Date >= startDate) + .WhereIf(endDate != null, jas => jas.Date <= endDate) + .GroupBy(jas => new { jas.Sku, jas.BusinessType, jas.CampaignId }) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + Sku = g.Key.Sku, + g.Key.BusinessType, + g.Key.CampaignId + }); + + var amounts = fsql.Select() + .InnerJoin((jr, o, osku) => jr.OrderId == o.Id) + .InnerJoin((jr, o, osku) => o.Id == osku.OrderId) + .Where((jr, o, osku) => o.OrderState != Enums.OrderState.已取消 && + o.IsGift == false && + jr.CookieTime >= startDate && + jr.CookieTime <= endDate && + osku.Price > 0 && + skuIdList.Contains(osku.SkuId)) + .GroupBy((jr, o, osku) => new { jr.PopularizeSku, jr.BusinessType, jr.CampaignId }) + .ToList(g => new PopularizeAmountBySku + { + ActualAmount = g.Sum(g.Value.Item3.ActualAmount * g.Value.Item3.ItemTotal), + Sku = g.Key.PopularizeSku, + BusinessType = g.Key.BusinessType, + CampaignId = g.Key.CampaignId + }); + + IList list = new List(); + foreach (var skuId in skuIdList) + { + var currentCosts = costs.Where(c => c.Sku == skuId).ToList(); + foreach (var cost in currentCosts) + { + var amount = amounts.FirstOrDefault(x => x.Sku == skuId && + x.BusinessType == cost.BusinessType && + x.CampaignId == cost.CampaignId); + var adskuroi = new ROIByAdSku() + { + Sku = skuId, + Cost = cost.Cost, + Amount = amount?.ActualAmount ?? 0M, + BusinessType = cost.BusinessType.Value, + CampaignId = cost.CampaignId.Value, + }; + list.Add(adskuroi); + } + } + return list; + } + public IList CalculationAdSkuProductLevelGOI(IList skuIdList, DateTime startDate, DateTime endDate) { var costs = fsql.Select() @@ -266,7 +362,7 @@ namespace SiNan.Business var profits = fsql.Select() .InnerJoin((ocd, o) => ocd.OrderId == o.Id) .Where((ocd, o) => skuIdList.Contains(ocd.SkuId) && - ocd.IsEnabled==true && + ocd.IsEnabled == true && o.StartTime >= startDate && o.StartTime <= endDate && o.OrderState != Enums.OrderState.已取消 && diff --git a/SiNan.Model/Core/ROI/ROIByAdSku.cs b/SiNan.Model/Core/ROI/ROIByAdSku.cs new file mode 100644 index 0000000..833ab64 --- /dev/null +++ b/SiNan.Model/Core/ROI/ROIByAdSku.cs @@ -0,0 +1,9 @@ +namespace SiNan.Model.Core.ROI +{ + public class ROIByAdSku : ROIBySku + { + public int BusinessType { get; set; } + + public long CampaignId { get; set; } + } +} diff --git a/SiNan.Model/Core/ROI/ROIBySku.cs b/SiNan.Model/Core/ROI/ROIBySku.cs new file mode 100644 index 0000000..56c5350 --- /dev/null +++ b/SiNan.Model/Core/ROI/ROIBySku.cs @@ -0,0 +1,7 @@ +namespace SiNan.Model.Core.ROI +{ + public class ROIBySku : ROICore + { + public string Sku { get; set; } + } +} diff --git a/SiNan.Model/Core/ROI/ROICore.cs b/SiNan.Model/Core/ROI/ROICore.cs new file mode 100644 index 0000000..b771fef --- /dev/null +++ b/SiNan.Model/Core/ROI/ROICore.cs @@ -0,0 +1,26 @@ +namespace SiNan.Model.Core +{ + public class ROICore + { + /// + /// 花费 + /// + public decimal Cost { get; set; } + + /// + /// 成交额 + /// + public decimal Amount { get; set; } + + /// + /// ROI + /// + public decimal ROI + { + get + { + return Cost == 0M ? 0M : Math.Round(Amount / Cost, 2); + } + } + } +} diff --git a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeAdSkuDaily.cs b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeAdSkuDaily.cs index 78b0bef..5a6175a 100644 --- a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeAdSkuDaily.cs +++ b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeAdSkuDaily.cs @@ -87,6 +87,12 @@ namespace SiNan.Model.Db [Column(DbType = "int")] public int? Clicks { get; set; } = 0; + + /// + /// 推广维度ROI + /// + [Column(DbType = "decimal(18,2)")] + public decimal? PopluarizeLevelROI { get; set; } = 0.00M; } } diff --git a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSku.cs b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSku.cs index 5c363ca..cd20975 100644 --- a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSku.cs +++ b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSku.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using System.Text; namespace SiNan.Model.Db { @@ -120,6 +121,12 @@ namespace SiNan.Model.Db [Column(DbType = "datetime")] public DateTime? Date { get; set; } + /// + /// 近7天推广维度ROI + /// + [Column(DbType = "decimal(18,2)")] + public decimal? Recent7dPopluarizeLevelROI { get; set; } = 0.00M; + } } diff --git a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSkuDaily.cs b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSkuDaily.cs index a321cca..350bf83 100644 --- a/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSkuDaily.cs +++ b/SiNan.Model/Db/Aggregation/AggregationJDPopularizeSkuDaily.cs @@ -67,6 +67,18 @@ namespace SiNan.Model.Db [Column(DbType = "decimal(18,2)")] public decimal? ActualAmount { get; set; } = 0.00M; + /// + /// 推广营业额(SKU实收) + /// + [Column(DbType = "decimal(18,2)")] + public decimal? PopularizeAmount { get; set; } = 0.00M; + + /// + /// 推广维度ROI + /// + [Column(DbType = "decimal(18,2)")] + public decimal? PopluarizeLevelROI { get; set; } = 0.00M; + } }