diff --git a/BBWY.Client/Views/Order/OrderList.xaml b/BBWY.Client/Views/Order/OrderList.xaml index c1d7e31f..db9382e8 100644 --- a/BBWY.Client/Views/Order/OrderList.xaml +++ b/BBWY.Client/Views/Order/OrderList.xaml @@ -423,7 +423,7 @@ - + diff --git a/BBWY.Server.API/Controllers/AfterSaleOrderSyncController.cs b/BBWY.Server.API/Controllers/AfterSaleOrderSyncController.cs new file mode 100644 index 00000000..8614924f --- /dev/null +++ b/BBWY.Server.API/Controllers/AfterSaleOrderSyncController.cs @@ -0,0 +1,27 @@ +using BBWY.Server.Business; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace BBWY.Server.API.Controllers +{ + + public class AfterSaleOrderSyncController : BaseApiController + { + private AfterSaleOrderSyncBusiness afterSaleOrderSyncBusiness; + + public AfterSaleOrderSyncController(IHttpContextAccessor httpContextAccessor, + AfterSaleOrderSyncBusiness afterSaleOrderSyncBusiness) : base(httpContextAccessor) + { + this.afterSaleOrderSyncBusiness = afterSaleOrderSyncBusiness; + } + + /// + /// 全店同步售后订单 + /// + [HttpPost] + public void SyncAllShopAfterOrder() + { + afterSaleOrderSyncBusiness.SyncAllShopAfterOrder(); + } + } +} diff --git a/BBWY.Server.API/Controllers/RefundOrderSyncController.cs b/BBWY.Server.API/Controllers/RefundOrderSyncController.cs index 60260f48..432bbca9 100644 --- a/BBWY.Server.API/Controllers/RefundOrderSyncController.cs +++ b/BBWY.Server.API/Controllers/RefundOrderSyncController.cs @@ -15,7 +15,7 @@ namespace BBWY.Server.API.Controllers } /// - /// 退款同步 + /// 全店同步退款订单 /// [HttpPost] public void SyncAllShopRefundOrder() diff --git a/BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs b/BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs index 39e6dad5..c1b29bbe 100644 --- a/BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs +++ b/BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs @@ -1,12 +1,17 @@ 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 NLog; using System; using System.Collections.Generic; +using System.Linq; +using System.Net.Http; using System.Threading.Tasks; using Yitter.IdGenerator; @@ -16,6 +21,8 @@ namespace BBWY.Server.Business { private IDictionary> syncAfterSaleOrderMethodDic; + private IDictionary processResultDic; + public AfterSaleOrderSyncBusiness(RestApiService restApiService, IOptions options, @@ -35,23 +42,130 @@ namespace BBWY.Server.Business { { Enums.Platform.京东, SyncJDAfterOrder } }; + + processResultDic = new Dictionary() + { + { 23,Enums.ServiceResult.换新}, + { 40,Enums.ServiceResult.退货}, + { 60,Enums.ServiceResult.原返}, + { 90,Enums.ServiceResult.线下换新}, + }; } - private void SyncJDAfterOrder(JArray refundOrderTokenJArray, ShopResponse shopResponse) + private void SyncJDAfterOrder(JArray afterOrderTokenJArray, ShopResponse shopResponse) { + var shopId = long.Parse(shopResponse.ShopId); + var validAfterOrderJArray = afterOrderTokenJArray.Where(j => j.Value("serviceStatus") == 10010 && //完成 + j.Value("processResult") != 100); //不等于闪电催收收款 + + var orderIds = validAfterOrderJArray.Select(j => j["orderId"].ToString()).Distinct().ToList(); + var orderSkuIds = validAfterOrderJArray.Select(j => j["skuId"].ToString()).Distinct().ToList(); + + var updateOrders = fsql.Select().Where(o => orderIds.Contains(o.Id) && o.IsAfterSaleOrder == false).ToList(); + var updateOrderSkus = fsql.Select().Where(osku => orderIds.Contains(osku.OrderId) && + orderSkuIds.Contains(osku.SkuId)).ToList(); + + var afterOrders = fsql.Select().Where(aso => orderIds.Contains(aso.OrderId)).ToList(); + + List insertAfterSaleOrders = new List(); + List> updateAfterSaleOrders = new List>(); + + foreach (var afterOrderJToken in validAfterOrderJArray) + { + var orderId = afterOrderJToken.Value("orderId"); + var skuId = afterOrderJToken.Value("skuId"); + + var updateSku = updateOrderSkus.FirstOrDefault(osku => osku.OrderId == orderId && osku.SkuId == skuId); + if (updateSku == null) + continue; + var afterOrder = afterOrders.FirstOrDefault(aso => aso.OrderId == orderId && aso.SkuId == skuId); + var processResult = processResultDic[afterOrderJToken.Value("processResult")]; + if (afterOrder == null) + { + insertAfterSaleOrders.Add(new AfterSaleOrder() + { + Id = idGenerator.NewLong(), + CreateTime = DateTime.Now, + OrderId = updateSku.OrderId, + ProductId = updateSku.ProductId, + RefundAmount = 0, + SkuId = skuId, + ShopId = shopId, + ServiceResult = processResult + }); + } + else + { + if (afterOrder.ServiceResult == null && afterOrder.ServiceResult != processResult) + { + var update = fsql.Update(afterOrder.Id).Set(aso => aso.ServiceResult, processResult); + updateAfterSaleOrders.Add(update); + } + } + } + + fsql.Transaction(() => + { + if (updateOrders.Count() > 0) + foreach (var updateOrder in updateOrders) + fsql.Update(updateOrder.Id).Set(o => o.IsAfterSaleOrder, true).ExecuteAffrows(); + + if (insertAfterSaleOrders.Count() > 0) + fsql.Insert(insertAfterSaleOrders).ExecuteAffrows(); + if (updateAfterSaleOrders.Count() > 0) + foreach (var update in updateAfterSaleOrders) + update.ExecuteUpdated(); + }); } private void SyncAfterOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false) { + try + { + logger.Info($"售后订单同步 {shop.ShopName} isAuto {isAuto}"); + if (!syncAfterSaleOrderMethodDic.ContainsKey(shop.PlatformId)) + throw new Exception("不支持的平台"); + var shopId = long.Parse(shop.ShopId); + var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId); + var afterOrderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetAfterOrderList", new SyncAfterOrderRequest() + { + StartDate = startTime ?? DateTime.Now.Date.AddDays(-1), + EndDate = endTime ?? DateTime.Now, + AppKey = shop.AppKey, + AppSecret = shop.AppSecret, + AppToken = shop.AppToken, + PageIndex = 1, + PageSize = 50, + Platform = shop.PlatformId, + SaveResponseLog = true, + OrderId = orderId, + VenderId = shop.VenderId + }, null, HttpMethod.Post); + if (afterOrderListApiResult.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception($"获取退款订单失败 {afterOrderListApiResult.Content}"); + var afterOrderListResponse = JsonConvert.DeserializeObject>(afterOrderListApiResult.Content); + if (!afterOrderListResponse.Success) + throw new Exception($"获取退款订单失败 {afterOrderListApiResult.Content}"); + + if (afterOrderListResponse.Data == null || afterOrderListResponse.Data.Count == 0) + return; + + syncAfterSaleOrderMethodDic[shop.PlatformId](afterOrderListResponse.Data, shop); + } + catch (Exception ex) + { + var shopData = JsonConvert.SerializeObject(shop); + logger.Error(ex, $"SyncAfterOrder ShopData:{shopData}"); + } } public void SyncAllShopAfterOrder() { var shopList = venderBusiness.GetShopList(); - //SyncRefundOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true); + //SyncAfterOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true); foreach (var shop in shopList) { Task.Factory.StartNew(() => SyncAfterOrder(shop, string.Empty, isAuto: true), diff --git a/BBWY.Server.Business/Sync/BaseSyncBusiness.cs b/BBWY.Server.Business/Sync/BaseSyncBusiness.cs index 240e182e..194102a7 100644 --- a/BBWY.Server.Business/Sync/BaseSyncBusiness.cs +++ b/BBWY.Server.Business/Sync/BaseSyncBusiness.cs @@ -27,6 +27,7 @@ namespace BBWY.Server.Business this.fsql = fsql; this.idGenerator = idGenerator; this.venderBusiness = venderBusiness; + this.taskSchedulerManager = taskSchedulerManager; } } } diff --git a/BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs b/BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs index efc3e50b..899f870b 100644 --- a/BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs +++ b/BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs @@ -4,6 +4,7 @@ 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; @@ -53,7 +54,10 @@ namespace BBWY.Server.Business orderSkuIds.Contains(osku.SkuId) && osku.IsRefund == false).ToList(); - List afterSaleOrders = new List(); + var afterOrders = fsql.Select().Where(aso => orderIds.Contains(aso.OrderId)).ToList(); + + List insertAfterSaleOrders = new List(); + List> updateAfterSaleOrders = new List>(); foreach (var refundOrderJToken in validRefundOrderTokenJArray) { @@ -66,18 +70,29 @@ namespace BBWY.Server.Business var refundAmount = refundOrderJToken.Value("refoundAmount"); var refundCompleteTime = refundOrderJToken.Value("completeTime").StampToDateTime(); - - afterSaleOrders.Add(new AfterSaleOrder() + var afterOrder = afterOrders.FirstOrDefault(aso => aso.OrderId == orderId && aso.SkuId == skuId); + if (afterOrder == null) + { + insertAfterSaleOrders.Add(new AfterSaleOrder() + { + Id = idGenerator.NewLong(), + CreateTime = DateTime.Now, + OrderId = updateSku.OrderId, + ProductId = updateSku.ProductId, + RefundAmount = refundAmount, + RefundTime = refundCompleteTime, + SkuId = skuId, + ShopId = shopId + }); + } + else if (afterOrder.RefundAmount == 0) { - Id = idGenerator.NewLong(), - CreateTime = DateTime.Now, - OrderId = updateSku.OrderId, - ProductId = updateSku.ProductId, - RefundAmount = refundAmount, - RefundTime = refundCompleteTime, - SkuId = skuId, - ShopId = shopId - }); + //afterOrder.RefundAmount = refundAmount; + //afterOrder.RefundTime = refundCompleteTime; + var update = fsql.Update(afterOrder.Id).Set(aso => aso.RefundAmount, refundAmount) + .Set(aso => aso.RefundTime, refundCompleteTime); + updateAfterSaleOrders.Add(update); + } } fsql.Transaction(() => @@ -88,8 +103,11 @@ namespace BBWY.Server.Business if (updateOrderSkus.Count() > 0) foreach (var updateOrderSku in updateOrderSkus) fsql.Update(updateOrderSku.Id).Set(osku => osku.IsRefund, true).ExecuteAffrows(); - if (afterSaleOrders.Count() > 0) - fsql.Insert(afterSaleOrders).ExecuteAffrows(); + if (insertAfterSaleOrders.Count() > 0) + fsql.Insert(insertAfterSaleOrders).ExecuteAffrows(); + if (updateAfterSaleOrders.Count() > 0) + foreach (var update in updateAfterSaleOrders) + update.ExecuteUpdated(); }); }