diff --git a/BBWYB.Server.API/Controllers/ProductSyncController.cs b/BBWYB.Server.API/Controllers/ProductSyncController.cs index b196c48..1fa2ace 100644 --- a/BBWYB.Server.API/Controllers/ProductSyncController.cs +++ b/BBWYB.Server.API/Controllers/ProductSyncController.cs @@ -1,4 +1,6 @@ -using BBWYB.Server.Business.Sync; +using BBWYB.Server.Business; +using BBWYB.Server.Business.Sync; +using BBWYB.Server.Model; using Microsoft.AspNetCore.Mvc; namespace BBWYB.Server.API.Controllers @@ -19,5 +21,24 @@ namespace BBWYB.Server.API.Controllers { productSyncBusiness.SyncAllShopAllProduct(); } + + /// + /// 同步所有店铺最近变化产品 + /// + [HttpPost] + public void SyncAllShopUpdateProduct() + { + productSyncBusiness.SyncAllShopUpdateProduct(); + } + + /// + /// 同步指定店铺最近变化产品 + /// + /// + [HttpPost("{shopId}")] + public void SyncOneShopUpdateProduct([FromRoute] long shopId) + { + productSyncBusiness.SyncOneShopUpdateProduct(shopId); + } } } diff --git a/BBWYB.Server.Business/Sync/ProductSyncBusiness.cs b/BBWYB.Server.Business/Sync/ProductSyncBusiness.cs index 04b1440..c466336 100644 --- a/BBWYB.Server.Business/Sync/ProductSyncBusiness.cs +++ b/BBWYB.Server.Business/Sync/ProductSyncBusiness.cs @@ -37,7 +37,21 @@ namespace BBWYB.Server.Business.Sync public void SyncAllShopUpdateProduct() { + var shopList = venderBusiness.GetShopList(platform: Enums.Platform.拳探); + //var shopList = venderBusiness.GetShopList(shopId: 9); + foreach (var shop in shopList) + { + Task.Factory.StartNew(() => SyncUpdateProduct(shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncProductTaskScheduler); + } + } + public void SyncOneShopUpdateProduct(long shopId) + { + var shopList = venderBusiness.GetShopList(shopId, platform: Enums.Platform.拳探); + foreach (var shop in shopList) + { + Task.Factory.StartNew(() => SyncUpdateProduct(shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncProductTaskScheduler); + } } @@ -285,7 +299,194 @@ namespace BBWYB.Server.Business.Sync private void SyncUpdateProduct(ShopResponse shop) { + try + { + List dbProductList; + List dbProductSkuList; + List opProductList = new List(); + List opProductSkuList = new List(); + + List insertProductList = new List(); + List insertProductSkuList = new List(); + List> updateProductList = new List>(); + List> updateProductSkuList = new List>(); + + #region 查询变化的spu + var spuRequest = new OP_QueryProductRequest() + { + PageSize = 50, + PageIndex = 1, + AppKey = shop.AppKey, + AppSecret = shop.AppSecret, + AppToken = shop.AppToken, + Platform = SDKAdapter.AdapterEnums.PlatformType.拳探, + UpdateStartTime = DateTime.Now.AddHours(-1), + UpdateEndTime = DateTime.Now + }; + while (true) + { + var response = productBusiness.GetProductList(spuRequest); + if (response == null || response.Items == null || response.Items.Count == 0) + break; + + opProductList.AddRange(response.Items); + if (response.Items.Count < 50) + break; + + spuRequest.PageIndex++; + } + #endregion + + #region 对比spu + + var spuIdList = opProductList.Select(x => x.Id); + dbProductList = fsql.Select(spuIdList).ToList(); + + #region 找出新增的产品 + var newProductList = opProductList.Where(p => !dbProductList.Any(dp => dp.Id == p.Id)).ToList(); + if (newProductList.Count() > 0) + { + insertProductList.AddRange(newProductList.Select(p => new Product() + { + Id = p.Id, + Logo = p.Logo, + ProductName = p.Title, + ShopId = int.Parse(shop.ShopId), + State = p.State, + SyncTime = DateTime.Now, + UpdateTime = p.UpdateTime, + UpperTime = p.CreateTime, + CategoryId = p.CategoryId, + CategoryName = p.CategoryName + })); + } + #endregion + + #region 找出变化的产品 (状态,标题,类目) + var stateChangeProductList = opProductList.Where(p => dbProductList.Any(dp => dp.Id == p.Id && + (dp.State != p.State || + dp.ProductName != p.Title || + dp.CategoryId != p.CategoryId))).ToList(); + if (stateChangeProductList.Count() > 0) + { + foreach (var product in stateChangeProductList) + { + var update = fsql.Update(product.Id).Set(p => p.State, product.State) + .Set(p => p.ProductName, product.Title) + .Set(p => p.CategoryId, product.CategoryId) + .Set(p => p.CategoryName, product.CategoryName) + .Set(p => p.UpdateTime, product.UpdateTime); + updateProductList.Add(update); + } + } + #endregion + + #endregion + + #region 查询变化的sku + + var skuRequest = new OP_QueryProductSkuRequest() + { + AppKey = shop.AppKey, + AppSecret = shop.AppSecret, + AppToken = shop.AppToken, + Platform = SDKAdapter.AdapterEnums.PlatformType.拳探, + //Spu = product.Id, + PageSize = 50, + PageIndex = 1, + UpdateStartTime = DateTime.Now.AddHours(-1), + UpdateEndTime = DateTime.Now + }; + while (true) + { + var response = productBusiness.GetProductSkuList(skuRequest); + if (response == null || response.Items == null || response.Items.Count == 0) + break; + + opProductSkuList.AddRange(response.Items); + if (response.Items.Count < 50) + break; + + skuRequest.PageIndex++; + } + #endregion + + #region 对比sku + + var skuIdList = opProductSkuList.Select(x => x.Id); + dbProductSkuList = fsql.Select(skuIdList).ToList(); + + #region 找出新增的SKU + var newProductSkuList = opProductSkuList.Where(ps => !dbProductSkuList.Any(dps => dps.Id == ps.Id)).ToList(); + if (newProductSkuList.Count() > 0) + { + insertProductSkuList.AddRange(newProductSkuList.Select(ps => new ProductSku() + { + Id = ps.Id, + Logo = ps.Logo, + Price = ps.Price, + ProductId = ps.ProductId, + ShopId = int.Parse(shop.ShopId), + SkuName = ps.Title, + State = ps.State, + SyncTime = DateTime.Now, + UpdateTime = ps.UpdateTime, + UpperTime = ps.CreateTime, + CategoryId = ps.CategoryId, + CategoryName = ps.CategoryName + })); + } + #endregion + #region 找出状态变化的SKU + var stateChangeProductSkuList = opProductSkuList.Where(ps => dbProductSkuList.Any(dps => dps.Id == ps.Id && + (dps.State != ps.State || + dps.SkuName != ps.Title || + dps.Price != ps.Price || + dps.Logo != ps.Logo || + dps.CategoryId != ps.CategoryId))).ToList(); + if (stateChangeProductSkuList.Count() > 0) + { + foreach (var productSku in stateChangeProductSkuList) + { + var update = fsql.Update(productSku.Id).Set(ps => ps.State, productSku.State) + .Set(ps => ps.SkuName, productSku.Title) + .Set(ps => ps.Price, productSku.Price) + .Set(ps => ps.Logo, productSku.Logo) + .Set(ps => ps.CategoryId, productSku.CategoryId) + .Set(ps => ps.CategoryName, productSku.CategoryName) + .Set(ps => ps.UpdateTime, productSku.UpdateTime); + updateProductSkuList.Add(update); + } + } + #endregion + + #endregion + + #region 数据库操作 + fsql.Transaction(() => + { + if (insertProductList.Count() > 0) + fsql.Insert(insertProductList).ExecuteAffrows(); + if (insertProductSkuList.Count() > 0) + fsql.Insert(insertProductSkuList).ExecuteAffrows(); + if (updateProductList.Count() > 0) + { + foreach (var update in updateProductList) + update.ExecuteAffrows(); + } + if (updateProductSkuList.Count() > 0) + { + foreach (var update in updateProductSkuList) + update.ExecuteAffrows(); + } + }); + #endregion + } + catch (Exception ex) + { + nLogManager.Default().Error(ex, $"SyncProduct ShopId:{shop.ShopName}"); + } } } } diff --git a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs index 186f08d..28ea707 100644 --- a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs +++ b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs @@ -15,5 +15,9 @@ public int page { get; set; } = 1; public int pageSize { get; set; } = 20; + + public DateTime? updateStart { get; set; } + + public DateTime? updateEnd { get; set; } } } diff --git a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs index 758f780..d95d6fe 100644 --- a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs +++ b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs @@ -9,5 +9,9 @@ public int page { get; set; } = 1; public int pageSize { get; set; } = 20; + + public DateTime? updateStart { get; set; } + + public DateTime? updateEnd { get; set; } } } diff --git a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs index a0c9e7c..f130742 100644 --- a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs +++ b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs @@ -21,6 +21,8 @@ public string CategoryName { get; set; } public string CategoryPath { get; set; } + + public DateTime? UpdateTime { get; set; } } public class QuanTan_Supplier_ProductListResponse : QuanTanListResponse diff --git a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs index d3adf89..b0baad3 100644 --- a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs +++ b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs @@ -26,6 +26,8 @@ public int? Status { get; set; } public DateTime? UpperTime { get; set; } + + public DateTime? UpdateTime { get; set;} } public class QuanTan_Supplier_ProductSkuListResponse : QuanTanListResponse diff --git a/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs b/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs index 5eba23d..f8e7a9e 100644 --- a/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs +++ b/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs @@ -31,7 +31,9 @@ namespace SDKAdapter.OperationPlatform.Client page = request.PageIndex, pageSize = request.PageSize, productId = request.Spu, - storeId = request.AppToken + storeId = request.AppToken, + updateStart = request.UpdateStartTime, + updateEnd = request.UpdateEndTime }, request.AppKey, request.AppSecret); if (qtResponse.Status != 200) @@ -50,7 +52,8 @@ namespace SDKAdapter.OperationPlatform.Client State = qtp.IsShow == 1 && qtp.Status == 1 ? 1 : 0, Title = qtp.ProductName, CategoryId = qtp.CategoryId, - CategoryName = qtp.CategoryName + CategoryName = qtp.CategoryName, + UpdateTime = qtp.UpdateTime }).ToList() }; } @@ -63,7 +66,9 @@ namespace SDKAdapter.OperationPlatform.Client pageSize = request.PageSize, storeId = request.AppToken, productId = request.Spu, - productSku = request.Sku + productSku = request.Sku, + updateStart = request.UpdateStartTime, + updateEnd = request.UpdateEndTime }, request.AppKey, request.AppSecret); if (qtResponse.Status != 200) @@ -82,7 +87,8 @@ namespace SDKAdapter.OperationPlatform.Client State = qtps.IsShow == 1 && qtps.Status == 1 ? 1 : 0, Title = qtps.SkuName, CategoryId = qtps.CategoryId, - CategoryName = qtps.CategoryName + CategoryName = qtps.CategoryName, + UpdateTime = qtps.UpdateTime }).ToList() }; } diff --git a/SDKAdapter/OperationPlatform/Models/Request/Product/OP_QueryProductSkuRequest.cs b/SDKAdapter/OperationPlatform/Models/Request/Product/OP_QueryProductSkuRequest.cs index d0b7b6b..6e437c5 100644 --- a/SDKAdapter/OperationPlatform/Models/Request/Product/OP_QueryProductSkuRequest.cs +++ b/SDKAdapter/OperationPlatform/Models/Request/Product/OP_QueryProductSkuRequest.cs @@ -21,5 +21,15 @@ /// 每页记录数 /// public int PageSize { get; set; } + + /// + /// 最后修改开始时间 + /// + public DateTime? UpdateStartTime { get; set; } + + /// + /// 最后修改结束时间 + /// + public DateTime? UpdateEndTime { get; set; } } } diff --git a/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductResponse.cs b/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductResponse.cs index 5dc1a8a..9bc8032 100644 --- a/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductResponse.cs +++ b/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductResponse.cs @@ -42,6 +42,11 @@ /// 分类名称 /// public string CategoryName { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } } } diff --git a/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductSkuResponse.cs b/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductSkuResponse.cs index bf72943..0e6eb94 100644 --- a/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductSkuResponse.cs +++ b/SDKAdapter/OperationPlatform/Models/Response/Product/OP_ProductSkuResponse.cs @@ -39,5 +39,10 @@ /// 分类名称 /// public string CategoryName { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } } }