using AutoMapper; using FreeSql; using Google.Protobuf.Collections; using SiNan.Common.Extensions; using SiNan.Common.Log; using SiNan.Common.Models; using SiNan.Model; using SiNan.Model.Core; using SiNan.Model.Db; using SiNan.Model.Dto; using Yitter.IdGenerator; namespace SiNan.Business { public class GOIBusiness : BaseBusiness, IDenpendency { private FreeSqlMultiDBManager freeSqlMultiDBManager; public GOIBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager freeSqlMultiDBManager) : base(fsql, nLogManager, idGenerator) { this.freeSqlMultiDBManager = freeSqlMultiDBManager; } private IList StatisticsProductLevelGOI(IList skuIdList, DateTime startDate, DateTime endDate) { var costs = fsql.Select() .Where(jas => skuIdList.Contains(jas.Sku) && jas.Date >= startDate && jas.Date <= endDate) .GroupBy(jas => jas.Sku) .ToList(g => new { Cost = g.Sum(g.Value.Cost), Sku = g.Key }); var profits = fsql.Select() .InnerJoin((ocd, o) => ocd.OrderId == o.Id) .Where((ocd, o) => skuIdList.Contains(ocd.SkuId) && ocd.IsEnabled && ocd.CreateTime >= startDate && ocd.CreateTime <= endDate && o.OrderState != Enums.OrderState.已取消) .GroupBy((ocd, o) => ocd.SkuId) .ToList(g => new { Profit = g.Sum(g.Value.Item1.SkuGrossProfit), Sku = g.Key }); IList list = new List(); foreach (var skuId in skuIdList) { var cost = costs.FirstOrDefault(x => x.Sku == skuId)?.Cost ?? 0M; var profit = profits.FirstOrDefault(x => x.Sku == skuId)?.Profit ?? 0M; var skugoi = new GOIBySku() { Sku = skuId, Cost = cost, Profit = profit }; list.Add(skugoi); } return list; } private IList StatisticsPopularizeLevelGOI(IList skuIdList, DateTime? startDate, DateTime? endDate) { IList list = new List(); 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 profits = fsql.Select() .InnerJoin((jr, ocd, o) => jr.OrderId == ocd.OrderId) .InnerJoin((jr, ocd, o) => jr.OrderId == o.Id) .Where((jr, ocd, o) => skuIdList.Contains(jr.PopularizeSku)) .WhereIf(startDate != null, (jr, ocd, o) => jr.CookieTime >= startDate) .WhereIf(endDate != null, (jr, ocd, o) => jr.CookieTime <= endDate) .Where((jr, ocd, o) => ocd.IsEnabled == true && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, ocd, o) => jr.PopularizeSku) .ToList(g => new { Profit = g.Sum(g.Value.Item2.SkuGrossProfit), Sku = g.Key }); foreach (var skuId in skuIdList) { var cost = costs.FirstOrDefault(x => x.Sku == skuId)?.Cost ?? 0M; var profit = profits.FirstOrDefault(x => x.Sku == skuId)?.Profit ?? 0M; var skugoi = new GOIBySku() { Sku = skuId, Cost = cost, Profit = profit }; list.Add(skugoi); } return list; } public IList CalculationCampaignLevelGOI(IList campaignIdList, DateTime startDate, DateTime endDate) { var costs = fsql.Select().Where(x => campaignIdList.Contains(x.CampaignId.Value) && x.Date >= startDate && x.Date <= endDate) .GroupBy(x => x.CampaignId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), CampaignId = g.Key }); var profits = fsql.Select().InnerJoin((jr, oc, o) => jr.OrderId == oc.OrderId) .InnerJoin((jr, oc, o) => jr.OrderId == o.Id) .Where((jr, oc, o) => campaignIdList.Contains(jr.CampaignId.Value) && jr.CookieTime >= startDate && jr.CookieTime <= endDate && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, oc, o) => jr.CampaignId) .ToList(g => new { CampaignId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); IList list = new List(); foreach (var campaignId in campaignIdList) { var cost = costs.FirstOrDefault(x => x.CampaignId == campaignId)?.Cost ?? 0M; var profit = profits.FirstOrDefault(x => x.CampaignId == campaignId)?.Profit ?? 0M; var skugoi = new GOIByLevel() { LevelId = campaignId, Cost = cost, Profit = profit }; list.Add(skugoi); } return list; } public IList CalculationAdGroupLevelGOI(IList adGroupIdList, DateTime startDate, DateTime endDate) { var customEndTime = gOIRequest.EndDate.AddDays(1).AddSeconds(-1); DateTime? _7dEndDate = null; DateTime? _7dStartDate = null; DateTime? _7dEndTime = null; DateTime? _30dEndDate = null; DateTime? _30dStartDate = null; DateTime? _30dEndTime = null; if (!gOIRequest.OnlyCustomDate) { _7dEndDate = DateTime.Now.Date.AddDays(-1); _7dStartDate = _7dEndDate.Value.AddDays(-6); _7dEndTime = _7dEndDate.Value.AddDays(1).AddSeconds(-1); _30dEndDate = DateTime.Now.Date.AddDays(-1); _30dStartDate = _30dEndDate.Value.AddDays(-29); _30dEndTime = _30dEndDate.Value.AddDays(1).AddSeconds(-1); } var _7dAdGroupCosts = gOIRequest.OnlyCustomDate ? null : fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdGroupId.Value) && x.Date >= _7dStartDate && x.Date <= _7dEndDate) .GroupBy(x => x.AdGroupId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), AdGroupId = g.Key }); var _7dAdGroupProfits = gOIRequest.OnlyCustomDate ? null : fsql.Select().InnerJoin((jr, oc, o) => jr.OrderId == oc.OrderId) .InnerJoin((jr, oc, o) => jr.OrderId == o.Id) .Where((jr, oc, o) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && jr.CookieTime >= _7dStartDate && jr.CookieTime <= _7dEndTime && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, oc, o) => jr.AdGroupId) .ToList(g => new { AdGroupId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); var _30dAdGroupCosts = gOIRequest.OnlyCustomDate ? null : fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdGroupId.Value) && x.Date >= _30dStartDate && x.Date <= _30dEndDate) .GroupBy(x => x.AdGroupId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), AdGroupId = g.Key }); var _30dAdGroupProfits = gOIRequest.OnlyCustomDate ? null : fsql.Select().InnerJoin((jr, oc, o) => jr.OrderId == oc.OrderId) .InnerJoin((jr, oc, o) => jr.OrderId == o.Id) .Where((jr, oc, o) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && jr.CookieTime >= _30dStartDate && jr.CookieTime <= _30dEndTime && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, oc, o) => jr.AdGroupId) .ToList(g => new { AdGroupId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); var customDaysAdGroupCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdGroupId.Value) && x.Date >= gOIRequest.StartDate && x.Date <= gOIRequest.EndDate) .GroupBy(x => x.AdGroupId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), AdGroupId = g.Key }); var customDaysAdGroupProfits = fsql.Select().InnerJoin((jr, oc, o) => jr.OrderId == oc.OrderId) .InnerJoin((jr, oc, o) => jr.OrderId == o.Id) .Where((jr, oc, o) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && jr.CookieTime >= gOIRequest.StartDate && jr.CookieTime <= customEndTime && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, oc, o) => jr.AdGroupId) .ToList(g => new { AdGroupId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); var totalAdGroupCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdGroupId.Value)) .GroupBy(x => x.AdGroupId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), AdGroupId = g.Key }); var list = new List(); foreach (var levelId in gOIRequest.LevelIdList) { var goiResponse = new JDMultiLevelGOIResponse() { LevelId = levelId, BusinessType = gOIRequest.BusinessType }; goiResponse._7GOI.Cost = _7dAdGroupCosts == null ? 0 : (_7dAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M); goiResponse._7GOI.Profit = _7dAdGroupProfits == null ? 0 : (_7dAdGroupProfits.FirstOrDefault(x => x.AdGroupId == levelId)?.Profit ?? 0M); goiResponse._30GOI.Cost = _30dAdGroupCosts == null ? 0 : (_30dAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M); goiResponse._30GOI.Profit = _30dAdGroupProfits == null ? 0 : (_30dAdGroupProfits.FirstOrDefault(x => x.AdGroupId == levelId)?.Profit ?? 0M); goiResponse.CustomDaysGOI.Cost = customDaysAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M; goiResponse.CustomDaysGOI.Profit = customDaysAdGroupProfits.FirstOrDefault(x => x.AdGroupId == levelId)?.Profit ?? 0M; goiResponse.TotalCost = totalAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M; list.Add(goiResponse); } return list; } public ListResponse QueryProductGOI(QueryProductGOIRequest request) { if (request.ShopId == 0) throw new BusinessException("缺少店铺Id"); ISelect? skuChildSelect = string.IsNullOrEmpty(request.Sku) ? null : fsql.Select().As("ps").Where(ps => ps.ShopId == request.ShopId && ps.Id == request.Sku); var productList = fsql.Select().Where(p => p.ShopId == request.ShopId) .WhereIf(!string.IsNullOrEmpty(request.Spu), p => p.Id == request.Spu) .WhereIf(skuChildSelect != null, p => skuChildSelect.Where(ps => ps.ProductId == p.Id).Any()) .Page(request.PageIndex, request.PageSize) .Count(out var productCount) .ToList(); if (productList.Count == 0) return new ListResponse() { ItemList = new List() }; var productIdList = productList.Select(p => p.Id).ToList(); var skuList = fsql.Select().Where(ps => productIdList.Contains(ps.Id)).ToList(); var skuIdList = skuList.Select(s => s.Id).ToList(); var startDate_yestoday = DateTime.Now.Date.AddDays(-1); var endDate_yestoday = DateTime.Now.Date.AddSeconds(-1); var startDate_Recent7day = DateTime.Now.Date.AddDays(-7); var endDate_Recent7day = DateTime.Now.Date.AddSeconds(-1); var startDate_Recent30day = DateTime.Now.Date.AddDays(-30); var endDate_Recent30day = DateTime.Now.Date.AddSeconds(-1); #region 商品维度 //昨天 var yestodayProductLevelGOIList = StatisticsProductLevelGOI(skuIdList, startDate_yestoday, endDate_yestoday); //近7天 var recent7dayProductLevelGOIList = StatisticsProductLevelGOI(skuIdList, startDate_Recent7day, endDate_Recent7day); //近30天 var recent30dayProductLevelGOIList = StatisticsProductLevelGOI(skuIdList, startDate_Recent30day, endDate_Recent30day); #endregion #region 推广维度 //昨天 var yestodayPopularizeLevelGOIList = StatisticsPopularizeLevelGOI(skuIdList, startDate_yestoday, endDate_yestoday); //近7天 var recent7dayPopularizeLevelGOIList = StatisticsPopularizeLevelGOI(skuIdList, startDate_Recent7day, endDate_Recent7day); //近30天 var recent30dayPopularizeLevelGOIList = StatisticsPopularizeLevelGOI(skuIdList, startDate_Recent30day, endDate_Recent30day); #endregion #region 累计花费/累计亏损 var historyPopularizeLevelGOIList = StatisticsPopularizeLevelGOI(skuIdList, null, null); #endregion List productGOIList = new List(); foreach (var product in productList) { var productGoi = product.Map(); productGOIList.Add(productGoi); productGoi.ProductSkuGOIList = skuList.Where(ps => ps.ProductId == product.Id).Map>(); foreach (var productSku in productGoi.ProductSkuGOIList) { productSku.ProductGOI_Yestoday = yestodayProductLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.ProductGOI_Recent7Day = recent7dayProductLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.ProductGOI_Recent30Day = recent30dayProductLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.PromotionGOI_Yestoday = yestodayPopularizeLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.PromotionGOI_Recent7Day = recent7dayPopularizeLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.PromotionGOI_Recent30Day = recent30dayPopularizeLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); var historyPopularizeLevelGOI = historyPopularizeLevelGOIList.FirstOrDefault(x => x.Sku == productSku.Id); productSku.TotalCost = historyPopularizeLevelGOI?.Cost ?? 0M; productSku.TotalDeficit = (historyPopularizeLevelGOI?.Profit ?? 0M) - (historyPopularizeLevelGOI?.Cost ?? 0M); } productGoi.ProductGOI_Yestoday = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Yestoday?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Yestoday?.Profit ?? 0M) }; productGoi.ProductGOI_Recent7Day = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Recent7Day?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Recent7Day?.Profit ?? 0M) }; productGoi.ProductGOI_Recent30Day = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Recent30Day?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.ProductGOI_Recent30Day?.Profit ?? 0M) }; productGoi.PromotionGOI_Yestoday = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Yestoday?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Yestoday?.Profit ?? 0M) }; productGoi.PromotionGOI_Recent7Day = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Recent7Day?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Recent7Day?.Profit ?? 0M) }; productGoi.PromotionGOI_Recent30Day = new GOIResponse() { Cost = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Recent30Day?.Cost ?? 0M), Profit = productGoi.ProductSkuGOIList.Sum(x => x.PromotionGOI_Recent30Day?.Profit ?? 0M) }; productGoi.TotalCost = productGoi.ProductSkuGOIList.Sum(x => x.TotalCost); productGoi.TotalDeficit = productGoi.ProductSkuGOIList.Sum(x => x.TotalDeficit); } return new ListResponse() { Count = productCount, ItemList = productGOIList }; } public ListResponse QueryProduct360PopularizeGOI(Product360PopularizeAnalysisRequest request) { if (request.SkuIdList == null || request.SkuIdList.Count() == 0) throw new BusinessException("缺少sku"); List list = new List(); var popularizeAdSkuSourceList = fsql.Select() .Where(x => x.ShopId == request.ShopId) .Where(x => x.Date >= request.StartDate && x.Date <= request.EndDate) .WhereIf(request.SkuIdList.Count() == 1, x => x.Sku == request.SkuIdList[0]) .WhereIf(request.SkuIdList.Count() > 1, x => request.SkuIdList.Contains(x.Sku)) .ToList(); #region 处理所有计划的GOI var allCampaignIdList = popularizeAdSkuSourceList.Select(x => x.CampaignId).Distinct().ToList(); #endregion var kuaicheCampaignSourceList = popularizeAdSkuSourceList.Where(x => x.BusinessType == 2).ToList(); var jstCampaignSourceList = popularizeAdSkuSourceList.Where(x => x.BusinessType == 134217728).ToList(); #region 处理快车 #region 处理单元统计 var adGroupStatisticsList = kuaicheCampaignSourceList.GroupBy(x => x.AdGroupId); var adGroupIdList = adGroupStatisticsList.Select(x => x.Key).ToList(); var allAdGroupList = new List(); foreach (var adGroupStatistics in adGroupStatisticsList) { var adGroupId = adGroupStatistics.Key; var adGroup = new Product360PopularizeAnalysisAdGroupResponse() { AdGroupId = adGroupId.Value, AdGroupName = string.Empty, BusinessType = 2, CampaignId = adGroupStatistics.FirstOrDefault()?.CampaignId ?? 0, Clicks = adGroupStatistics.Sum(x => x.Clicks), Cost = adGroupStatistics.Sum(x => x.Cost), Impressions = adGroupStatistics.Sum(x => x.Impressions), OrderCnt = adGroupStatistics.Sum(x => x.TotalOrderCnt) }; allAdGroupList.Add(adGroup); var campagin = list.FirstOrDefault(x => x.CampaignId == adGroup.CampaignId); if (campagin != null) campagin.AdGroupList.Add(adGroup); } #endregion #region 处理单元GOI #endregion #endregion #region 处理京速推 #endregion return new ListResponse() { ItemList = list, Count = list.Count }; } } }