diff --git a/BBWY.Server.API/Controllers/JDReportFormStatisticsController.cs b/BBWY.Server.API/Controllers/JDReportFormStatisticsController.cs new file mode 100644 index 00000000..cb66fd43 --- /dev/null +++ b/BBWY.Server.API/Controllers/JDReportFormStatisticsController.cs @@ -0,0 +1,52 @@ +using BBWY.Server.Business.Statistics; +using BBWY.Server.Model.Dto; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; + +namespace BBWY.Server.API.Controllers +{ + + public class JDReportFormStatisticsController : BaseApiController + { + private JDReportFormStatisticsBusiness jDReportFormStatisticsBusiness; + + public JDReportFormStatisticsController(IHttpContextAccessor httpContextAccessor, JDReportFormStatisticsBusiness jDReportFormStatisticsBusiness) : base(httpContextAccessor) + { + this.jDReportFormStatisticsBusiness = jDReportFormStatisticsBusiness; + } + + /// + /// 计划维度GOI计算,支持快车和京速推 + /// + /// + /// + [HttpPost] + public IList CalculationCampaignLevelGOI([FromBody]GOIRequest gOIRequest) + { + return jDReportFormStatisticsBusiness.CalculationCampaignLevelGOI(gOIRequest); + } + + /// + /// 单元维度GOI计算,仅支持快车 + /// + /// + /// + [HttpPost] + public IList CalculationAdGroupLevelGOI([FromBody] GOIRequest gOIRequest) + { + return jDReportFormStatisticsBusiness.CalculationAdGroupLevelGOI(gOIRequest); + } + + /// + /// 创意维度GOI计算,仅支持快车 + /// + /// + /// + [HttpPost] + public IList CalculationAdLevelGOI([FromBody] GOIRequest gOIRequest) + { + return jDReportFormStatisticsBusiness.CalculationAdLevelGOI(gOIRequest); + } + } +} diff --git a/BBWY.Server.Business/Statistics/JDReportFormStatisticsBusiness.cs b/BBWY.Server.Business/Statistics/JDReportFormStatisticsBusiness.cs new file mode 100644 index 00000000..8df02de0 --- /dev/null +++ b/BBWY.Server.Business/Statistics/JDReportFormStatisticsBusiness.cs @@ -0,0 +1,307 @@ +using BBWY.Common.Models; +using BBWY.Server.Model.Db; +using BBWY.Server.Model.Dto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Yitter.IdGenerator; + +namespace BBWY.Server.Business.Statistics +{ + public class JDReportFormStatisticsBusiness : BaseBusiness, IDenpendency + { + public JDReportFormStatisticsBusiness(IFreeSql fsql, NLog.ILogger logger, IIdGenerator idGenerator) : base(fsql, logger, idGenerator) + { + + } + + public IList CalculationCampaignLevelGOI(GOIRequest gOIRequest) + { + var _7dEndDate = DateTime.Now.Date.AddDays(-1); + var _7dStartDate = _7dEndDate.AddDays(-6); + var _7dEndTime = _7dEndDate.AddDays(1).AddSeconds(-1); + + var _30dEndDate = DateTime.Now.Date.AddDays(-1); + var _30dStartDate = _30dEndDate.AddDays(-29); + var _30dEndTime = _30dEndDate.AddDays(1).AddSeconds(-1); + + var customEndTime = gOIRequest.EndDate.AddDays(1).AddSeconds(-1); + + var _7dCampaignCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.CampaignId.Value) && + x.Date >= _7dStartDate && + x.Date <= _7dEndDate) + .GroupBy(x => x.CampaignId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + CampaignId = g.Key + }); + + var _7dCampaignProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.CampaignId.Value) && + jr.OrderTime >= _7dStartDate && + jr.OrderTime <= _7dEndTime) + .GroupBy((jr, oc) => jr.CampaignId) + .ToList(g => new + { + CampaignId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var _30dCampaignCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.CampaignId.Value) && + x.Date >= _30dStartDate && + x.Date <= _30dEndDate) + .GroupBy(x => x.CampaignId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + CampaignId = g.Key + }); + + var _30dCampaignProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.CampaignId.Value) && + jr.OrderTime >= _30dStartDate && + jr.OrderTime <= _30dEndTime) + .GroupBy((jr, oc) => jr.CampaignId) + .ToList(g => new + { + CampaignId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var customDaysCampaignCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.CampaignId.Value) && + x.Date >= gOIRequest.StartDate && + x.Date <= gOIRequest.EndDate) + .GroupBy(x => x.CampaignId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + CampaignId = g.Key + }); + + var customDaysCampaignProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.CampaignId.Value) && + jr.OrderTime >= gOIRequest.StartDate && + jr.OrderTime <= customEndTime) + .GroupBy((jr, oc) => jr.CampaignId) + .ToList(g => new + { + CampaignId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var list = new List(); + foreach (var levelId in gOIRequest.LevelIdList) + { + var goiResponse = new JDMultiLevelGOIResponse() + { + LevelId = levelId, + BusinessType = gOIRequest.BusinessType + }; + goiResponse._7GOI.Cost = _7dCampaignCosts.FirstOrDefault(x => x.CampaignId == levelId)?.Cost ?? 0M; + goiResponse._7GOI.Profit = _7dCampaignProfits.FirstOrDefault(x => x.CampaignId == levelId)?.Profit ?? 0M; + + goiResponse._30GOI.Cost = _30dCampaignCosts.FirstOrDefault(x => x.CampaignId == levelId)?.Cost ?? 0M; + goiResponse._30GOI.Profit = _30dCampaignProfits.FirstOrDefault(x => x.CampaignId == levelId)?.Profit ?? 0M; + + goiResponse.CustomDaysGOI.Cost = customDaysCampaignCosts.FirstOrDefault(x => x.CampaignId == levelId)?.Cost ?? 0M; + goiResponse.CustomDaysGOI.Profit = customDaysCampaignProfits.FirstOrDefault(x => x.CampaignId == levelId)?.Profit ?? 0M; + list.Add(goiResponse); + } + return list; + } + + public IList CalculationAdGroupLevelGOI(GOIRequest gOIRequest) + { + var _7dEndDate = DateTime.Now.Date.AddDays(-1); + var _7dStartDate = _7dEndDate.AddDays(-6); + var _7dEndTime = _7dEndDate.AddDays(1).AddSeconds(-1); + + var _30dEndDate = DateTime.Now.Date.AddDays(-1); + var _30dStartDate = _30dEndDate.AddDays(-29); + var _30dEndTime = _30dEndDate.AddDays(1).AddSeconds(-1); + + var customEndTime = gOIRequest.EndDate.AddDays(1).AddSeconds(-1); + + var _7dAdGroupCosts = 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 = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && + jr.OrderTime >= _7dStartDate && + jr.OrderTime <= _7dEndTime) + .GroupBy((jr, oc) => jr.AdGroupId) + .ToList(g => new + { + AdGroupId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var _30dAdGroupCosts = 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 = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && + jr.OrderTime >= _30dStartDate && + jr.OrderTime <= _30dEndTime) + .GroupBy((jr, oc) => 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) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdGroupId.Value) && + jr.OrderTime >= gOIRequest.StartDate && + jr.OrderTime <= customEndTime) + .GroupBy((jr, oc) => jr.AdGroupId) + .ToList(g => new + { + AdGroupId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var list = new List(); + foreach (var levelId in gOIRequest.LevelIdList) + { + var goiResponse = new JDMultiLevelGOIResponse() + { + LevelId = levelId, + BusinessType = gOIRequest.BusinessType + }; + goiResponse._7GOI.Cost = _7dAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M; + goiResponse._7GOI.Profit = _7dAdGroupProfits.FirstOrDefault(x => x.AdGroupId == levelId)?.Profit ?? 0M; + + goiResponse._30GOI.Cost = _30dAdGroupCosts.FirstOrDefault(x => x.AdGroupId == levelId)?.Cost ?? 0M; + goiResponse._30GOI.Profit = _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; + list.Add(goiResponse); + } + return list; + } + + public IList CalculationAdLevelGOI(GOIRequest gOIRequest) + { + var _7dEndDate = DateTime.Now.Date.AddDays(-1); + var _7dStartDate = _7dEndDate.AddDays(-6); + var _7dEndTime = _7dEndDate.AddDays(1).AddSeconds(-1); + + var _30dEndDate = DateTime.Now.Date.AddDays(-1); + var _30dStartDate = _30dEndDate.AddDays(-29); + var _30dEndTime = _30dEndDate.AddDays(1).AddSeconds(-1); + + var customEndTime = gOIRequest.EndDate.AddDays(1).AddSeconds(-1); + + var _7dAdCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdId.Value) && + x.Date >= _7dStartDate && + x.Date <= _7dEndDate) + .GroupBy(x => x.AdId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + AdId = g.Key + }); + + var _7dAdProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdId.Value) && + jr.OrderTime >= _7dStartDate && + jr.OrderTime <= _7dEndTime) + .GroupBy((jr, oc) => jr.AdId) + .ToList(g => new + { + AdId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var _30dAdCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdId.Value) && + x.Date >= _30dStartDate && + x.Date <= _30dEndDate) + .GroupBy(x => x.AdId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + AdId = g.Key + }); + + var _30dAdProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdId.Value) && + jr.OrderTime >= _30dStartDate && + jr.OrderTime <= _30dEndTime) + .GroupBy((jr, oc) => jr.AdId) + .ToList(g => new + { + AdId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var customDaysAdCosts = fsql.Select().Where(x => gOIRequest.LevelIdList.Contains(x.AdId.Value) && + x.Date >= gOIRequest.StartDate && + x.Date <= gOIRequest.EndDate) + .GroupBy(x => x.AdId) + .ToList(g => new + { + Cost = g.Sum(g.Value.Cost), + AdId = g.Key + }); + + var customDaysAdProfits = fsql.Select().InnerJoin((jr, oc) => jr.OrderId == oc.OrderId) + .Where((jr, oc) => gOIRequest.LevelIdList.Contains(jr.AdId.Value) && + jr.OrderTime >= gOIRequest.StartDate && + jr.OrderTime <= customEndTime) + .GroupBy((jr, oc) => jr.AdId) + .ToList(g => new + { + AdId = g.Key, + Profit = g.Sum(g.Value.Item2.Profit) + }); + + var list = new List(); + foreach (var levelId in gOIRequest.LevelIdList) + { + var goiResponse = new JDMultiLevelGOIResponse() + { + LevelId = levelId, + BusinessType = gOIRequest.BusinessType + }; + goiResponse._7GOI.Cost = _7dAdCosts.FirstOrDefault(x => x.AdId == levelId)?.Cost ?? 0M; + goiResponse._7GOI.Profit = _7dAdProfits.FirstOrDefault(x => x.AdId == levelId)?.Profit ?? 0M; + + goiResponse._30GOI.Cost = _30dAdCosts.FirstOrDefault(x => x.AdId == levelId)?.Cost ?? 0M; + goiResponse._30GOI.Profit = _30dAdProfits.FirstOrDefault(x => x.AdId == levelId)?.Profit ?? 0M; + + goiResponse.CustomDaysGOI.Cost = customDaysAdCosts.FirstOrDefault(x => x.AdId == levelId)?.Cost ?? 0M; + goiResponse.CustomDaysGOI.Profit = customDaysAdProfits.FirstOrDefault(x => x.AdId == levelId)?.Profit ?? 0M; + list.Add(goiResponse); + } + return list; + } + } +} diff --git a/BBWY.Server.Model/Dto/Request/Statistics/GOIRequest.cs b/BBWY.Server.Model/Dto/Request/Statistics/GOIRequest.cs new file mode 100644 index 00000000..885c6008 --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/Statistics/GOIRequest.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BBWY.Server.Model.Dto +{ + public class GOIRequest + { + /// + /// 维度Id数组 + /// + public IList LevelIdList { get; set; } + + /// + /// 业务线 快车=2,京速推=134217728 + /// 计划维度支持快车,京速推 + /// 单元维度仅支持快车 + /// 创意维度仅支持快车 + /// SKU维度仅支持京速推 + /// + public int BusinessType { get; set; } + + public DateTime StartDate { get; set; } + + public DateTime EndDate { get; set; } + } + + public class SkuGOIRequest: GOIRequest + { + public new IList LevelIdList { get; set; } + } +} diff --git a/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/GOIResponse.cs b/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/GOIResponse.cs new file mode 100644 index 00000000..9391475f --- /dev/null +++ b/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/GOIResponse.cs @@ -0,0 +1,19 @@ +using System; + +namespace BBWY.Server.Model.Dto +{ + public class GOIResponse + { + public decimal Cost { get; set; } + + public decimal Profit { get; set; } + + public decimal GOI + { + get + { + return Cost == 0M ? 0M : Math.Round(Profit / Cost, 2); + } + } + } +} diff --git a/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/JDMultiLevelGOIResponse.cs b/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/JDMultiLevelGOIResponse.cs new file mode 100644 index 00000000..a3b56ca3 --- /dev/null +++ b/BBWY.Server.Model/Dto/Response/Statistics/JDReportForm/JDMultiLevelGOIResponse.cs @@ -0,0 +1,25 @@ +namespace BBWY.Server.Model.Dto +{ + public class JDMultiLevelGOIResponse + { + public JDMultiLevelGOIResponse() + { + _7GOI = new GOIResponse(); + _30GOI = new GOIResponse(); + CustomDaysGOI = new GOIResponse(); + } + + public long LevelId { get; set; } + + /// + /// 快车=2 京速推=134217728 + /// + public int BusinessType { get; set; } + + public GOIResponse _7GOI { get; set; } + + public GOIResponse _30GOI { get; set; } + + public GOIResponse CustomDaysGOI { get; set; } + } +}