diff --git a/BBWY.Server.API/Controllers/EvaluationAssistantController.cs b/BBWY.Server.API/Controllers/EvaluationAssistantController.cs index 809c458c..16a39775 100644 --- a/BBWY.Server.API/Controllers/EvaluationAssistantController.cs +++ b/BBWY.Server.API/Controllers/EvaluationAssistantController.cs @@ -117,5 +117,24 @@ namespace BBWY.Server.API.Controllers { evaluationAssistantBusiness.StopPromotionTask(request); } + + /// + /// 开始监控 + /// + [HttpGet] + public void StartMonitor() + { + evaluationAssistantBusiness.StartMonitor(null); + } + + /// + /// 开始监控(按店铺) + /// + /// + [HttpGet] + public void StartMonitorByShopId(long shopId) + { + evaluationAssistantBusiness.StartMonitor(shopId); + } } } diff --git a/BBWY.Server.Business/EvaluationAssistant/EvaluationAssistantBusiness.cs b/BBWY.Server.Business/EvaluationAssistant/EvaluationAssistantBusiness.cs index dc969838..2f33e22f 100644 --- a/BBWY.Server.Business/EvaluationAssistant/EvaluationAssistantBusiness.cs +++ b/BBWY.Server.Business/EvaluationAssistant/EvaluationAssistantBusiness.cs @@ -20,19 +20,30 @@ namespace BBWY.Server.Business public class EvaluationAssistantBusiness : BasePlatformRelayBusiness, IDenpendency { private IFreeSql fsql; - private IIdGenerator idGenerator; - private TaskSchedulerManager taskSchedulerManager; - private VenderBusiness venderBusiness; + private DingDingBusiness dingDingBusiness; + private NLogManager nLogManager; + private List validOrderStateList; - public EvaluationAssistantBusiness(RestApiService restApiService, IOptions options, YunDingBusiness yunDingBusiness, IFreeSql fsql, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager, VenderBusiness venderBusiness) : base(restApiService, options, yunDingBusiness) + public EvaluationAssistantBusiness(RestApiService restApiService, IOptions options, YunDingBusiness yunDingBusiness, IFreeSql fsql, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager, VenderBusiness venderBusiness, DingDingBusiness dingDingBusiness, NLogManager nLogManager) : base(restApiService, options, yunDingBusiness) { this.fsql = fsql; this.idGenerator = idGenerator; this.taskSchedulerManager = taskSchedulerManager; this.venderBusiness = venderBusiness; + this.dingDingBusiness = dingDingBusiness; + this.nLogManager = nLogManager; + validOrderStateList = new List() + { + Enums.OrderState.待出库, + Enums.OrderState.待收货, + Enums.OrderState.暂停, + Enums.OrderState.等待采购, + Enums.OrderState.已完成, + Enums.OrderState.锁定 + }; } #region 赠品模板 @@ -484,29 +495,204 @@ namespace BBWY.Server.Business } #endregion + + + #region 自动任务 + public void StartMonitor(long? shopId) { + //查询店铺 var shopList = venderBusiness.GetShopList(shopId, Enums.Platform.京东); + //查询正在进行的任务 + var runningTaskList = fsql.Select() + .WhereIf(shopId != null, pt => pt.ShopId == shopId) + .Where(pt => pt.Status == Enums.PromitionTaskStatus.进行中).ToList(); + + if (runningTaskList == null || runningTaskList.Count() == 0) + return; + var runningTaskIdList = runningTaskList.Select(pt => pt.Id).ToList(); + + //查询订单sku + var querySkuTime = DateTime.Now.AddHours(-1); + var orderSkuList = fsql.Select() + .InnerJoin((osku, o) => osku.OrderId == o.Id) + .WhereIf(shopId != null, (osku, o) => o.ShopId == shopId) + .Where((osku, o) => o.StorageType != Enums.StorageType.SD && o.StorageType != null) + .Where((osku, o) => validOrderStateList.Contains(o.OrderState.Value)) + .Where((osku, o) => osku.Price > 0 && osku.CreateTime >= querySkuTime) + .ToList((osku, o) => new OrderSku + { + CreateTime = osku.CreateTime, + Id = osku.Id, + IsRefund = osku.IsRefund, + ItemTotal = osku.ItemTotal, + Logo = osku.Logo, + OrderDropShippingId = osku.OrderDropShippingId, + OrderId = osku.OrderId, + Price = osku.Price, + ProductId = osku.ProductId, + SkuId = osku.SkuId, + ProductNo = osku.ProductNo, + Title = osku.Title, + ShopId = o.ShopId + }); + + + //查询已记录的任务进度sku + var promotionTaskSkuRecordList = fsql.Select() + .WhereIf(shopId != null, psr => psr.ShopId == shopId) + .Where(psr => runningTaskIdList.Contains(psr.PromotionTaskId)) + .Where(psr => psr.CreateTime >= querySkuTime) + .ToList(); + foreach (var shop in shopList) { - Task.Factory.StartNew(() => MonitorTaskCore(shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.JDPromotionMonitorTaskScheduler); + var sId = long.Parse(shop.ShopId); + + var currentShopRunningTaskList = runningTaskList.Where(pt => pt.ShopId == sId).ToList(); + if (currentShopRunningTaskList == null || currentShopRunningTaskList.Count() == 0) + continue; + + var currentOrderSkuList = orderSkuList.Where(osku => osku.ShopId == sId).ToList(); + if (currentOrderSkuList == null || currentOrderSkuList.Count() == 0) + continue; + + var currentPromotionTaskSkuRecordList = promotionTaskSkuRecordList.Where(psr => psr.ShopId == sId).ToList(); + + Task.Factory.StartNew(() => MonitorTaskCore(shop, sId, currentShopRunningTaskList, currentOrderSkuList, currentPromotionTaskSkuRecordList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.JDPromotionMonitorTaskScheduler); } } - #region 自动任务 - private void MonitorTaskCore(ShopResponse shop) + /// + /// 监控 + /// + /// + /// + /// + /// + /// + private void MonitorTaskCore(ShopResponse shop, + long shopId, + IList runningTaskList, + IList orderSkuList, + IList promotionTaskSkuRecordList) { - var shopId = long.Parse(shop.ShopId); + var loggerName = $"库存预警-{shop.ShopName}"; + List> updatePromotionTaskList = new List>(); + List insertPromotionTaskSkuRecordList = new List(); + IList jobDoneTaskIdList = new List(); - #region 查询正在进行的任务 - var runningTaskList = fsql.Select().Where(pt => pt.ShopId == shopId && pt.Status == Enums.PromitionTaskStatus.进行中).ToList(); - if (runningTaskList == null || runningTaskList.Count() == 0) - return; + foreach (var promotionTask in runningTaskList) + { + var motherSkuList = new List(); + if (!string.IsNullOrEmpty(promotionTask.CustomMotherSku)) + motherSkuList.AddRange(promotionTask.CustomMotherSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + if (!string.IsNullOrEmpty(promotionTask.MainProductSku)) + motherSkuList.AddRange(promotionTask.MainProductSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + + var newOrderSkuList = orderSkuList.Where(osku => motherSkuList.Contains(osku.SkuId) && + osku.CreateTime > promotionTask.StartTime && + promotionTaskSkuRecordList.Count(psr => psr.PromotionTaskId == promotionTask.Id && + psr.OrderId == osku.OrderId) == 0).ToList(); + + //if (newOrderSkuList.Count() == 0) + // continue; + + var completedTaskCount = 0; + if (newOrderSkuList.Count() > 0) + { + foreach (var newOrderSku in newOrderSkuList) + { + completedTaskCount += newOrderSku.ItemTotal ?? 1; + insertPromotionTaskSkuRecordList.Add(new PromotionTaskSkuRecord() + { + CreateTime = DateTime.Now, + Id = idGenerator.NewLong(), + ItemTotal = newOrderSku.ItemTotal ?? 1, + OrderId = newOrderSku.OrderId, + PromotionTaskId = promotionTask.Id, + ShopId = shopId, + SkuId = newOrderSku.SkuId + }); + } + } + + promotionTask.CompletedTaskCount += completedTaskCount; + var isDone = promotionTask.CompletedTaskCount >= promotionTask.TaskCount || (promotionTask.EndTime != null && promotionTask.EndTime > DateTime.Now); + + if (completedTaskCount > 0 || isDone) + { + var updatePromotionTask = fsql.Update(promotionTask.Id) + .Set(pt => pt.CompletedTaskCount, promotionTask.CompletedTaskCount) + .SetIf(isDone, pt => pt.Status, Enums.PromitionTaskStatus.已完成) + .SetIf(isDone, pt => pt.StopTime, DateTime.Now); + updatePromotionTaskList.Add(updatePromotionTask); + + if (isDone) + { + if (promotionTask.EndTime < DateTime.Now) + { + #region 提前完成任务量,暂停JD活动 + { + var httpResult = restApiService.SendRequest(GetPlatformRelayAPIHost(Enums.Platform.京东), + "api/platformsdk/SuspendJDPromotionTask", + new SuspendDPromotionTaskRequest() + { + AppKey = shop.AppKey2, + AppSecret = shop.AppSecret2, + AppToken = shop.AppToken2, + Platform = Enums.Platform.京东, + PromotionId = promotionTask.PromotionId.Value + }, + GetYunDingRequestHeader(), + HttpMethod.Post); + + if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) + { + LogMonitorError(shop, loggerName, "自动任务-暂停京东活动", httpResult.Content); + } + else + { + var response = JsonConvert.DeserializeObject(httpResult.Content); + if (!response.Success) + { + LogMonitorError(shop, loggerName, "自动任务-暂停京东活动", response.Msg); + } + } + } + #endregion + } + + jobDoneTaskIdList.Add(promotionTask.Id); //记录完成任务 + } + } + } + fsql.Transaction(() => + { + if (updatePromotionTaskList.Count() > 0) + foreach (var update in updatePromotionTaskList) + update.ExecuteAffrows(); + if (insertPromotionTaskSkuRecordList.Count() > 0) + fsql.Insert(insertPromotionTaskSkuRecordList).ExecuteAffrows(); + }); + + #region 开始后续任务 + if (jobDoneTaskIdList.Count() > 0) + { + } #endregion } + + private void LogMonitorError(ShopResponse shop, string loggerName, string step, string error) + { + nLogManager.GetLogger(loggerName).Error($"{step},{error}"); + + //send dingding + + } #endregion } } diff --git a/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTask.cs b/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTask.cs index 3fc98774..625ddd3d 100644 --- a/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTask.cs +++ b/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTask.cs @@ -123,6 +123,11 @@ namespace BBWY.Server.Model.Db /// 已完成任务量 /// public int CompletedTaskCount { get; set; } + + /// + /// 前置任务Id + /// + public long? BeforeTaskId { get; set; } } } diff --git a/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTaskSkuRecord.cs b/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTaskSkuRecord.cs new file mode 100644 index 00000000..8b8f03b9 --- /dev/null +++ b/BBWY.Server.Model/Db/EvaluationAssistant/PromotionTaskSkuRecord.cs @@ -0,0 +1,37 @@ +using FreeSql.DataAnnotations; +using System; + +namespace BBWY.Server.Model.Db +{ + + [Table(Name = "promotiontaskskurecord", DisableSyncStructure = true)] + public partial class PromotionTaskSkuRecord + { + + [Column(IsPrimary = true)] + public long Id { get; set; } + + [ Column(DbType = "datetime")] + public DateTime? CreateTime { get; set; } + + + public int ItemTotal { get; set; } + + [Column(StringLength = 50)] + public string OrderId { get; set; } + + /// + /// pjzs活动任务Id (非京东活动Id) + /// + + public long PromotionTaskId { get; set; } + + + public long ShopId { get; set; } + + [Column(StringLength = 50)] + public string SkuId { get; set; } + + } + +} diff --git a/BBWY.Server.Model/Db/Order/OrderSku.cs b/BBWY.Server.Model/Db/Order/OrderSku.cs index c141930d..bb0165c5 100644 --- a/BBWY.Server.Model/Db/Order/OrderSku.cs +++ b/BBWY.Server.Model/Db/Order/OrderSku.cs @@ -61,6 +61,9 @@ namespace BBWY.Server.Model.Db /// [Column(DbType = "bit")] public bool IsRefund { get; set; } = false; + + [Column(IsIgnore = true)] + public long ShopId { get; set; } } }