diff --git a/BBWY.Server.API/Controllers/ProductSyncController.cs b/BBWY.Server.API/Controllers/ProductSyncController.cs
new file mode 100644
index 00000000..7b9c2f17
--- /dev/null
+++ b/BBWY.Server.API/Controllers/ProductSyncController.cs
@@ -0,0 +1,25 @@
+using BBWY.Server.Business.Sync;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace BBWY.Server.API.Controllers
+{
+
+ public class ProductSyncController : BaseApiController
+ {
+ private ProductSyncBusiness productSyncBusiness;
+ public ProductSyncController(IHttpContextAccessor httpContextAccessor, ProductSyncBusiness productSyncBusiness) : base(httpContextAccessor)
+ {
+ this.productSyncBusiness = productSyncBusiness;
+ }
+
+ ///
+ /// 全店同步产品
+ ///
+ [HttpPost]
+ public void SyncAllShopProduct()
+ {
+ productSyncBusiness.SyncAllShopProduct();
+ }
+ }
+}
diff --git a/BBWY.Server.Business/Sync/ProductSyncBusiness.cs b/BBWY.Server.Business/Sync/ProductSyncBusiness.cs
new file mode 100644
index 00000000..711eaf61
--- /dev/null
+++ b/BBWY.Server.Business/Sync/ProductSyncBusiness.cs
@@ -0,0 +1,124 @@
+using BBWY.Common.Http;
+using BBWY.Common.Models;
+using BBWY.Server.Model;
+using BBWY.Server.Model.Dto;
+using Microsoft.Extensions.Options;
+using NLog;
+using System.Threading.Tasks;
+using Yitter.IdGenerator;
+using System.Linq;
+using BBWY.Server.Model.Db;
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace BBWY.Server.Business.Sync
+{
+ public class ProductSyncBusiness : BaseSyncBusiness, IDenpendency
+ {
+ private ProductBusiness productBusiness;
+
+ public ProductSyncBusiness(RestApiService restApiService,
+ IOptions options,
+ ILogger logger,
+ IFreeSql fsql,
+ IIdGenerator idGenerator,
+ TaskSchedulerManager taskSchedulerManager,
+ VenderBusiness venderBusiness,
+ ProductBusiness productBusiness) : base(restApiService,
+ options,
+ logger,
+ fsql,
+ idGenerator,
+ taskSchedulerManager,
+ venderBusiness)
+ {
+ this.productBusiness = productBusiness;
+ }
+
+ private void SyncProduct(ShopResponse shop)
+ {
+ try
+ {
+ var shopId = long.Parse(shop.ShopId);
+ var productList = productBusiness.GetProductList(new SearchProductRequest()
+ {
+ PageSize = 50,
+ PageIndex = 1,
+ AppKey = shop.AppKey,
+ AppSecret = shop.AppSecret,
+ AppToken = shop.AppToken,
+ Platform = shop.PlatformId
+ });
+
+ if (productList == null || productList.Count == 0)
+ return;
+
+ var productIds = productList.Items.Select(p => p.Id);
+
+ var dbProductIds = fsql.Select().Where(p => p.ShopId == shopId && p.Platform == shop.PlatformId && productIds.Contains(p.Id)).ToList(p => p.Id);
+ var noExtisProductIds = productIds.Except(dbProductIds).ToList();
+ if (noExtisProductIds.Count() == 0)
+ return;
+
+ var insertProductList = productList.Items.Where(p => noExtisProductIds.Contains(p.Id)).Select(p => new Product()
+ {
+ Id = p.Id,
+ CreateTime = DateTime.Now,
+ Platform = shop.PlatformId,
+ ProductItemNum = p.ProductItemNum,
+ ShopId = shopId,
+ Title = p.Title
+ }).ToList();
+
+ var inserSkuList = new List();
+ foreach (var product in insertProductList)
+ {
+ var skuList = productBusiness.GetProductSkuList(new SearchProductSkuRequest()
+ {
+ AppKey = shop.AppKey,
+ AppSecret = shop.AppSecret,
+ AppToken = shop.AppToken,
+ Platform = shop.PlatformId,
+ Spu = product.Id
+ });
+ inserSkuList.AddRange(skuList.Select(s => new ProductSku()
+ {
+ Id = s.Id,
+ CreateTime = DateTime.Now,
+ Logo = s.Logo,
+ Platform = shop.PlatformId,
+ Price = s.Price,
+ ProductId = s.ProductId,
+ ShopId = shopId,
+ Title = s.Title
+ }));
+ }
+
+ fsql.Transaction(() =>
+ {
+ fsql.Insert(insertProductList).ExecuteAffrows();
+ fsql.Insert(inserSkuList).ExecuteAffrows();
+ });
+ }
+ catch (Exception ex)
+ {
+ var shopData = JsonConvert.SerializeObject(shop);
+ logger.Error(ex, $"SyncProduct ShopData:{shopData}");
+ }
+ }
+
+ ///
+ /// 同步所有店铺的订单
+ ///
+ public void SyncAllShopProduct()
+ {
+ var shopList = venderBusiness.GetShopList();
+ foreach (var shop in shopList)
+ {
+ Task.Factory.StartNew(() => SyncProduct(shop), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.ProductSyncTaskScheduler);
+ }
+ }
+ }
+}
+
diff --git a/BBWY.Server.Business/TaskSchedulerManager.cs b/BBWY.Server.Business/TaskSchedulerManager.cs
index 764b17e6..7e966818 100644
--- a/BBWY.Server.Business/TaskSchedulerManager.cs
+++ b/BBWY.Server.Business/TaskSchedulerManager.cs
@@ -6,6 +6,8 @@ namespace BBWY.Server.Business
{
public LimitedConcurrencyLevelTaskScheduler SyncOrderTaskScheduler { get; private set; }
+ public LimitedConcurrencyLevelTaskScheduler ProductSyncTaskScheduler { get; private set; }
+
public LimitedConcurrencyLevelTaskScheduler SyncRefundOrderTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler SyncAfterOrderTaskScheduler { get; private set; }
@@ -18,6 +20,7 @@ namespace BBWY.Server.Business
SyncRefundOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncAfterOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
+ ProductSyncTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(5);
}
}
}
diff --git a/BBWY.Server.Model/Db/Product/Product.cs b/BBWY.Server.Model/Db/Product/Product.cs
new file mode 100644
index 00000000..c20b4913
--- /dev/null
+++ b/BBWY.Server.Model/Db/Product/Product.cs
@@ -0,0 +1,39 @@
+using FreeSql.DataAnnotations;
+using System;
+
+namespace BBWY.Server.Model.Db
+{
+
+ [Table(Name = "product", DisableSyncStructure = true)]
+ public partial class Product {
+
+ ///
+ /// SPU
+ ///
+ [Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
+ public string Id { get; set; }
+
+ [Column(DbType = "datetime")]
+ public DateTime? CreateTime { get; set; }
+
+ [Column(DbType = "int(1)", MapType = typeof(int))]
+ public Enums.Platform Platform { get; set; }
+
+ ///
+ /// 货号
+ ///
+ [Column(StringLength = 100)]
+ public string ProductItemNum { get; set; }
+
+
+ public long? ShopId { get; set; }
+
+ ///
+ /// 标题
+ ///
+
+ public string Title { get; set; }
+
+ }
+
+}
diff --git a/BBWY.Server.Model/Db/Product/ProductSku.cs b/BBWY.Server.Model/Db/Product/ProductSku.cs
new file mode 100644
index 00000000..1fb50e41
--- /dev/null
+++ b/BBWY.Server.Model/Db/Product/ProductSku.cs
@@ -0,0 +1,46 @@
+using FreeSql.DataAnnotations;
+using System;
+
+namespace BBWY.Server.Model.Db
+{
+
+ [Table(Name = "productsku", DisableSyncStructure = true)]
+ public partial class ProductSku
+ {
+
+ ///
+ /// SKU
+ ///
+ [Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
+ public string Id { get; set; }
+
+ [Column(DbType = "datetime")]
+ public DateTime? CreateTime { get; set; }
+
+
+ public string Logo { get; set; }
+
+ [Column(DbType = "int(1)", MapType = typeof(int))]
+ public Enums.Platform Platform { get; set; }
+
+ ///
+ /// 售价
+ ///
+ [Column(DbType = "decimal(18,2)")]
+ public decimal? Price { get; set; }
+
+ ///
+ /// SPU
+ ///
+ [Column(StringLength = 50)]
+ public string ProductId { get; set; }
+
+
+ public long? ShopId { get; set; }
+
+
+ public string Title { get; set; }
+
+ }
+
+}