From 79963cf8bafeee7f0009dfa006f66d7f21b2e8c5 Mon Sep 17 00:00:00 2001 From: shanj <18996038927@163.com> Date: Fri, 18 Nov 2022 03:08:29 +0800 Subject: [PATCH] 1 --- .../Controllers/StoreHouseSyncController.cs | 24 ++++ BBWY.Server.Business/Order/OrderBusiness.cs | 61 +++++----- .../PlatformSDK/JDBusiness.cs | 15 +++ .../PlatformSDK/PlatformSDKBusiness.cs | 5 + .../Sync/StoreHouseSyncBusiness.cs | 110 ++++++++++++++++++ BBWY.Server.Business/TaskSchedulerManager.cs | 4 + BBWY.Server.Model/Db/Order/Order.cs | 39 +------ BBWY.Server.Model/Db/Stock/StoreHouse.cs | 31 +++++ BBWY.Server.Model/Enums.cs | 16 +++ JD.API/Controllers/PlatformSDKController.cs | 13 ++- .../Middlewares/CustomExceptionMiddleWare.cs | 9 +- 11 files changed, 257 insertions(+), 70 deletions(-) create mode 100644 BBWY.Server.API/Controllers/StoreHouseSyncController.cs create mode 100644 BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs create mode 100644 BBWY.Server.Model/Db/Stock/StoreHouse.cs diff --git a/BBWY.Server.API/Controllers/StoreHouseSyncController.cs b/BBWY.Server.API/Controllers/StoreHouseSyncController.cs new file mode 100644 index 00000000..4cd18773 --- /dev/null +++ b/BBWY.Server.API/Controllers/StoreHouseSyncController.cs @@ -0,0 +1,24 @@ +using BBWY.Server.Business.Sync; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace BBWY.Server.API.Controllers +{ + public class StoreHouseSyncController : BaseApiController + { + private StoreHouseSyncBusiness storeHouseSyncBusiness; + public StoreHouseSyncController(IHttpContextAccessor httpContextAccessor, StoreHouseSyncBusiness storeHouseSyncBusiness) : base(httpContextAccessor) + { + this.storeHouseSyncBusiness = storeHouseSyncBusiness; + } + + /// + /// 同步全店仓库信息 + /// + [HttpGet] + public void StartSyncAllShopStoreHouse() + { + storeHouseSyncBusiness.StartSyncAllShopStoreHouse(); + } + } +} diff --git a/BBWY.Server.Business/Order/OrderBusiness.cs b/BBWY.Server.Business/Order/OrderBusiness.cs index 141b49e2..270748a3 100644 --- a/BBWY.Server.Business/Order/OrderBusiness.cs +++ b/BBWY.Server.Business/Order/OrderBusiness.cs @@ -50,13 +50,14 @@ namespace BBWY.Server.Business productBusinessLazy = new Lazy(() => serviceProvider.GetService()); } - private ISelect GetOrderListQueryConditions(SearchOrderRequest searchOrderRequest) + private ISelect GetOrderListQueryConditions(SearchOrderRequest searchOrderRequest) { - var select = fsql.Select().LeftJoin((o, ocs, oct) => o.Id == ocs.OrderId) - .LeftJoin((o, ocs, oct) => o.Id == oct.OrderId); + var select = fsql.Select().LeftJoin((o, ocs, oct, sh) => o.Id == ocs.OrderId) + .LeftJoin((o, ocs, oct, sh) => o.Id == oct.OrderId) + .LeftJoin((o, ocs, oct, sh) => o.StoreId == sh.Id); if (!string.IsNullOrEmpty(searchOrderRequest.OrderId)) { - select = select.Where((o, ocs, oct) => o.Id == searchOrderRequest.OrderId); + select = select.Where((o, ocs, oct, sh) => o.Id == searchOrderRequest.OrderId); } else { @@ -66,35 +67,35 @@ namespace BBWY.Server.Business .WhereIf(!string.IsNullOrEmpty(searchOrderRequest.Sku), osku => osku.SkuId == searchOrderRequest.Sku) .WhereIf(!string.IsNullOrEmpty(searchOrderRequest.ProductId), osku => osku.ProductId == searchOrderRequest.ProductId) .WhereIf(!string.IsNullOrEmpty(searchOrderRequest.ProductNo), osku => osku.ProductNo == searchOrderRequest.ProductNo); - select = select.Where((o, ocs, oct) => childSelect.Where(osku => osku.OrderId == o.Id).Any()); + select = select.Where((o, ocs, oct, sh) => childSelect.Where(osku => osku.OrderId == o.Id).Any()); } - select = select.WhereIf(searchOrderRequest.OrderState != null, (o, ocs, oct) => o.OrderState == searchOrderRequest.OrderState) - .WhereIf(searchOrderRequest.StartDate != null, (o, ocs, oct) => o.StartTime >= searchOrderRequest.StartDate) - .WhereIf(searchOrderRequest.EndDate != null, (o, ocs, oct) => o.StartTime <= searchOrderRequest.EndDate) + select = select.WhereIf(searchOrderRequest.OrderState != null, (o, ocs, oct, sh) => o.OrderState == searchOrderRequest.OrderState) + .WhereIf(searchOrderRequest.StartDate != null, (o, ocs, oct, sh) => o.StartTime >= searchOrderRequest.StartDate) + .WhereIf(searchOrderRequest.EndDate != null, (o, ocs, oct, sh) => o.StartTime <= searchOrderRequest.EndDate) .WhereIf(searchOrderRequest.IncludeExceptionOrder, - (o, ocs, oct) => o.OrderState != Enums.OrderState.已取消 && + (o, ocs, oct, sh) => o.OrderState != Enums.OrderState.已取消 && ((o.StorageType != Enums.StorageType.SD && o.StorageType != null && oct.PurchaseAmount == 0M) || (o.StorageType != Enums.StorageType.SD && oct.PurchaseAmount + oct.DeliveryExpressFreight > o.OrderSellerPrice + o.FreightPrice) || (o.StorageType == null && o.OrderState != Enums.OrderState.等待采购))) - .WhereIf(searchOrderRequest.OnlyDF, (o, ocs, oct) => o.StorageType == Enums.StorageType.代发) - .WhereIf(searchOrderRequest.ExcludeCanceled, (o, ocs, oct) => o.OrderState != Enums.OrderState.已取消) - .WhereIf(searchOrderRequest.ExcludeSD && !searchOrderRequest.OnlyDF, (o, ocs, oct) => o.StorageType == null || o.StorageType != Enums.StorageType.SD) - .WhereIf(string.IsNullOrEmpty(searchOrderRequest.ContactName) == false, (o, ocs, oct) => ocs.ContactName == searchOrderRequest.ContactName) - .WhereIf(string.IsNullOrEmpty(searchOrderRequest.Waybill) == false, (o, ocs, oct) => o.WaybillNo == searchOrderRequest.Waybill); + .WhereIf(searchOrderRequest.OnlyDF, (o, ocs, oct, sh) => o.StorageType == Enums.StorageType.代发) + .WhereIf(searchOrderRequest.ExcludeCanceled, (o, ocs, oct, sh) => o.OrderState != Enums.OrderState.已取消) + .WhereIf(searchOrderRequest.ExcludeSD && !searchOrderRequest.OnlyDF, (o, ocs, oct, sh) => o.StorageType == null || o.StorageType != Enums.StorageType.SD) + .WhereIf(string.IsNullOrEmpty(searchOrderRequest.ContactName) == false, (o, ocs, oct, sh) => ocs.ContactName == searchOrderRequest.ContactName) + .WhereIf(string.IsNullOrEmpty(searchOrderRequest.Waybill) == false, (o, ocs, oct, sh) => o.WaybillNo == searchOrderRequest.Waybill); } - select = select.WhereIf(searchOrderRequest.ShopId != null, (o, ocs, oct) => o.ShopId == searchOrderRequest.ShopId) - .WhereIf(!string.IsNullOrEmpty(searchOrderRequest.SDOperator), (o, ocs, oct) => o.SDOperator == searchOrderRequest.SDOperator); + select = select.WhereIf(searchOrderRequest.ShopId != null, (o, ocs, oct, sh) => o.ShopId == searchOrderRequest.ShopId) + .WhereIf(!string.IsNullOrEmpty(searchOrderRequest.SDOperator), (o, ocs, oct, sh) => o.SDOperator == searchOrderRequest.SDOperator); //select = select.Where((o, ocs, oct) => o.ShopId == searchOrderRequest.ShopId); return select; } - private Expression> GetOrderListField() + private Expression> GetOrderListField() { - return (o, ocs, oct) => new Order() + return (o, ocs, oct, sh) => new Order() { Id = o.Id, BuyerRemark = o.BuyerRemark, @@ -147,7 +148,9 @@ namespace BBWY.Server.Business SDOrderAmount = oct.SDOrderAmount, RefundAmount = oct.RefundAmount, RefundPurchaseAmount = oct.RefundPurchaseAmount, - AfterTotalCost = oct.AfterTotalCost + AfterTotalCost = oct.AfterTotalCost, + + StoreName = sh.Name }; } @@ -162,7 +165,7 @@ namespace BBWY.Server.Business //var noCancelSelect = GetOrderListQueryConditions(searchOrderRequest); //var currentConditionsTotalProfit = noCancelSelect.Where((o, ocs, oct) => o.OrderState != Enums.OrderState.已取消).ToAggregate((o, ocs, oct) => oct.Sum(oct.Key.Profit)); - var select = GetOrderListQueryConditions(searchOrderRequest).OrderByDescending((o, ocs, oct) => o.StartTime) + var select = GetOrderListQueryConditions(searchOrderRequest).OrderByDescending((o, ocs, oct, sh) => o.StartTime) .Count(out var total) .Page(searchOrderRequest.PageIndex, searchOrderRequest.PageSize); @@ -222,10 +225,10 @@ namespace BBWY.Server.Business order.AfterSaleOrderList = afterSaleOrderList.Where(aso => aso.OrderId == order.Id).ToList(); #endregion - #region 翻译仓库Id - foreach (var order in orderList) - order.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == order.StoreId)?.StoreName ?? order.StoreId; - #endregion + //#region 翻译仓库Id + //foreach (var order in orderList) + // order.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == order.StoreId)?.StoreName ?? order.StoreId; + //#endregion } var response = new OrderListResponse() @@ -338,10 +341,10 @@ namespace BBWY.Server.Business public OrderResponse GetOrderById(string orderId) { - var order = fsql.Select().LeftJoin((o, ocs, oct) => o.Id == ocs.OrderId) - .LeftJoin((o, ocs, oct) => o.Id == oct.OrderId) - .Where((o, ocs, oct) => o.Id == orderId) - .ToOne(GetOrderListField()); + var order = fsql.Select().LeftJoin((o, ocs, oct, sh) => o.Id == ocs.OrderId) + .LeftJoin((o, ocs, oct, sh) => o.Id == oct.OrderId) + .Where((o, ocs, oct, sh) => o.Id == orderId) + .ToOne(GetOrderListField()); if (order == null) throw new BusinessException("订单不存在"); @@ -369,7 +372,7 @@ namespace BBWY.Server.Business orderResponse.OrderCouponList = orderCouponList; orderResponse.OrderCostDetailList = orderCostDetailList; - orderResponse.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == orderResponse.StoreId)?.StoreName ?? order.StoreId; + //orderResponse.StoreName = globalConfig.Stores.FirstOrDefault(s => s.StoreId == orderResponse.StoreId)?.StoreName ?? order.StoreId; return orderResponse; } diff --git a/BBWY.Server.Business/PlatformSDK/JDBusiness.cs b/BBWY.Server.Business/PlatformSDK/JDBusiness.cs index e75ac760..e8e07ef7 100644 --- a/BBWY.Server.Business/PlatformSDK/JDBusiness.cs +++ b/BBWY.Server.Business/PlatformSDK/JDBusiness.cs @@ -607,5 +607,20 @@ namespace BBWY.Server.Business res.Json = JsonConvert.DeserializeObject(res.Body); return (JArray)res.Json["jingdong_ads_ibg_UniversalJosService_order_query_responce"]["returnType"]["data"]["datas"]; } + + public override JArray GetStoreHouseList(PlatformRequest request) + { + var jdClient = GetJdClient(request.AppKey, request.AppSecret); + var req = new StoreFindPartitionWhByIdAndStatusRequest(); + req.status = "2"; + + var res = jdClient.Execute(req, request.AppToken, DateTime.Now.ToLocalTime()); + if (res.IsError) + throw new BusinessException($"获取仓库出错 {(string.IsNullOrEmpty(res.ErrorMsg) ? res.ErrMsg : res.ErrorMsg)}"); + if (res.Json == null) + res.Json = JsonConvert.DeserializeObject(res.Body); + + return (JArray)res.Json["jingdong_store_findPartitionWhByIdAndStatus_responce"]["find_Partition_Warehouse_Result"]["result"]; + } } } diff --git a/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs b/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs index ea8134e4..b658f4fd 100644 --- a/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs +++ b/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs @@ -137,5 +137,10 @@ namespace BBWY.Server.Business { throw new NotImplementedException(); } + + public virtual JArray GetStoreHouseList(PlatformRequest request) + { + throw new NotImplementedException(); + } } } diff --git a/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs b/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs new file mode 100644 index 00000000..57d6cdf0 --- /dev/null +++ b/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs @@ -0,0 +1,110 @@ +using BBWY.Common.Http; +using BBWY.Common.Models; +using BBWY.Server.Model; +using BBWY.Server.Model.Db; +using BBWY.Server.Model.Dto; +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.Threading; +using System.Threading.Tasks; +using Yitter.IdGenerator; + +namespace BBWY.Server.Business.Sync +{ + public class StoreHouseSyncBusiness : BaseSyncBusiness, IDenpendency + { + private IDictionary>> storeHouseSyncMethodDic; + + public StoreHouseSyncBusiness(RestApiService restApiService, + IOptions options, + NLogManager nLogManager, + IFreeSql fsql, + IIdGenerator idGenerator, + TaskSchedulerManager taskSchedulerManager, + VenderBusiness venderBusiness, + YunDingBusiness yunDingBusiness) : base(restApiService, + options, + nLogManager, + fsql, + idGenerator, + taskSchedulerManager, + venderBusiness, + yunDingBusiness) + { + storeHouseSyncMethodDic = new Dictionary>>() + { + { Enums.Platform.京东, ResolveJDStoreHouse} + }; + } + + public void StartSyncAllShopStoreHouse() + { + Task.Factory.StartNew(SyncAllShopStoreHouse, CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.StoreHouseTaskScheduler); + } + + public void SyncAllShopStoreHouse() + { + var shopList = venderBusiness.GetShopList(); + var storeHouseList = new List(); + foreach (var shop in shopList) + { + Thread.Sleep(1000); + try + { + var restApiResult = restApiService.SendRequest(GetPlatformRelayAPIHost(shop.PlatformId), "api/PlatformSDK/GetStoreHouseList", new PlatformRequest() + { + AppKey = shop.AppKey, + AppSecret = shop.AppSecret, + AppToken = shop.AppToken, + Platform = shop.PlatformId, + SaveResponseLog = false + }, GetYunDingRequestHeader(), HttpMethod.Post); + if (restApiResult.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception(restApiResult.Content); + var response = JsonConvert.DeserializeObject>(restApiResult.Content); + if (response.Data == null || response.Data.Count() == 0) + continue; + //ResolveJDStoreHouse(response.Data, shop, storeHouseList); + storeHouseSyncMethodDic[shop.PlatformId](response.Data, shop, storeHouseList); + } + catch (Exception ex) + { + nLogManager.Default().Error(ex, $"{shop.ShopName} 获取仓库列表失败"); + } + } + + var storeHouseIds = storeHouseList.Select(s => s.Id).ToArray(); + var dbStoreIds = fsql.Select(storeHouseIds).ToList(s => s.Id); + var exceptIds = storeHouseIds.Except(dbStoreIds); + if (exceptIds.Count() > 0) + { + var insertList = storeHouseList.Where(s => exceptIds.Contains(s.Id)).ToList(); + fsql.Insert(insertList).ExecuteAffrows(); + } + } + + private void ResolveJDStoreHouse(JArray jarray, ShopResponse shop, IList storeHouseList) + { + foreach (var storeHouseJToken in jarray) + { + var seq_num = storeHouseJToken.Value("seq_num"); + if (storeHouseList.Count(s => s.Id == seq_num) > 0) + continue; + storeHouseList.Add(new Storehouse() + { + Id = seq_num, + Name = storeHouseJToken.Value("name"), + Platform = shop.PlatformId, + CreateTime = DateTime.Now, + Status = (Enums.StockStatus)storeHouseJToken.Value("use_flag"), + Type = (Enums.StockType)storeHouseJToken.Value("type") + }); + } + } + } +} diff --git a/BBWY.Server.Business/TaskSchedulerManager.cs b/BBWY.Server.Business/TaskSchedulerManager.cs index 189e9c02..91af950e 100644 --- a/BBWY.Server.Business/TaskSchedulerManager.cs +++ b/BBWY.Server.Business/TaskSchedulerManager.cs @@ -16,6 +16,8 @@ namespace BBWY.Server.Business public LimitedConcurrencyLevelTaskScheduler JDPopularizeTaskScheduler { get; private set; } + public LimitedConcurrencyLevelTaskScheduler StoreHouseTaskScheduler { get; private set; } + public TaskSchedulerManager() { SyncOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10); @@ -24,6 +26,8 @@ namespace BBWY.Server.Business PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10); ProductSyncTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(5); JDPopularizeTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10); + + StoreHouseTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(2); } } } diff --git a/BBWY.Server.Model/Db/Order/Order.cs b/BBWY.Server.Model/Db/Order/Order.cs index d3b30ade..000f3d22 100644 --- a/BBWY.Server.Model/Db/Order/Order.cs +++ b/BBWY.Server.Model/Db/Order/Order.cs @@ -276,42 +276,9 @@ namespace BBWY.Server.Model.Db public bool? IsDecode { get; set; } #endregion - #region 代发信息 - ///// - ///// 买家账号 - ///// - //[Column(IsIgnore = true)] - //public string BuyerAccount { get; set; } - - ///// - ///// 发货运费 - ///// - //[Column(IsIgnore = true)] - //public decimal DeliveryFreight { get; set; } = 0.00M; - - ///// - ///// 采购单号 - ///// - //[Column(IsIgnore = true)] - //public string PurchaseOrderId { get; set; } - - ///// - ///// 采购平台 - ///// - //[Column(IsIgnore = true)] - //public Enums.Platform? PurchasePlatform { get; set; } - - ///// - ///// 卖家账号 - ///// - //[Column(IsIgnore = true)] - //public string SellerAccount { get; set; } - - //[Column(IsIgnore = true)] - //public decimal OrderDropShippingSkuAmount { get; set; } - - //[Column(IsIgnore = true)] - //public decimal OrderDropShippingPurchaseFreight { get; set; } + #region 仓库 + [Column(IsIgnore = true)] + public string StoreName { get; set; } #endregion } diff --git a/BBWY.Server.Model/Db/Stock/StoreHouse.cs b/BBWY.Server.Model/Db/Stock/StoreHouse.cs new file mode 100644 index 00000000..d6b666b4 --- /dev/null +++ b/BBWY.Server.Model/Db/Stock/StoreHouse.cs @@ -0,0 +1,31 @@ +using FreeSql.DataAnnotations; +using System; + +namespace BBWY.Server.Model.Db +{ + + [Table(Name = "storehouse", DisableSyncStructure = true)] + public partial class Storehouse + { + + [Column(DbType = "datetime")] + public DateTime? CreateTime { get; set; } + + [Column(StringLength = 50, IsPrimary = true, IsNullable = false)] + public string Id { get; set; } + + [Column(StringLength = 50)] + public string Name { get; set; } + + [Column(MapType = typeof(int))] + public Enums.Platform Platform { get; set; } + + [Column(MapType = typeof(int))] + public Enums.StockStatus Status { get; set; } + + [Column(MapType = typeof(int))] + public Enums.StockType Type { get; set; } + + } + +} diff --git a/BBWY.Server.Model/Enums.cs b/BBWY.Server.Model/Enums.cs index 480ebf10..1e14a12a 100644 --- a/BBWY.Server.Model/Enums.cs +++ b/BBWY.Server.Model/Enums.cs @@ -196,5 +196,21 @@ 自定义 = 18, 备用金充值 = 19 } + + /// + /// 京东仓库类型 1商家仓 2京东仓 + /// + public enum StockType + { + 商家仓 = 1, 京仓 = 2 + } + + /// + /// 仓库状态 0暂停,1使用 + /// + public enum StockStatus + { + 暂停 = 0, 使用 = 1 + } } } diff --git a/JD.API/Controllers/PlatformSDKController.cs b/JD.API/Controllers/PlatformSDKController.cs index d276a66e..36360fd6 100644 --- a/JD.API/Controllers/PlatformSDKController.cs +++ b/JD.API/Controllers/PlatformSDKController.cs @@ -250,9 +250,20 @@ namespace JD.API.API.Controllers /// /// [HttpPost] - public JArray GetJDSopularizeReportFormByOrderLevel(SyncJDPopularizeReportFormRequest request) + public JArray GetJDSopularizeReportFormByOrderLevel([FromBody] SyncJDPopularizeReportFormRequest request) { return platformSDKBusinessList.FirstOrDefault(p => p.Platform == request.Platform).GetJDSopularizeReportFormByOrderLevel(request); } + + /// + /// 获取仓库列表 + /// + /// + /// + [HttpPost] + public JArray GetStoreHouseList([FromBody] PlatformRequest request) + { + return platformSDKBusinessList.FirstOrDefault(p => p.Platform == request.Platform).GetStoreHouseList(request); + } } } diff --git a/JD.API/Middlewares/CustomExceptionMiddleWare.cs b/JD.API/Middlewares/CustomExceptionMiddleWare.cs index 38ff1b65..da17e1db 100644 --- a/JD.API/Middlewares/CustomExceptionMiddleWare.cs +++ b/JD.API/Middlewares/CustomExceptionMiddleWare.cs @@ -22,12 +22,13 @@ namespace JD.API.Middlewares /// private IDictionary _exceptionStatusCodeDic; - private ILogger logger; + //private ILogger logger; + private NLogManager nLogManager; - public CustomExceptionMiddleWare(RequestDelegate next, ILogger logger) + public CustomExceptionMiddleWare(RequestDelegate next, NLogManager nLogManager) { _next = next; - this.logger = logger; + this.nLogManager = nLogManager; _exceptionStatusCodeDic = new Dictionary { { 401, "未授权的请求" }, @@ -57,7 +58,7 @@ namespace JD.API.Middlewares { context.Response.Clear(); context.Response.StatusCode = 500; //发生未捕获的异常,手动设置状态码 - logger.Error(ex); //记录错误 + nLogManager.Default().Error(ex); //记录错误 } } finally