using BBWY.Common.Extensions; using BBWY.Common.Http; using BBWY.Common.Models; using BBWY.Server.Model; using BBWY.Server.Model.Db; using BBWY.Server.Model.Dto; using FreeSql; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using Yitter.IdGenerator; 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; private List preTaskStateList; private ProductBusiness productBusiness; private FreeSqlMultiDBManager freeSqlMultiDBManager; private char[] spliter; public EvaluationAssistantBusiness(RestApiService restApiService, IOptions options, YunDingBusiness yunDingBusiness, IFreeSql fsql, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager, VenderBusiness venderBusiness, DingDingBusiness dingDingBusiness, NLogManager nLogManager, ProductBusiness productBusiness, FreeSqlMultiDBManager freeSqlMultiDBManager) : base(restApiService, options, yunDingBusiness) { this.fsql = fsql; this.idGenerator = idGenerator; this.taskSchedulerManager = taskSchedulerManager; this.venderBusiness = venderBusiness; this.dingDingBusiness = dingDingBusiness; this.nLogManager = nLogManager; this.productBusiness = productBusiness; this.freeSqlMultiDBManager = freeSqlMultiDBManager; validOrderStateList = new List() { Enums.OrderState.待出库, Enums.OrderState.待收货, Enums.OrderState.暂停, Enums.OrderState.等待采购, Enums.OrderState.已完成, Enums.OrderState.锁定 }; preTaskStateList = new List() { Enums.PromitionTaskStatus.等待, Enums.PromitionTaskStatus.进行中 }; spliter = new char[] { ',' }; } #region 赠品模板 public void AddOrEditGiftTemplate(AddOrEditGiftTemplateRequest request) { if (string.IsNullOrEmpty(request.TemplateName)) throw new BusinessException("缺少模板名称"); if (request.GiftSkuList == null || request.GiftSkuList.Count() == 0) throw new BusinessException("缺少赠品SKU"); IInsert insert = null; IUpdate update = null; IDelete delete = null; List inserList = null; long giftTemplateId = request.Id; if (giftTemplateId == 0) { giftTemplateId = idGenerator.NewLong(); var giftTemplate = new GiftTemplate() { Id = giftTemplateId, CreateTime = DateTime.Now, TemplateName = request.TemplateName, Platform = Enums.Platform.京东, ShopId = request.ShopId, TemplateSpu = request.TemplateSpu, GiftCount = request.GiftSkuList.Count() }; insert = fsql.Insert(giftTemplate); } else { update = fsql.Update(giftTemplateId).Set(g => g.TemplateName, request.TemplateName) .Set(g => g.TemplateSpu, request.TemplateSpu) .Set(g => g.GiftCount, request.GiftSkuList.Count()); delete = fsql.Delete().Where(gs => gs.GiftTemplateId == giftTemplateId); } inserList = request.GiftSkuList.Select(gs => new GiftTemplateSku() { Id = idGenerator.NewLong(), CreateTime = DateTime.Now, GiftTemplateId = giftTemplateId, Logo = gs.Logo, Price = gs.Price, Title = gs.Title, ShopId = request.ShopId, SkuId = gs.SkuId, SpuId = request.TemplateSpu }).ToList(); fsql.Transaction(() => { insert?.ExecuteAffrows(); update?.ExecuteAffrows(); delete?.ExecuteAffrows(); fsql.Insert(inserList).ExecuteAffrows(); }); } public IList GetGiftTemplateList(long shopId) { var templateList = fsql.Select().Where(g => g.ShopId == shopId).ToList(); var templateIdList = templateList.Select(g => g.Id).ToList(); var templateSkuList = fsql.Select().Where(gs => templateIdList.Contains(gs.GiftTemplateId.Value)).ToList(); foreach (var template in templateList) { template.GiftSkuList = templateSkuList.Where(gs => gs.GiftTemplateId == template.Id).ToList(); } return templateList; } public void DeleteGiftTemplate(long giftTemplateId) { fsql.Transaction(() => { fsql.Delete(giftTemplateId).ExecuteAffrows(); fsql.Delete().Where(gs => gs.GiftTemplateId == giftTemplateId).ExecuteAffrows(); }); } #endregion #region 评价助手任务 public void AddOrEditPromotionTask(AddOrEditPromotionTaskRequest request) { if (string.IsNullOrEmpty(request.MainProductSpu)) throw new BusinessException("缺少主商品SPU"); if (request.MotherTemplateId == 0 && string.IsNullOrEmpty(request.MainProductSku) && string.IsNullOrEmpty(request.CustomMotherSku)) throw new BusinessException("奶妈模板,奶妈自定义SKU,主商品SKU至少具备一个"); if (request.GiftTemplateId == 0 && string.IsNullOrEmpty(request.MainProductGiftSku)) throw new BusinessException("赠品模板和主商品赠品SKU至少具备一个"); if (string.IsNullOrEmpty(request.FullTitle)) throw new BusinessException("缺少完整标题"); if (string.IsNullOrEmpty(request.SimpleTitle)) throw new BusinessException("缺少精简标题"); if (string.IsNullOrEmpty(request.ActivityName)) throw new BusinessException("缺少任务名称"); if (request.ActivityName.Length > 10) throw new BusinessException("任务名称不能超过10个字"); if (request.TaskCount == 0) throw new BusinessException("任务量不能为0"); if (request.GiftTemplateId != 0 && string.IsNullOrEmpty(request.OuterId)) throw new BusinessException("使用赠品模板时必须填写外部Id"); request.FullTitle = request.FullTitle.Trim(); request.ActivityName = request.ActivityName.Trim(); request.MainProductSpu = request.MainProductSpu.Trim(); if (!string.IsNullOrEmpty(request.MainProductSku)) request.MainProductSku = request.MainProductSku.Trim(); if (!string.IsNullOrEmpty(request.CustomMotherSku)) request.CustomMotherSku = request.CustomMotherSku.Trim(); if (!string.IsNullOrEmpty(request.MainProductGiftSku)) request.MainProductGiftSku = request.MainProductGiftSku.Trim(); if (request.Id == 0) { var relayAPIHost = GetPlatformRelayAPIHost(Enums.Platform.京东); var restApiResult_spu = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetProductList", new SearchProductRequest() { AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, PageIndex = 1, PageSize = 10, Platform = Enums.Platform.京东, Spu = request.MainProductSpu }, GetYunDingRequestHeader(), HttpMethod.Post); if (restApiResult_spu.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException(restApiResult_spu.Content) { Code = (int)restApiResult_spu.StatusCode }; var spuResponse = JsonConvert.DeserializeObject>(restApiResult_spu.Content); if (!spuResponse.Success) throw new BusinessException(spuResponse.Msg) { Code = spuResponse.Code }; var sort = fsql.Select().Where(pt => pt.ShopId == request.ShopId).ToAggregate(p => p.Max(p.Key.Sort)); var promotionTask = new PromotionTask() { Id = idGenerator.NewLong(), ActivityName = request.ActivityName, CreateTime = DateTime.Now, FullTitle = request.FullTitle, ShopId = request.ShopId, SimpleTitle = request.SimpleTitle, GiftTemplateId = request.GiftTemplateId, MainProductGiftSku = request.MainProductGiftSku, MainProductSku = request.MainProductSku, MainProductSpu = request.MainProductSpu, MotherTemplateId = request.MotherTemplateId, IsEnabled = true, Status = Enums.PromitionTaskStatus.等待, PromotionId = 0, Sort = sort + 1, UpdateSortTime = DateTime.Now, SpuLogo = spuResponse.Data.Items[0].Logo, SpuPublishTime = spuResponse.Data.Items[0].CreateTime, TaskCount = request.TaskCount, CustomMotherSku = request.CustomMotherSku, OuterId = request.OuterId }; fsql.Insert(promotionTask).ExecuteAffrows(); } else { var dbPromotionTask = fsql.Select(request.Id).ToOne(); if (dbPromotionTask == null) throw new BusinessException("任务不存在"); if (dbPromotionTask.Status != Enums.PromitionTaskStatus.等待) throw new BusinessException("只能在任务处于等待状态时才能修改"); request.Map(dbPromotionTask); fsql.Update().SetSource(dbPromotionTask) .IgnoreColumns(new string[] { "UpdateSortTime", "Sort", "Status", "CreateTime", "SpuLogo", "SpuPublishTime", "StartTime", "EndTime", "StopTime", "CompletedTaskCount" }) .ExecuteAffrows(); } } /// /// 获取任务列表 /// /// /// public PromotionTaskResponse GetPromotionTaskList(QueryPromotionTaskRequest request) { var list = fsql.Select().As("pt") .Where(pt => pt.ShopId == request.ShopId) .Where(pt => pt.IsEnabled == true) .OrderBy(pt => SqlExt.Case().When(pt.Status == Enums.PromitionTaskStatus.进行中, 0) .When(pt.Status == Enums.PromitionTaskStatus.等待, 1) .When(pt.Status == Enums.PromitionTaskStatus.已完成, 2) .When(pt.Status == Enums.PromitionTaskStatus.已停止, 3) .End()) //.OrderBy("case when pt.status=1 then 0 when pt.status=0 then 1 when pt.status=2 then 2 when pt.status=3 then 3 end asc") .OrderByDescending(pt => pt.Sort) .Page(request.PageIndex, request.PageSize) .Count(out long count) .ToList(); if (list.Count() > 0) { var preTaskIdList = list.Where(pt => pt.PreTaskId != null && pt.PreTaskId != -1).Select(pt => pt.PreTaskId).ToArray(); if (preTaskIdList.Count() > 0) { var preTaskList = fsql.Select(preTaskIdList).ToList(pt => new { Id = pt.Id, ActivityName = pt.ActivityName }); foreach (var preTask in preTaskList) { var ptTaskList = list.Where(pt => pt.PreTaskId == preTask.Id); foreach (var ptTask in ptTaskList) ptTask.PreTaskName = preTask.ActivityName; } } } return new PromotionTaskResponse() { Count = count, ItemList = list }; } public PromotionTaskResponse GetPrePromotionTaskList(long shopId) { var list = fsql.Select().As("pt") .Where(pt => pt.ShopId == shopId) .Where(pt => preTaskStateList.Contains(pt.Status.Value)) .Where(pt => pt.IsEnabled == true) .OrderBy(pt => SqlExt.Case().When(pt.Status == Enums.PromitionTaskStatus.进行中, 0) .When(pt.Status == Enums.PromitionTaskStatus.等待, 1) .When(pt.Status == Enums.PromitionTaskStatus.已完成, 2) .When(pt.Status == Enums.PromitionTaskStatus.已停止, 3) .End()) //.OrderBy("case when pt.status=1 then 0 when pt.status=0 then 1 when pt.status=2 then 2 when pt.status=3 then 3 end asc") .OrderByDescending(pt => pt.Sort) .Page(1, 1000) .Count(out long count) .ToList(); return new PromotionTaskResponse() { Count = count, ItemList = list }; } /// /// 设置前置任务 /// /// /// public void EditPreTask(EditPreTaskRequest request) { var pt = fsql.Select(request.TaskId).ToOne(); if (pt == null) throw new BusinessException($"{request.TaskId}任务不存在"); if (pt.Status != Enums.PromitionTaskStatus.等待) throw new BusinessException("任务状态必须为等待"); if (request.PreTaskId != -1) { var prpt = fsql.Select(request.PreTaskId).ToOne(); if (prpt == null) throw new BusinessException($"{request.PreTaskId}前置任务不存在"); if (pt.Id == prpt.Id) throw new BusinessException("前置任务不能设置为自己"); if (prpt.Status != Enums.PromitionTaskStatus.等待 && prpt.Status != Enums.PromitionTaskStatus.进行中) throw new BusinessException("前置任务状态必须为等待或进行中"); var nextPromotionTaskList = fsql.Select().Where(pt1 => pt1.PreTaskId == request.PreTaskId && pt1.IsEnabled == true).ToList(); if (nextPromotionTaskList.Count() > 0) { CheckSkuRepeat(pt, nextPromotionTaskList); } } #region 清空后代 var waitList = fsql.Select().Where(pt1 => pt1.ShopId == pt.ShopId && pt1.Id != pt.Id && pt1.PreTaskId != null && pt1.Status == Enums.PromitionTaskStatus.等待).ToList(pt1 => new PromotionTask { Id = pt1.Id, PreTaskId = pt1.PreTaskId }); var childIdList = GetChildTaskIdList(pt.Id, waitList, null); #endregion fsql.Transaction(() => { fsql.Update(request.TaskId).Set(pt1 => pt1.PreTaskId, request.PreTaskId).ExecuteAffrows(); if (childIdList.Count() > 0) fsql.Update(childIdList.ToArray()).Set(pt1 => pt1.PreTaskId, null).ExecuteAffrows(); }); } /// /// 递归找子级任务 /// /// /// /// /// public IList GetChildTaskIdList(long taskId, IList waitList, IList childIdList) { if (childIdList == null) childIdList = new List(); var childTaskList = waitList.Where(w => w.PreTaskId == taskId).ToList(); if (childTaskList.Count() != 0) { foreach (var childTask in childTaskList) { childIdList.Add(childTask.Id); GetChildTaskIdList(childTask.Id, waitList, childIdList); } } return childIdList; } private void CheckSkuRepeat(PromotionTask pt, IList waitCheckList) { var ptSkuList = new List(); var waitptSkuList = new List(); if (!string.IsNullOrEmpty(pt.MainProductSku)) ptSkuList.AddRange(pt.MainProductSku.Split(spliter, StringSplitOptions.RemoveEmptyEntries)); if (!string.IsNullOrEmpty(pt.CustomMotherSku)) ptSkuList.AddRange(pt.CustomMotherSku.Split(spliter, StringSplitOptions.RemoveEmptyEntries)); foreach (var waitPt in waitCheckList) { if (!string.IsNullOrEmpty(waitPt.MainProductSku)) waitptSkuList.AddRange(waitPt.MainProductSku.Split(spliter, StringSplitOptions.RemoveEmptyEntries)); if (!string.IsNullOrEmpty(waitPt.CustomMotherSku)) waitptSkuList.AddRange(waitPt.CustomMotherSku.Split(spliter, StringSplitOptions.RemoveEmptyEntries)); var intersectSkuList = ptSkuList.Intersect(waitptSkuList).ToList(); if (intersectSkuList != null && intersectSkuList.Count() > 0) throw new BusinessException($"任务1[{pt.ActivityName}]与任务2[{waitPt.ActivityName}]之间存在sku重复,{string.Join(",", intersectSkuList)}"); } } /// /// 修改任务排序 /// /// public void EditPromotionTaskSort(EditPromotionTaskSortRequest request) { var dbPromotionTask = fsql.Select(request.Id).ToOne(); PromotionTask oldDbPromotionTask = null; if (request.MoveType == 1) oldDbPromotionTask = fsql.Select().Where(pt => pt.Sort > dbPromotionTask.Sort).OrderBy(pt => pt.Sort).ToOne(); else oldDbPromotionTask = fsql.Select().Where(pt => pt.Sort < dbPromotionTask.Sort).OrderByDescending(pt => pt.Sort).ToOne(); if (oldDbPromotionTask != null) { fsql.Transaction(() => { fsql.Update(dbPromotionTask.Id).Set(pt => pt.Sort, oldDbPromotionTask.Sort) .Set(pt => pt.UpdateSortTime, DateTime.Now) .ExecuteAffrows(); fsql.Update(oldDbPromotionTask.Id).Set(pt => pt.Sort, dbPromotionTask.Sort) .Set(pt => pt.UpdateSortTime, DateTime.Now) .ExecuteAffrows(); }); } } /// /// 检查任务重复sku /// /// /// private void CheckRepeatSkuInRuningTask(IList runingTaskList, string skuIds) { var skuIdList = skuIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var pt in runingTaskList) { foreach (var sku in skuIdList) { //判断奶妈模板sku重复 //判断自定义奶妈sku重复 if ((!string.IsNullOrEmpty(pt.CustomMotherSku) && pt.CustomMotherSku.Contains(sku)) || (!string.IsNullOrEmpty(pt.MainProductSku) && pt.MainProductSku.Contains(sku))) { throw new BusinessException($"sku[{sku}]已存在于任务[{pt.ActivityName}]的奶妈sku中,请删除该sku或等待任务结束"); } } } } /// /// 开始任务 /// /// /// /// public void StartPromotionTask(StartPromotionTaskRequest request, ShopResponse shop = null) { var dbPromotionTask = fsql.Select(request.Id).ToOne(); if (dbPromotionTask == null) throw new BusinessException("任务不存在"); if (dbPromotionTask.Status != Enums.PromitionTaskStatus.等待) throw new BusinessException("只能在任务处于等待状态时才能开始"); if (shop == null) shop = venderBusiness.GetShopList(dbPromotionTask.ShopId, Enums.Platform.京东)?.FirstOrDefault(); if (shop == null) throw new BusinessException("未查询到店铺"); IList giftTemplateSkuList = null; //赠品模板sku var motherTemplateSku = string.Empty; //奶妈模板的sku if (dbPromotionTask.GiftTemplateId != null && dbPromotionTask.GiftTemplateId != 0) { giftTemplateSkuList = fsql.Select().Where(gs => gs.GiftTemplateId == dbPromotionTask.GiftTemplateId).ToList(gs => new GiftTemplateSkuRequest() { Logo = gs.Logo, Price = gs.Price, SkuId = gs.SkuId, Title = gs.Title }); if (giftTemplateSkuList == null || giftTemplateSkuList.Count() == 0) { throw new BusinessException("赠品模板不存在"); } } var runingTaskList = fsql.Select().Where(pt => pt.ShopId == dbPromotionTask.ShopId && pt.Status == Enums.PromitionTaskStatus.进行中 && pt.IsEnabled == true).ToList(); if (dbPromotionTask.MotherTemplateId != null && dbPromotionTask.MotherTemplateId != 0) { } if (request.IsDebug == null || request.IsDebug == false) { if (!string.IsNullOrEmpty(dbPromotionTask.CustomMotherSku)) CheckRepeatSkuInRuningTask(runingTaskList, dbPromotionTask.CustomMotherSku); if (!string.IsNullOrEmpty(motherTemplateSku)) CheckRepeatSkuInRuningTask(runingTaskList, motherTemplateSku); if (!string.IsNullOrEmpty(dbPromotionTask.MainProductSku)) CheckRepeatSkuInRuningTask(runingTaskList, dbPromotionTask.MainProductSku); } var joinSkuCount = 0; var joinSkuNoGiftList = new List(); var host = GetPlatformRelayAPIHost(Enums.Platform.京东); var haveGiftTemplateSku = giftTemplateSkuList != null && giftTemplateSkuList.Count() > 0; string barCode = string.Empty, categoryId = string.Empty; IList multiCateProps = null; var mainProductSkuInStore = false; var mainSkuResult = restApiService.SendRequest(host, "api/PlatformSDK/GetProductSkuList", new SearchProductSkuRequest() { AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, IsContainSource = true, Platform = request.Platform, Spu = dbPromotionTask.MainProductSpu }, GetYunDingRequestHeader(), HttpMethod.Post); if (mainSkuResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException($"获取主商品sku失败 {mainSkuResult.Content}"); var mainSkuListResponse = JsonConvert.DeserializeObject>>(mainSkuResult.Content); if (!mainSkuListResponse.Success) throw new BusinessException($"获取主商品sku失败 {mainSkuListResponse.Msg}"); joinSkuNoGiftList.AddRange(mainSkuListResponse.Data.Select(s => s.Id)); //开启延迟任务 if (!string.IsNullOrEmpty(dbPromotionTask.CustomMotherSku)) joinSkuNoGiftList.AddRange(dbPromotionTask.CustomMotherSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); if (haveGiftTemplateSku) { barCode = mainSkuListResponse.Data[0].Source.Value("barCode"); categoryId = mainSkuListResponse.Data[0].Source.Value("categoryId"); multiCateProps = mainSkuListResponse.Data[0].Source["multiCateProps"] != null ? mainSkuListResponse.Data[0].Source["multiCateProps"].ToList() : null; var jyStoreIdList = fsql.Select().Where(s => s.Type == Enums.StockType.京仓 || s.Name.Contains("云仓")).ToList(s => s.Id); foreach (var sku in mainSkuListResponse.Data) { var stockNumApiResult = restApiService.SendRequest(host, "api/platformsdk/GetStockNumBySku", new SearchProductSkuRequest() { AppKey = shop.AppKey, AppSecret = shop.AppSecret, AppToken = shop.AppToken, Platform = shop.PlatformId, Sku = sku.Id }, GetYunDingRequestHeader(), HttpMethod.Post); if (stockNumApiResult.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception($"{sku} {stockNumApiResult.Content}"); var stockNumListResponse = JsonConvert.DeserializeObject>(stockNumApiResult.Content); var skuStockNumList = stockNumListResponse.Data.Select(j => new { StockNum = j.Value("stockNum"), StoreId = j.Value("storeId"), SkuId = sku }); mainProductSkuInStore = skuStockNumList.Any(s => jyStoreIdList.Contains(s.StoreId)); if (mainProductSkuInStore) break; } } var httpApiResult = restApiService.SendRequest(host, "api/PlatformSDK/StartJDPromotionTask", new StartPromotionTaskRequest2() { Id = dbPromotionTask.Id, ActivityName = dbPromotionTask.ActivityName, AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, SimpleTitle = dbPromotionTask.SimpleTitle, FullTitle = dbPromotionTask.FullTitle, GiftTemplateSkuList = giftTemplateSkuList, MainProductGiftSku = dbPromotionTask.MainProductGiftSku, MainProductSku = dbPromotionTask.MainProductSku, MotherTemplateSku = motherTemplateSku, CustomMotherSku = dbPromotionTask.CustomMotherSku, MainProductSpu = dbPromotionTask.MainProductSpu, Platform = Enums.Platform.京东, ShopId = dbPromotionTask.ShopId.Value, TaskCount = dbPromotionTask.TaskCount, MainProductBarCode = barCode, MainProductCategoryId = categoryId, MainProductMultiCateProps = multiCateProps, MainProductSkuInStore = mainProductSkuInStore, OuterId = dbPromotionTask.OuterId }, GetYunDingRequestHeader(), HttpMethod.Post, timeOutSeconds: 800); if (httpApiResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException(httpApiResult.Content); var response = JsonConvert.DeserializeObject>(httpApiResult.Content); if (!response.Success) throw new BusinessException(response.Msg); var startResponse = response.Data; if (dbPromotionTask.GiftTemplateId != null && dbPromotionTask.GiftTemplateId != 0 && startResponse.DeleteGiftSkuList != null && startResponse.DeleteGiftSkuList.Count() != 0) dbPromotionTask.GiftTemplatePutNewSku = string.Join(",", startResponse.DeleteGiftSkuList); //try //{ // if (!string.IsNullOrEmpty(shop.PJZSDingDingKey) && !string.IsNullOrEmpty(shop.PJZSDingDingWebHook)) // dingDingBusiness.SendDingDingBotMessage(shop.PJZSDingDingKey, shop.PJZSDingDingWebHook, $"任务[{dbPromotionTask.ActivityName}]已开始,请及时查看任务是否正常进行"); //} //catch { } fsql.Update(request.Id).Set(pt => pt.PromotionId, startResponse.JDPromotionId) .SetIf(!string.IsNullOrEmpty(dbPromotionTask.GiftTemplatePutNewSku), pt => pt.GiftTemplatePutNewSku, dbPromotionTask.GiftTemplatePutNewSku) .Set(pt => pt.StartTime, DateTime.Now) .Set(pt => pt.EndTime, DateTime.Now.AddDays(180)) .Set(pt => pt.Status, Enums.PromitionTaskStatus.进行中) .ExecuteAffrows(); //joinSkuCount = joinSkuNoGiftList.Distinct().Count(); joinSkuNoGiftList = joinSkuNoGiftList.Distinct().ToList(); Task.Factory.StartNew(() => StartPromotionDelayTask(request, startResponse, dbPromotionTask, shop, joinSkuNoGiftList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.JDPromotionDelayTaskScheduler); } private void StartPromotionDelayTask(StartPromotionTaskRequest request, StartPromotionTaskResponse startResponse, PromotionTask promotionTask, ShopResponse shop, List joinSkuList) { var host = GetPlatformRelayAPIHost(Enums.Platform.京东); var httpApiResult = restApiService.SendRequest(host, "api/PlatformSDK/StartJDPromotionDelayTask", new StartPromotionTaskDelayRequest() { Platform = Enums.Platform.京东, AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, BrandName = startResponse.BrandName, FullTitle = promotionTask.FullTitle, JDPromotionId = startResponse.JDPromotionId, MainProductSpu = promotionTask.MainProductSpu, HaveGiftTemplate = promotionTask.GiftTemplateId != null && promotionTask.GiftTemplateId != 0, DeleteGiftSkuList = startResponse.DeleteGiftSkuList, ActivityName = promotionTask.ActivityName, JoinSkuCount = joinSkuList.Count(), JoinSkuList = joinSkuList, PJZSDingDingKey = shop.PJZSDingDingKey, PJZSDingDingWebHook = shop.PJZSDingDingWebHook }, GetYunDingRequestHeader(), HttpMethod.Post, timeOutSeconds: 500); var errorBack = new Action((id, errorMsg) => { fsql.Update(id).Set(pt => pt.Status, Enums.PromitionTaskStatus.已停止) .Set(pt => pt.ErrorMsg, errorMsg) .ExecuteAffrows(); Error(shop, $"评价助手-{shop.ShopName}", $"开始任务-延迟任务-任务Id {request.Id}", new Exception(errorMsg)); }); if (httpApiResult.StatusCode != System.Net.HttpStatusCode.OK) { errorBack(promotionTask.Id, httpApiResult.Content); return; } var response = JsonConvert.DeserializeObject>(httpApiResult.Content); if (!response.Success) { errorBack(promotionTask.Id, response.Msg); return; } } /// /// 删除任务和京东任务 /// /// public void DeletePromotionTaskAndJDTask(DeletePromotionTaskRequest request) { var dbPromotionTask = fsql.Select(request.TaskId).ToOne(); if (dbPromotionTask.IsEnabled == false) return; fsql.Transaction(() => { //fsql.Delete(request.TaskId).ExecuteAffrows(); fsql.Update(request.TaskId).Set(p => p.IsEnabled, false).ExecuteAffrows(); //fsql.Delete().Where(psr => psr.PromotionTaskId == request.TaskId).ExecuteAffrows(); }); //if (dbPromotionTask.Status != Enums.PromitionTaskStatus.等待) //{ if (dbPromotionTask.PromotionId != null && dbPromotionTask.PromotionId != 0) { var httpResult = restApiService.SendRequest(GetPlatformRelayAPIHost(Enums.Platform.京东), "api/platformsdk/DeleteJDPromotionTask", new DeleteJDPromotionTaskRequest() { AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, Platform = Enums.Platform.京东, PromotionId = dbPromotionTask.PromotionId.Value }, GetYunDingRequestHeader(), HttpMethod.Post); if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException($"【{dbPromotionTask.ActivityName}】评价助手活动删除成功,JD活动删除失败,请手动到JD后台删除,并通知技术员分析失败原因,{httpResult.Content}"); var response = JsonConvert.DeserializeObject(httpResult.Content); if (!response.Success) throw new BusinessException($"【{dbPromotionTask.ActivityName}】评价助手活动删除成功,JD活动删除失败,请手动到JD后台删除,并通知技术员分析失败原因,{response.Msg}"); } //} } public void DeletePromotionTask(long pjzsTaskId) { fsql.Transaction(() => { fsql.Delete(pjzsTaskId).ExecuteAffrows(); fsql.Delete().Where(psr => psr.PromotionTaskId == pjzsTaskId).ExecuteAffrows(); }); } /// /// 删除任务和奶妈SKU /// /// public void DeletePromotionTaskAndMotherSku(DeletePromotionTaskRequest request) { var dbPromotionTask = fsql.Select(request.TaskId).ToOne(); if (dbPromotionTask.Status != Enums.PromitionTaskStatus.等待) { List motherSkuIdList = new List(); if (dbPromotionTask.MotherTemplateId != null) { } if (!string.IsNullOrEmpty(dbPromotionTask.CustomMotherSku)) motherSkuIdList.AddRange(dbPromotionTask.CustomMotherSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); var httpResult = restApiService.SendRequest(GetPlatformRelayAPIHost(Enums.Platform.京东), "api/platformsdk/DeleteJDPromotionTaskSku", new DeleteJDPromotionTaskSkuRequest() { AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, Platform = Enums.Platform.京东, PromotionId = dbPromotionTask.PromotionId.Value, SkuId = string.Join(",", motherSkuIdList) }, GetYunDingRequestHeader(), HttpMethod.Post); if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException(httpResult.Content); var response = JsonConvert.DeserializeObject(httpResult.Content); if (!response.Success) throw new BusinessException(response.Msg); } fsql.Transaction(() => { fsql.Delete(request.TaskId).ExecuteAffrows(); fsql.Delete().Where(psr => psr.PromotionTaskId == request.TaskId).ExecuteAffrows(); }); } /// /// 停止任务 /// /// /// public void StopPromotionTask(StopPromotionTaskRequest request) { var dbPromotionTask = fsql.Select(request.Id).ToOne(); if (dbPromotionTask == null) throw new BusinessException("任务不存在"); if (dbPromotionTask.Status != Enums.PromitionTaskStatus.进行中) throw new BusinessException("只能在任务处于进行中时才能停止"); var httpResult = restApiService.SendRequest(GetPlatformRelayAPIHost(Enums.Platform.京东), "api/platformsdk/SuspendJDPromotionTask", new SuspendDPromotionTaskRequest() { AppKey = request.AppKey, AppSecret = request.AppSecret, AppToken = request.AppToken, Platform = Enums.Platform.京东, PromotionId = dbPromotionTask.PromotionId.Value }, GetYunDingRequestHeader(), HttpMethod.Post); if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException(httpResult.Content); var response = JsonConvert.DeserializeObject(httpResult.Content); if (!response.Success) { if (!response.Msg.Contains("促销已删除")) throw new BusinessException(response.Msg); } fsql.Update(request.Id).Set(pt => pt.Status, Enums.PromitionTaskStatus.已停止).ExecuteAffrows(); } public void EditPJZSSettings(PJZSShopSettingRequest request) { var shopId = request.ShopId.ToString(); freeSqlMultiDBManager.MDSfsql.Update().Set(s => s.PJZSDingDingKey, request.PJZSDingDingKey) .Set(s => s.PJZSDingDingWebHook, request.PJZSDingDingWebHook) .Where(s => s.ShopId == shopId) .ExecuteAffrows(); } #endregion #region 自动任务 public void StartMonitor(long? shopId, long? taskId) { //查询店铺 var shopList = venderBusiness.GetShopList(shopId, Enums.Platform.京东); //开始下一轮开始任务 var nextPromotionTaskList = fsql.Select().WhereIf(shopId != null, pt => pt.ShopId == shopId) .Where(pt => pt.Status == Enums.PromitionTaskStatus.等待 && pt.PreTaskId == -1 && pt.IsEnabled == true) .ToList(pt => new { Id = pt.Id, ShopId = pt.ShopId, TaskName = pt.ActivityName }); if (nextPromotionTaskList.Count() > 0) { foreach (var nextTask in nextPromotionTaskList) { var shop = shopList.FirstOrDefault(s => s.ShopId == nextTask.ShopId.ToString()); if (shop != null) { Task.Factory.StartNew(() => AutoStart(nextTask.Id, nextTask.TaskName, shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.JDPromotionAutoStartTaskScheduler); } } } //查询正在进行的任务 var runningTaskList = fsql.Select() .Where(pt => pt.IsEnabled == true) .WhereIf(shopId != null, pt => pt.ShopId == shopId) .WhereIf(taskId != null, pt => pt.Id == taskId) .WhereIf(taskId == null, 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(-2); var orderSkuList = fsql.Select() .InnerJoin((osku, o) => osku.OrderId == o.Id) .WhereIf(shopId != null, (osku, o) => o.ShopId == shopId) .Where((osku, o) => validOrderStateList.Contains(o.OrderState.Value)) //.Where((osku, o) => osku.CreateTime >= querySkuTime) .Where((osku, o) => o.ModifyTime >= 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) { 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); } } /// /// 监控 /// /// /// /// /// /// private void MonitorTaskCore(ShopResponse shop, long shopId, IList runningTaskList, IList orderSkuList, IList promotionTaskSkuRecordList) { var loggerName = $"评价助手-{shop.ShopName}"; List> updatePromotionTaskList = new List>(); List insertPromotionTaskSkuRecordList = new List(); IList jobDoneTaskIdList = new List(); IList jobDoneTaskList = new List(); foreach (var promotionTask in runningTaskList) { var productSkuList = new List(); #region 读取主商品sku { var productResponseSkuList = productBusiness.GetProductSkuList(new SearchProductSkuRequest() { AppKey = shop.AppKey2, AppSecret = shop.AppSecret2, AppToken = shop.AppToken2, IsContainSource = false, Platform = Enums.Platform.京东, Spu = promotionTask.MainProductSpu }); if (productResponseSkuList == null || productResponseSkuList.Count() == 0) { Error(shop, loggerName, $"监控任务-查询主商品sku-任务Id {promotionTask.Id}", new Exception("未查询到主商品sku信息")); continue; } productSkuList.AddRange(productResponseSkuList.Select(p => p.Id)); } #endregion if (!string.IsNullOrEmpty(promotionTask.GiftTemplatePutNewSku)) { productSkuList.AddRange(promotionTask.GiftTemplatePutNewSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); } if (!string.IsNullOrEmpty(promotionTask.MainProductGiftSku)) { productSkuList.AddRange(promotionTask.MainProductGiftSku.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); } var newOrderSkuList = orderSkuList.Where(osku => productSkuList.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; completedTaskCount += 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 && DateTime.Now > promotionTask.EndTime); 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 (DateTime.Now < promotionTask.EndTime) { #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); var httpResult = restApiService.SendRequest(GetPlatformRelayAPIHost(Enums.Platform.京东), "api/platformsdk/DeleteJDPromotionTask", new DeleteJDPromotionTaskRequest() { 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) { var msgBuilder = new StringBuilder(); msgBuilder.AppendLine($"店铺名称:{shop.ShopName}"); msgBuilder.AppendLine($"活动名称:{promotionTask.ActivityName}"); msgBuilder.AppendLine($"错误原因:{httpResult.Content}"); msgBuilder.AppendLine("删除活动失败,请手动到后台删除,并通知技术员分析失败原因"); dingDingBusiness.SendDingDingBotMessage(shop.PJZSDingDingKey, shop.PJZSDingDingWebHook, $"任务[{promotionTask.ActivityName}]删除任务失败,{httpResult.Content}"); } else { var res = JsonConvert.DeserializeObject(httpResult.Content); if (!res.Success) { var msgBuilder = new StringBuilder(); msgBuilder.AppendLine($"店铺名称:{shop.ShopName}"); msgBuilder.AppendLine($"活动名称:{promotionTask.ActivityName}"); msgBuilder.AppendLine($"错误原因:{httpResult.Content}"); msgBuilder.AppendLine("删除活动失败,请手动到后台删除,并通知技术员分析失败原因"); dingDingBusiness.SendDingDingBotMessage(shop.PJZSDingDingKey, shop.PJZSDingDingWebHook, $"任务[{promotionTask.ActivityName}]删除任务失败,{res.Msg}"); } } } #endregion } jobDoneTaskIdList.Add(promotionTask.Id); //记录完成任务 jobDoneTaskList.Add(promotionTask); } } } fsql.Transaction(() => { if (updatePromotionTaskList.Count() > 0) foreach (var update in updatePromotionTaskList) update.ExecuteAffrows(); if (insertPromotionTaskSkuRecordList.Count() > 0) fsql.Insert(insertPromotionTaskSkuRecordList).ExecuteAffrows(); }); #region 钉钉通知结束 if (!string.IsNullOrEmpty(shop.PJZSDingDingKey) && !string.IsNullOrEmpty(shop.PJZSDingDingWebHook)) { foreach (var jobDoneTask in jobDoneTaskList) { try { dingDingBusiness.SendDingDingBotMessage(shop.PJZSDingDingKey, shop.PJZSDingDingWebHook, $"任务[{jobDoneTask.ActivityName}]已结束"); } catch { } } } #endregion #region 开始后续任务 //下一轮开始任务 if (jobDoneTaskIdList.Count() > 0) { var childTaskList = fsql.Select().Where(pt => pt.ShopId == shopId && pt.Status == Enums.PromitionTaskStatus.等待 && pt.IsEnabled == true && jobDoneTaskIdList.Contains(pt.PreTaskId.Value)) .ToList(pt => new { Id = pt.Id, ShopId = pt.ShopId, TaskName = pt.ActivityName }); if (childTaskList.Count() > 0) { foreach (var task in childTaskList) { Task.Factory.StartNew(() => AutoStart(task.Id, task.TaskName, shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.JDPromotionAutoStartTaskScheduler); } } } #endregion } private void AutoStart(long taskId, string taskName, ShopResponse shop) { var loggerName = $"评价助手-{shop.ShopName}"; try { StartPromotionTask(new StartPromotionTaskRequest() { Id = taskId, AppKey = shop.AppKey2, AppSecret = shop.AppSecret2, AppToken = shop.AppToken2, Platform = Enums.Platform.京东 }, shop); } catch (Exception ex) { Error(shop, loggerName, $"AutoStart 任务[{taskName}]", ex); } } private void Error(ShopResponse shop, string loggerName, string message, Exception ex) { nLogManager.GetLogger(loggerName).Error(ex, message); //send dingding if (!string.IsNullOrEmpty(shop.PJZSDingDingKey) && !string.IsNullOrEmpty(shop.PJZSDingDingWebHook)) dingDingBusiness.SendDingDingBotMessage(shop.PJZSDingDingKey, shop.PJZSDingDingWebHook, $"评价助手\n{shop.ShopName}\n{message}\n{ex.Message}"); } #endregion } }