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.Value, Cost = cost, Profit = profit }; list.Add(skugoi); } return list; } public IList CalculationAdGroupLevelGOI(IList adGroupIdList, DateTime startDate, DateTime endDate) { var costs = fsql.Select().Where(x => adGroupIdList.Contains(x.AdGroupId.Value) && x.Date >= startDate && x.Date <= endDate) .GroupBy(x => x.AdGroupId) .ToList(g => new { Cost = g.Sum(g.Value.Cost), AdGroupId = 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) => adGroupIdList.Contains(jr.AdGroupId.Value) && jr.CookieTime >= startDate && jr.CookieTime <= endDate && o.OrderState != Enums.OrderState.已取消) .GroupBy((jr, oc, o) => jr.AdGroupId) .ToList(g => new { AdGroupId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); IList list = new List(); foreach (var adGroupId in adGroupIdList) { var cost = costs.FirstOrDefault(x => x.AdGroupId == adGroupId)?.Cost ?? 0M; var profit = profits.FirstOrDefault(x => x.AdGroupId == adGroupId)?.Profit ?? 0M; var skugoi = new GOIByLevel() { LevelId = adGroupId.Value, Cost = cost, Profit = profit }; list.Add(skugoi); } 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 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); 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(); var kuaicheCampaignSourceList = popularizeAdSkuSourceList.Where(x => x.BusinessType == 2).ToList(); var jstCampaignSourceList = popularizeAdSkuSourceList.Where(x => x.BusinessType == 134217728).ToList(); var allCampaignIdList = popularizeAdSkuSourceList.Select(x => x.CampaignId).Distinct().ToList(); var kuaicheCampaignIdList = kuaicheCampaignSourceList.Select(x => x.CampaignId).Distinct().ToList(); var jstCampaignIdList = jstCampaignSourceList.Select(x => x.CampaignId).Distinct().ToList(); #region 查询所有计划名称 var allCampaignNameList = fsql.Select() .Where(x => x.ShopId == request.ShopId && allCampaignIdList.Contains(x.CampaignId)) .GroupBy(x => new { x.CampaignId, x.CampaignName }) .ToList(g => new { g.Value.CampaignId, g.Value.CampaignName }); #endregion #region 处理所有计划的GOI var recent7DayCampaignGOIList = CalculationCampaignLevelGOI(allCampaignIdList, startDate_Recent7day, endDate_Recent7day); var recent30DayCampaignGOIList = CalculationCampaignLevelGOI(allCampaignIdList, startDate_Recent30day, endDate_Recent30day); #endregion #region 处理快车 #region 处理快车GOI foreach (var campaignId in kuaicheCampaignIdList) { var campaign = new Product360PopularizeAnalysisCampaginRepsonse() { CampaignId = campaignId.Value, BusinessType = 2, CampaignGOI_Recent7Day = recent7DayCampaignGOIList.FirstOrDefault(x => x.LevelId == campaignId), CampaignGOI_Recent30Day = recent30DayCampaignGOIList.FirstOrDefault(x => x.LevelId == campaignId), CampaignName = allCampaignNameList.FirstOrDefault(x => x.CampaignId == campaignId)?.CampaignName }; list.Add(campaign); } #endregion #region 处理单元GOI var kuaicheAdGroupIdList = popularizeAdSkuSourceList.Where(x => x.BusinessType == 2).Select(x => x.AdGroupId).Distinct().ToList(); var recent7DayAdGroupGOIList = CalculationAdGroupLevelGOI(kuaicheAdGroupIdList, startDate_Recent7day, endDate_Recent7day); var recent30DayAdGroupGOIList = CalculationAdGroupLevelGOI(kuaicheAdGroupIdList, startDate_Recent30day, endDate_Recent30day); #endregion #region 处理单元统计 var adGroupStatisticsList = kuaicheCampaignSourceList.GroupBy(x => x.AdGroupId); var adGroupIdList = adGroupStatisticsList.Select(x => x.Key).ToList(); var allAdGroupList = new List(); var allAdGroupNameList = fsql.Select() .Where(x => x.ShopId == request.ShopId && adGroupIdList.Contains(x.AdGroupId)) .GroupBy(x => new { x.AdGroupId, x.AdGroupName }) .ToList(g => new { g.Value.AdGroupId, g.Value.AdGroupName }); foreach (var adGroupStatistics in adGroupStatisticsList) { var adGroupId = adGroupStatistics.Key; var adGroup = new Product360PopularizeAnalysisAdGroupResponse() { AdGroupId = adGroupId.Value, AdGroupName = allAdGroupNameList.FirstOrDefault(x => x.AdGroupId == adGroupId)?.AdGroupName, 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), AdGroupGOI_Recent7Day = recent7DayAdGroupGOIList.FirstOrDefault(x => x.LevelId == adGroupId), AdGroupGOI_Recent30Day = recent30DayAdGroupGOIList.FirstOrDefault(x => x.LevelId == adGroupId) }; allAdGroupList.Add(adGroup); var campagin = list.FirstOrDefault(x => x.CampaignId == adGroup.CampaignId); if (campagin != null) campagin.AdGroupList.Add(adGroup); } #endregion #endregion #region 处理京速推 #region 处理京速推GOI和统计 var jstCampaignStatisticsList = jstCampaignSourceList.GroupBy(x => x.CampaignId); foreach (var jstCampaignStatistics in jstCampaignStatisticsList) { var campaignId = jstCampaignStatistics.Key; var jstCampaign = new Product360PopularizeAnalysisCampaginRepsonse() { CampaignId = campaignId.Value, CampaignName = allCampaignNameList.FirstOrDefault(x => x.CampaignId == campaignId)?.CampaignName, BusinessType = 134217728, CampaignGOI_Recent7Day = recent7DayCampaignGOIList.FirstOrDefault(x => x.LevelId == campaignId), CampaignGOI_Recent30Day = recent30DayCampaignGOIList.FirstOrDefault(x => x.LevelId == campaignId), Clicks = jstCampaignStatistics.Sum(x => x.Clicks), Cost = jstCampaignStatistics.Sum(x => x.Cost), Impressions = jstCampaignStatistics.Sum(x => x.Impressions), OrderCnt = jstCampaignStatistics.Sum(x => x.TotalOrderCnt) }; } #endregion #endregion return new ListResponse() { ItemList = list, Count = list.Count }; } public ListResponse QueryProduct360HistogramStatistics(JDXXHistogramRequest request) { var startDate = DateTime.Now.Date.AddDays(-14); var endDate = DateTime.Now.Date.AddSeconds(-1); var list = fsql.Select().Where(s => request.SkuList.Contains(s.Sku)) .Where(s => s.CreateTime >= startDate && s.CreateTime <= endDate) .ToList(s => new JDXXHistogramResponse() { UV = s.Uv, Sales = s.Sales, Profit = s.Profits, TotalCost = s.TotalCost }); return new ListResponse() { Count = list.Count, ItemList = list }; } } }