Browse Source

对接换货

qianyi
shanji 3 years ago
parent
commit
d49f235a54
  1. 41
      BBWY.Server.API/Controllers/OrderController.cs
  2. 36
      BBWY.Server.API/Controllers/OrderSyncController.cs
  3. 12
      BBWY.Server.API/Controllers/PlatformSDKController.cs
  4. 26
      BBWY.Server.API/Controllers/RefundOrderSyncController.cs
  5. 25
      BBWY.Server.API/Controllers/TestController.cs
  6. 674
      BBWY.Server.Business/Order/OrderBusiness.cs
  7. 24
      BBWY.Server.Business/PlatformSDK/JDBusiness.cs
  8. 4
      BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs
  9. 64
      BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs
  10. 32
      BBWY.Server.Business/Sync/BaseSyncBusiness.cs
  11. 605
      BBWY.Server.Business/Sync/OrderSyncBusiness.cs
  12. 147
      BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs
  13. 3
      BBWY.Server.Business/TaskSchedulerManager.cs
  14. 46
      BBWY.Server.Business/TestBusiness.cs
  15. 8
      BBWY.Server.Business/Vender/VenderBusiness.cs
  16. 6
      BBWY.Server.Model/Db/Mds/Shops.cs
  17. 20
      BBWY.Server.Model/Dto/Request/Sync/SyncAfterOrderRequest.cs
  18. 2
      BBWY.Server.Model/Dto/Response/Vender/ShopResponse.cs
  19. 21
      BBWY.Test/Program.cs

41
BBWY.Server.API/Controllers/OrderController.cs

@ -141,46 +141,5 @@ namespace BBWY.Server.API.Controllers
{
orderBusiness.EditAfterSaleOrderSku(editAfterSaleOrderSkuRequest);
}
/// <summary>
/// 指定时间范围的订单同步
/// </summary>
/// <param name="syncOrderByDateRequest"></param>
[HttpPost]
public void SyncOrderByDate([FromBody] SyncOrderByDateRequest syncOrderByDateRequest)
{
orderBusiness.SyncOrderByDate(syncOrderByDateRequest);
}
/// <summary>
/// 同步所有店铺订单
/// </summary>
[HttpPost]
public void SyncAllShopOrder()
{
orderBusiness.SyncAllShopOrder();
}
/// <summary>
/// 订单同步
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderId"></param>
[HttpPost("{shopId}/{orderId}")]
public void SyncOrder([FromRoute] long shopId, [FromRoute] string orderId)
{
Task.Factory.StartNew(() => orderBusiness.SyncOrder(shopId, orderId), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
/// <summary>
/// 退款同步
/// </summary>
[HttpPost]
public void SyncAllShopRefundOrder()
{
orderBusiness.SyncAllShopRefundOrder();
}
}
}

36
BBWY.Server.API/Controllers/OrderSyncController.cs

@ -0,0 +1,36 @@
using BBWY.Server.Business;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace BBWY.Server.API.Controllers
{
public class OrderSyncController : BaseApiController
{
private OrderSyncBusiness orderSyncBusiness;
public OrderSyncController(IHttpContextAccessor httpContextAccessor, OrderSyncBusiness orderSyncBusiness) : base(httpContextAccessor)
{
this.orderSyncBusiness = orderSyncBusiness;
}
/// <summary>
/// 同步所有店铺的订单
/// </summary>
[HttpPost]
public void SyncAllShopOrder()
{
orderSyncBusiness.SyncAllShopOrder();
}
/// <summary>
/// 订单同步
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderId"></param>
[HttpPost("{shopId}/{orderId}")]
public void SyncOrder([FromRoute] long shopId, [FromRoute] string orderId)
{
orderSyncBusiness.SyncOrder(shopId, orderId, null, null);
}
}
}

12
BBWY.Server.API/Controllers/PlatformSDKController.cs

@ -1,4 +1,5 @@
using BBWY.Server.Business;
using BBWY.Server.Model;
using BBWY.Server.Model.Dto;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -163,5 +164,16 @@ namespace BBWY.Server.API.Controllers
{
return platformSDKBusinessList.FirstOrDefault(p => p.Platform == searchRefundPlatformOrderRequest.Platform).GetRefundList(searchRefundPlatformOrderRequest);
}
/// <summary>
/// 获取售后订单
/// </summary>
/// <param name="syncAfterOrderRequest"></param>
/// <returns></returns>
[HttpPost]
public JArray GetAfterOrderList([FromBody] SyncAfterOrderRequest syncAfterOrderRequest)
{
return platformSDKBusinessList.FirstOrDefault(p => p.Platform == syncAfterOrderRequest.Platform).GetAfterOrderList(syncAfterOrderRequest);
}
}
}

26
BBWY.Server.API/Controllers/RefundOrderSyncController.cs

@ -0,0 +1,26 @@
using BBWY.Server.Business;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace BBWY.Server.API.Controllers
{
public class RefundOrderSyncController : BaseApiController
{
private RefundOrderSyncBusiness refundOrderSyncBusiness;
public RefundOrderSyncController(RefundOrderSyncBusiness refundOrderSyncBusiness, IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
this.refundOrderSyncBusiness = refundOrderSyncBusiness;
}
/// <summary>
/// 退款同步
/// </summary>
[HttpPost]
public void SyncAllShopRefundOrder()
{
refundOrderSyncBusiness.SyncAllShopRefundOrder();
}
}
}

25
BBWY.Server.API/Controllers/TestController.cs

@ -1,4 +1,5 @@
using BBWY.Server.Model.Db;
using BBWY.Server.Business;
using BBWY.Server.Model.Db;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
@ -9,27 +10,17 @@ namespace BBWY.Server.API.Controllers
public class TestController : BaseApiController
{
private IFreeSql fsql;
public TestController(IHttpContextAccessor httpContextAccessor, IFreeSql fsql) : base(httpContextAccessor)
private TestBusiness testBusiness;
public TestController(IHttpContextAccessor httpContextAccessor, IFreeSql fsql, TestBusiness testBusiness) : base(httpContextAccessor)
{
this.fsql = fsql;
this.testBusiness = testBusiness;
}
[HttpGet]
public IList<string> GetList()
[HttpPost]
public void SyncVenderId()
{
return new List<string>() {
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now.ToString()
};
}
[HttpGet("{orderId}")]
public decimal SumNoExists([FromRoute] string orderId)
{
var a = fsql.Select<OrderCoupon>().Where(oc => oc.OrderId == orderId).ToAggregate(g => g.Sum(g.Key.CouponPrice) );
return a;
testBusiness.SyncVenderId();
}
}
}

674
BBWY.Server.Business/Order/OrderBusiness.cs

@ -25,8 +25,7 @@ namespace BBWY.Server.Business
{
private ILogger logger;
private IFreeSql fsql;
private IDictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>> syncOrderMethodDic;
private IDictionary<Enums.Platform, Action<JArray, ShopResponse>> syncRefundOrderMethodDic;
private IIdGenerator idGenerator;
private TaskSchedulerManager taskSchedulerManager;
private MDSBusiness mdsBusiness;
@ -48,14 +47,6 @@ namespace BBWY.Server.Business
this.fsql = fsql;
this.idGenerator = idGenerator;
this.taskSchedulerManager = taskSchedulerManager;
syncOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>>()
{
{ Enums.Platform., SyncJDOrder }
};
syncRefundOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, ShopResponse>>()
{
{ Enums.Platform., SyncJDRefundOrder}
};
this.mdsBusiness = mdsBusiness;
this.venderBusiness = venderBusiness;
freeSqlMultiDBManagerLazy = new Lazy<FreeSqlMultiDBManager>(() => serviceProvider.GetService<FreeSqlMultiDBManager>());
@ -1076,668 +1067,5 @@ namespace BBWY.Server.Business
updateAfterSaleOrder?.ExecuteAffrows();
});
}
/// <summary>
/// 同步订单
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderId"></param>
/// <param name="startTime">默认3小时前</param>
/// <param name="endTime">默认当前时间</param>
/// <exception cref="Exception"></exception>
public void SyncOrder(long shopId, string orderId, DateTime? startTime = null, DateTime? endTime = null)
{
var shop = mdsBusiness.GetShopInfoByShopId(shopId);
SyncOrder(shop, orderId, startTime, endTime);
}
private void SyncOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
{
try
{
logger.Info($"订单同步 {shop.ShopName} isAuto {isAuto}");
if (!syncOrderMethodDic.ContainsKey(shop.PlatformId))
throw new Exception("不支持的平台");
var shopId = long.Parse(shop.ShopId);
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
var orderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetOrderList", new SearchPlatformOrderRequest()
{
StartDate = startTime ?? DateTime.Now.AddHours(-3),
EndDate = endTime ?? DateTime.Now,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
PageIndex = 1,
PageSize = 100,
Platform = shop.PlatformId,
JDColType = string.IsNullOrEmpty(shop.ShopType) ? "0" : shop.ShopType,
//SaveResponseLog = true,
OrderId = orderId
}, null, HttpMethod.Post);
if (orderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
var orderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(orderListApiResult.Content);
if (!orderListResponse.Success)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
if (orderListResponse.Data == null || orderListResponse.Data.Count == 0)
return;
syncOrderMethodDic[shop.PlatformId](orderListResponse.Data, shopId, relayAPIHost, shop.AppKey, shop.AppSecret, shop.AppToken, shop.PlatformCommissionRatio ?? 0.05M);
}
catch (Exception ex)
{
var shopData = JsonConvert.SerializeObject(shop);
logger.Error(ex, $"SyncOrder ShopData:{shopData}");
}
}
public void SyncOrderByDate(SyncOrderByDateRequest syncOrderByDateRequest)
{
if (fsql.Select<OrderSyncTask>().Where(ost => ost.ShopId == syncOrderByDateRequest.ShopId && ost.State == Enums.OrderSyncState.Running).Any())
throw new BusinessException("存在未结束的同步任务,请稍后同步");
syncOrderByDateRequest.EndTime = syncOrderByDateRequest.EndTime.Date.AddDays(1).AddSeconds(-1);
if ((syncOrderByDateRequest.EndTime - syncOrderByDateRequest.StartTime).Days > 7)
throw new BusinessException("同步任务时差最长7天");
var orderSyncTask = new OrderSyncTask()
{
Id = idGenerator.NewLong(),
ShopId = syncOrderByDateRequest.ShopId,
State = Enums.OrderSyncState.Running,
SyncStartTime = syncOrderByDateRequest.StartTime,
SyncEndTime = syncOrderByDateRequest.EndTime
};
fsql.Insert(orderSyncTask).ExecuteAffrows();
Task.Factory.StartNew(() =>
{
var currentStartTime = syncOrderByDateRequest.StartTime;
var currentEndTime = currentStartTime.AddHours(3);
var keeploop = true;
while (keeploop)
{
try
{
SyncOrder(syncOrderByDateRequest.ShopId, String.Empty, currentStartTime, currentEndTime);
}
catch (Exception ex) { }
finally
{
var lessHour = (syncOrderByDateRequest.EndTime - currentEndTime).TotalHours;
if (lessHour > 3)
{
currentStartTime = currentStartTime.AddHours(3);
currentEndTime = currentEndTime.AddHours(3);
}
else if (lessHour > 0 && lessHour < 3)
{
currentStartTime = currentEndTime;
currentEndTime = syncOrderByDateRequest.EndTime;
}
else if (lessHour <= 0)
{
keeploop = false;
}
}
}
try
{
fsql.Update<OrderSyncTask>(orderSyncTask.Id).Set(ost => ost.State, Enums.OrderSyncState.End).ExecuteAffrows();
}
catch (Exception ex) { }
}, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
private void SyncJDOrder(JArray orderTokenJArray, long shopId, string relayAPIHost, string appKey, string appSecret, string appToken, decimal platformCommissionRatio)
{
var orderTokenList = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") != 0);
var interfaceOrderIdList = orderTokenList.Select(orderJToken => orderJToken.Value<string>("orderId"));
var interfaceCanceledOrderIdList = orderTokenList.Where(orderJToken => orderJToken.Value<string>("orderState").Equals("TRADE_CANCELED"))
.Select(orderJToken => orderJToken.Value<string>("orderId")); //接口查询结果中取消状态的订单Id
var dbOrderList = fsql.Select<Order>().Where(o => interfaceOrderIdList.Contains(o.Id)).ToList(o => new Order()
{
Id = o.Id,
OrderState = o.OrderState,
StorageType = o.StorageType
}); //数据库订单
var dbOrderConsigneeList = fsql.Select<OrderConsignee>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单收货信息
var dbOrderCostList = fsql.Select<OrderCost>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单成本信息
var dbOrderCouponList = fsql.Select<OrderCoupon>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单优惠信息
List<OrderCostDetail> dbOrderCostDetailList = null; //数据库成本明细
if (interfaceCanceledOrderIdList.Count() > 0 &&
dbOrderList.Any(dbOrder => interfaceCanceledOrderIdList.Contains(dbOrder.Id) && dbOrder.OrderState != Enums.OrderState.))
{
dbOrderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => interfaceCanceledOrderIdList.Contains(ocd.OrderId) && ocd.IsEnabled == true).ToList();
}
var orderSkuIds = new List<string>();
foreach (var orderJToken in orderTokenList)
{
var itemInfoList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuJToken => skuJToken.Value<string>("skuId"));
foreach (var skuId in itemInfoList)
{
if (!orderSkuIds.Contains(skuId))
orderSkuIds.Add(skuId);
}
}
var dbPurchaseOrderList = fsql.Select<PurchaseOrder>().Where(po => po.RemainingQuantity != 0 && orderSkuIds.Contains(po.SkuId)).ToList(); //数据库采购单
orderSkuIds.Clear();
#region 数据库操作
List<Order> insertOrderList = new List<Order>();
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
List<OrderCost> insertOrderCostList = new List<OrderCost>();
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
List<OrderCoupon> insertOrderCouponList = new List<OrderCoupon>();
IList<IUpdate<Order>> updateOrderList = new List<IUpdate<Order>>();
IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
#endregion
foreach (var orderJToken in orderTokenList)
{
var orderId = orderJToken.Value<string>("orderId");
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == orderId);
var isNewOrder = dbOrder == null;
#region 订单基本信息
var buyerRemark = orderJToken.Value<string>("orderRemark");
var venderRemark = orderJToken.Value<string>("venderRemark");
var modifyTime = orderJToken.Value<DateTime?>("modified");
var endTime = orderJToken.Value<DateTime?>("orderEndTime");
var waybillNo = orderJToken.Value<string>("waybill");
if (dbOrder == null)
{
dbOrder = new Order()
{
Id = orderId,
BuyerRemark = buyerRemark,
VenderRemark = venderRemark,
FreightPrice = orderJToken.Value<decimal>("freightPrice"),
EndTime = endTime,
StartTime = orderJToken.Value<DateTime>("orderStartTime"),
ModifyTime = modifyTime,
OrderPayment = orderJToken.Value<decimal>("orderPayment"),
SellerPreferentialAmount = orderJToken.Value<decimal>("sellerDiscount"),
OrderSellerPrice = orderJToken.Value<decimal>("orderSellerPrice"),
OrderTotalPrice = orderJToken.Value<decimal>("orderTotalPrice"),
OrderType = (Enums.OrderType)orderJToken.Value<int>("orderType"),
Platform = Enums.Platform.,
ShopId = shopId,
//VenderId = orderJToken.Value<long>("venderId"),
WaybillNo = waybillNo,
StoreOrder = orderJToken.Value<string>("storeOrder") ?? string.Empty,
StoreId = orderJToken.Value<string>("storeId")
};
if (dbOrder.StoreOrder.Contains("京仓"))
dbOrder.StorageType = Enums.StorageType.;
else if (dbOrder.StoreOrder.Contains("云仓"))
dbOrder.StorageType = Enums.StorageType.;
var payType = orderJToken.Value<string>("payType");
if (payType.Contains("-"))
dbOrder.PayType = (Enums.PayType)Convert.ToInt32(payType.Substring(0, 1));
insertOrderList.Add(dbOrder);
#region OrderSku
var orderSkuList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuToken => new OrderSku()
{
Id = idGenerator.NewLong(),
ItemTotal = skuToken.Value<int>("itemTotal"),
Price = skuToken.Value<decimal>("jdPrice"),
ProductId = skuToken.Value<string>("wareId"),
Title = skuToken.Value<string>("skuName").SimplifySkuName(),
ProductNo = skuToken.Value<string>("productNo"),
CreateTime = DateTime.Now,
OrderId = orderId,
SkuId = skuToken.Value<string>("skuId")
}).ToList();
insertOrderSkuList.AddRange(orderSkuList);
#endregion
}
#endregion
#region 收货人信息
if (dbOrderConsigneeList.FirstOrDefault(oc => oc.OrderId == orderId) == null)
{
var orderConsignee = new OrderConsignee()
{
OrderId = orderId,
//Address = orderJToken["consigneeInfo"].Value<string>("fullAddress"),
//ContactName = orderJToken["consigneeInfo"].Value<string>("fullname"),
//Mobile = orderJToken["consigneeInfo"].Value<string>("mobile"),
//TelePhone = orderJToken["consigneeInfo"].Value<string>("telephone"),
City = orderJToken["consigneeInfo"].Value<string>("city"),
Province = orderJToken["consigneeInfo"].Value<string>("province"),
County = orderJToken["consigneeInfo"].Value<string>("county"),
Town = orderJToken["consigneeInfo"].Value<string>("town"),
IsDecode = false,
CreateTime = DateTime.Now
};
insertOrderConsigneeList.Add(orderConsignee);
}
#endregion
#region 订单优惠
if (!dbOrderCouponList.Any(oc => oc.OrderId == orderId))
{
var orderCouponJArray = (JArray)orderJToken["couponDetailList"];
if (orderCouponJArray.HasValues)
{
foreach (var orderCouponJToken in orderCouponJArray)
{
var couponType = orderCouponJToken.Value<string>("couponType");
if (string.IsNullOrEmpty(couponType))
continue;
dbOrder.PreferentialAmount += orderCouponJToken.Value<decimal>("couponPrice");
insertOrderCouponList.Add(new OrderCoupon()
{
Id = idGenerator.NewLong(),
SkuId = orderCouponJToken.Value<string>("skuId"),
OrderId = orderId,
CreateTime = DateTime.Now,
CouponType = couponType,
CouponPrice = orderCouponJToken.Value<decimal>("couponPrice")
});
}
}
}
#endregion
#region 订单状态转换
var jdOrderState = orderJToken.Value<string>("orderState");
Enums.OrderState? orderState = null;
#region SOP状态翻译
if (jdOrderState.Equals("NOT_PAY")) //未付款
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_SELLER_STOCK_OUT")) //等待出库
{
orderState = Enums.OrderState.;
if (dbOrder.StorageType != null)
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_GOODS_RECEIVE_CONFIRM"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("FINISHED_L"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("POP_ORDER_PAUSE") || jdOrderState.Equals("PAUSE"))
{
orderState = Enums.OrderState.;
}
#endregion
#region FBP状态翻译
else if (jdOrderState.Equals("DengDaiDaYin") || jdOrderState.Equals("DengDaiChuKu") || jdOrderState.Equals("DengDaiDaBao") || jdOrderState.Equals("DengDaiFaHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("DengDaiQueRenShouHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WanCheng"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("SuoDing") || jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
#endregion
#endregion
#region 取消订单恢复库存
if (orderState == Enums.OrderState. &&
!isNewOrder &&
dbOrder.OrderState != Enums.OrderState. &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType.)
{
var currentOrderCostDetailList = dbOrderCostDetailList.Where(ocd => ocd.OrderId == orderId);
if (currentOrderCostDetailList.Count() > 0)
{
foreach (var orderCostDetail in currentOrderCostDetailList)
{
var updateSql = fsql.Update<PurchaseOrder>(orderCostDetail.PurchaseOrderPKId)
.Set(po => po.RemainingQuantity + orderCostDetail.DeductionQuantity);
updatePurchaseOrderList.Add(updateSql);
}
}
}
#endregion
#region 扣减库存, 计算成本
if (dbOrder.StorageType != null &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType. &&
orderState != null &&
orderState != Enums.OrderState. &&
orderState != Enums.OrderState.)
{
var orderCost = dbOrderCostList.FirstOrDefault(oc => oc.OrderId == dbOrder.Id);
if (orderCost == null)
{
//再查询一次数据库,以防同步开始执行后被人为操作扣减库存,造成重复扣减库存
if (!fsql.Select<OrderCost>(dbOrder.Id).Any())
{
var orderSkuJArray = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M);
if (orderSkuJArray != null && orderSkuJArray.Count() > 0)
{
var orderCostPurchaseAmount = 0M;
var orderDeliveryExpressFreight = 0M; //发货总运费,sku购买数量第二个开始半价
#region 扣减库存
foreach (var orderSkuJToken in orderSkuJArray)
{
var orderSkuId = orderSkuJToken.Value<string>("skuId");
var itemTotal = orderSkuJToken.Value<int>("itemTotal"); //sku购买数量
var isReduceMultiTimes = false; //是否多次扣减库存
while (itemTotal != 0)
{
var purchaseOrder = dbPurchaseOrderList.FirstOrDefault(po => po.StorageType == dbOrder.StorageType &&
po.RemainingQuantity != 0 &&
po.SkuId == orderSkuId);
if (purchaseOrder == null)
break; //没有库存了
//本次扣减量
var deductionQuantity = purchaseOrder.RemainingQuantity >= itemTotal ? itemTotal : purchaseOrder.RemainingQuantity;
//本次扣减量的采购成本
var currentPurchaseAmount = purchaseOrder.UnitCost * deductionQuantity;
//本次扣减量的发货运费
var currentSkuDeliveryFreight = isReduceMultiTimes ?
(purchaseOrder.SingleDeliveryFreight / 2 * deductionQuantity) :
(purchaseOrder.SingleDeliveryFreight + purchaseOrder.SingleDeliveryFreight / 2 * (deductionQuantity - 1));
purchaseOrder.RemainingQuantity -= deductionQuantity;
itemTotal -= deductionQuantity;
//累计采购成本
orderCostPurchaseAmount += currentPurchaseAmount;
//累计发货运费(销售运费)
orderDeliveryExpressFreight += currentSkuDeliveryFreight;
isReduceMultiTimes = true;
var updateSql = fsql.Update<PurchaseOrder>(purchaseOrder.Id).Set(po => po.RemainingQuantity - deductionQuantity);
updatePurchaseOrderList.Add(updateSql);
var orderCostDetail = new OrderCostDetail()
{
Id = idGenerator.NewLong(),
OrderId = orderId,
ProductId = orderSkuJToken.Value<string>("wareId"),
SkuId = orderSkuId,
CreateTime = DateTime.Now,
PurchaseOrderPKId = purchaseOrder.Id,
UnitCost = purchaseOrder.UnitCost,
DeductionQuantity = deductionQuantity,
DeliveryExpressFreight = currentSkuDeliveryFreight,
TotalCost = currentPurchaseAmount,
ConsumableAmount = purchaseOrder.SingleConsumableAmount * deductionQuantity,
FirstFreight = purchaseOrder.SingleFirstFreight * deductionQuantity,
OperationAmount = purchaseOrder.SingleOperationAmount * deductionQuantity,
PurchaseFreight = purchaseOrder.SingleFreight * deductionQuantity,
SkuAmount = purchaseOrder.SingleSkuAmount * deductionQuantity,
StorageAmount = purchaseOrder.SingleStorageAmount * deductionQuantity
};
insertOrderCostDetailList.Add(orderCostDetail);
}
}
#endregion
#region 计算成本
orderCost = new OrderCost()
{
OrderId = orderId,
PlatformCommissionRatio = platformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
PurchaseAmount = orderCostPurchaseAmount,
DeliveryExpressFreight = orderDeliveryExpressFreight,
CreateTime = DateTime.Now
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCostList.Add(orderCost);
#endregion
}
}
}
}
#endregion
#region 检查订单信息是否变化
if (isNewOrder)
{
dbOrder.OrderState = orderState;
}
else if ((orderState != null && orderState != dbOrder.OrderState) ||
buyerRemark != dbOrder.BuyerRemark ||
venderRemark != dbOrder.VenderRemark ||
modifyTime != dbOrder.ModifyTime ||
endTime != dbOrder.EndTime ||
waybillNo != dbOrder.WaybillNo)
{
var updateSql = fsql.Update<Order>(orderId).SetIf(orderState != null && orderState != dbOrder.OrderState, o => o.OrderState, orderState)
.SetIf(buyerRemark != dbOrder.BuyerRemark, o => o.BuyerRemark, buyerRemark)
.SetIf(venderRemark != dbOrder.VenderRemark, o => o.VenderRemark, venderRemark)
.SetIf(modifyTime != dbOrder.ModifyTime, o => o.ModifyTime, modifyTime)
.SetIf(endTime != dbOrder.EndTime, o => o.EndTime, modifyTime)
.SetIf(waybillNo != dbOrder.WaybillNo, o => o.WaybillNo, waybillNo);
updateOrderList.Add(updateSql);
}
#endregion
}
#region 补齐sku logo
if (insertOrderSkuList.Count() > 0)
{
foreach (var orderSku in insertOrderSkuList)
{
if (!orderSkuIds.Contains(orderSku.SkuId))
orderSkuIds.Add(orderSku.SkuId);
}
var orderSkuRequestCount = (orderSkuIds.Count() - 1) / 50 + 1; //sku最多一次请求50条
for (var i = 0; i < orderSkuRequestCount; i++)
{
var orderSkuIdString = string.Join(",", orderSkuIds.Skip(i * 50).Take(50));
var skuHttpResult = restApiService.SendRequest(relayAPIHost, "Api/PlatformSDK/GetSimpleProductSkuList", new SearchProductSkuRequest()
{
AppKey = appKey,
AppSecret = appSecret,
AppToken = appToken,
Platform = Enums.Platform.,
Sku = orderSkuIdString
}, null, HttpMethod.Post);
if (skuHttpResult.StatusCode != System.Net.HttpStatusCode.OK)
continue;
var skuResponse = JsonConvert.DeserializeObject<ApiResponse<IList<SimpleProductSkuResponse>>>(skuHttpResult.Content);
if (!skuResponse.Success)
continue;
foreach (var sku in skuResponse.Data)
{
var insertSkus = insertOrderSkuList.Where(orderSku => orderSku.SkuId == sku.Id);
foreach (var insertSku in insertSkus) { insertSku.Logo = sku.Logo; }
}
}
}
#endregion
fsql.Transaction(() =>
{
if (insertOrderList.Count() > 0)
fsql.Insert(insertOrderList).ExecuteAffrows();
if (insertOrderSkuList.Count() > 0)
fsql.Insert(insertOrderSkuList).ExecuteAffrows();
if (insertOrderConsigneeList.Count() > 0)
fsql.Insert(insertOrderConsigneeList).ExecuteAffrows();
if (insertOrderCostList.Count() > 0)
fsql.Insert(insertOrderCostList).ExecuteAffrows();
if (insertOrderCostDetailList.Count() > 0)
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
if (insertOrderCouponList.Count() > 0)
fsql.Insert(insertOrderCouponList).ExecuteAffrows();
if (updatePurchaseOrderList.Count() > 0)
{
foreach (var update in updatePurchaseOrderList)
update.ExecuteAffrows();
}
if (updateOrderList.Count() > 0)
{
foreach (var update in updateOrderList)
update.ExecuteAffrows();
}
});
}
/// <summary>
/// 同步所有店铺的订单
/// </summary>
public void SyncAllShopOrder()
{
var shopList = venderBusiness.GetShopList();
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncOrder(shop, string.Empty, isAuto: true), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
}
private void SyncJDRefundOrder(JArray refundOrderTokenJArray, ShopResponse shopResponse)
{
var shopId = long.Parse(shopResponse.ShopId);
var validRefundOrderTokenJArray = refundOrderTokenJArray.Where(j => j.Value<int>("status") == 13 && j.Value<decimal>("refoundAmount") != 0M).ToList();
var orderIds = validRefundOrderTokenJArray.Select(j => j["sameOrderServiceBill"]["orderId"].ToString()).Distinct().ToList();
var orderSkuIds = validRefundOrderTokenJArray.Select(j => j["sameOrderServiceBill"]["wareId"].ToString()).Distinct().ToList();
var updateOrders = fsql.Select<Order>().Where(o => orderIds.Contains(o.Id) && o.IsAfterSaleOrder == false).ToList();
var updateOrderSkus = fsql.Select<OrderSku>().Where(osku => orderIds.Contains(osku.OrderId) &&
orderSkuIds.Contains(osku.SkuId) &&
osku.IsRefund == false).ToList();
List<AfterSaleOrder> afterSaleOrders = new List<AfterSaleOrder>();
foreach (var refundOrderJToken in validRefundOrderTokenJArray)
{
var skuId = refundOrderJToken["sameOrderServiceBill"]["wareId"].ToString();
var orderId = refundOrderJToken["sameOrderServiceBill"]["orderId"].ToString();
var updateSku = updateOrderSkus.FirstOrDefault(osku => osku.OrderId == orderId && osku.SkuId == skuId);
if (updateSku == null)
continue;
var refundAmount = refundOrderJToken.Value<decimal>("refoundAmount");
var refundCompleteTime = refundOrderJToken.Value<long>("completeTime").StampToDateTime();
afterSaleOrders.Add(new AfterSaleOrder()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
OrderId = updateSku.OrderId,
ProductId = updateSku.ProductId,
RefundAmount = refundAmount,
RefundTime = refundCompleteTime,
SkuId = skuId,
ShopId = shopId
});
}
fsql.Transaction(() =>
{
if (updateOrders.Count() > 0)
foreach (var updateOrder in updateOrders)
fsql.Update<Order>(updateOrder.Id).Set(o => o.IsAfterSaleOrder, true).ExecuteAffrows();
if (updateOrderSkus.Count() > 0)
foreach (var updateOrderSku in updateOrderSkus)
fsql.Update<OrderSku>(updateOrderSku.Id).Set(osku => osku.IsRefund, true).ExecuteAffrows();
if (afterSaleOrders.Count() > 0)
fsql.Insert(afterSaleOrders).ExecuteAffrows();
});
}
public void SyncRefundOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
{
try
{
logger.Info($"退款订单同步 {shop.ShopName} isAuto {isAuto}");
if (!syncOrderMethodDic.ContainsKey(shop.PlatformId))
throw new Exception("不支持的平台");
var shopId = long.Parse(shop.ShopId);
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
var refundOrderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetRefundList", new SearchRefundPlatformOrderRequest()
{
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
}, null, HttpMethod.Post);
if (refundOrderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取退款订单失败 {refundOrderListApiResult.Content}");
var refundOrderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(refundOrderListApiResult.Content);
if (!refundOrderListResponse.Success)
throw new Exception($"获取退款订单失败 {refundOrderListApiResult.Content}");
if (refundOrderListResponse.Data == null || refundOrderListResponse.Data.Count == 0)
return;
syncRefundOrderMethodDic[shop.PlatformId](refundOrderListResponse.Data, shop);
}
catch (Exception ex)
{
var shopData = JsonConvert.SerializeObject(shop);
logger.Error(ex, $"SyncRefundOrder ShopData:{shopData}");
}
}
public void SyncAllShopRefundOrder()
{
var shopList = venderBusiness.GetShopList();
//SyncRefundOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncRefundOrder(shop, string.Empty, isAuto: true), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncRefundOrderTaskScheduler);
}
}
}
}

24
BBWY.Server.Business/PlatformSDK/JDBusiness.cs

@ -5,6 +5,7 @@ using BBWY.Server.Model.Dto;
using Jd.ACES;
using Jd.Api;
using Jd.Api.Request;
using Jd.Api.Response;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -470,5 +471,28 @@ namespace BBWY.Server.Business
//return base.GetRefundList(searchRefundPlatformOrderRequest);
return (JArray)response.Json["jingdong_asc_serviceAndRefund_view_responce"]["pageResult"]["data"];
}
public override JArray GetAfterOrderList(SyncAfterOrderRequest syncAfterOrderRequest)
{
var jdClient = GetJdClient(syncAfterOrderRequest.AppKey, syncAfterOrderRequest.AppSecret);
var req = new AscQueryListRequest();
req.buId = syncAfterOrderRequest.VenderId;
req.operatePin = "开发测试";
req.operateNick = "开发测试";
req.finishTimeBegin = syncAfterOrderRequest.StartDate;
req.finishTimeEnd = syncAfterOrderRequest.EndDate;
req.pageNumber = syncAfterOrderRequest.PageIndex.ToString();
req.pageSize = syncAfterOrderRequest.PageSize.ToString();
if (!string.IsNullOrEmpty(syncAfterOrderRequest.OrderId))
req.orderId = long.Parse(syncAfterOrderRequest.OrderId);
AscQueryListResponse response = jdClient.Execute(req, syncAfterOrderRequest.AppToken, DateTime.Now.ToLocalTime());
if (response.IsError)
throw new BusinessException($"获取售后订单失败 {(string.IsNullOrEmpty(response.ErrorMsg) ? response.ErrMsg : response.ErrorMsg)}");
if (response.Json == null)
response.Json = JsonConvert.DeserializeObject<JObject>(response.Body);
return (JArray)response.Json["jingdong_asc_query_list_responce"]["pageResult"]["data"];
}
}
}

4
BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs

@ -99,6 +99,8 @@ namespace BBWY.Server.Business
throw new NotImplementedException();
}
public virtual JArray GetRefundList(SearchRefundPlatformOrderRequest searchRefundPlatformOrderRequest) { throw new NotImplementedException(); }
public virtual JArray GetRefundList(SearchRefundPlatformOrderRequest searchRefundPlatformOrderRequest) { throw new NotImplementedException(); }
public virtual JArray GetAfterOrderList(SyncAfterOrderRequest syncAfterOrderRequest) { throw new NotImplementedException(); }
}
}

64
BBWY.Server.Business/Sync/AfterSaleOrderSyncBusiness.cs

@ -0,0 +1,64 @@
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Model;
using BBWY.Server.Model.Dto;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace BBWY.Server.Business
{
public class AfterSaleOrderSyncBusiness : BaseSyncBusiness, IDenpendency
{
private IDictionary<Enums.Platform, Action<JArray, ShopResponse>> syncAfterSaleOrderMethodDic;
public AfterSaleOrderSyncBusiness(RestApiService restApiService,
IOptions<GlobalConfig> options,
ILogger logger,
IFreeSql fsql,
IIdGenerator idGenerator,
TaskSchedulerManager taskSchedulerManager,
VenderBusiness venderBusiness) : base(restApiService,
options,
logger,
fsql,
idGenerator,
taskSchedulerManager,
venderBusiness)
{
syncAfterSaleOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, ShopResponse>>()
{
{ Enums.Platform., SyncJDAfterOrder }
};
}
private void SyncJDAfterOrder(JArray refundOrderTokenJArray, ShopResponse shopResponse)
{
}
private void SyncAfterOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
{
}
public void SyncAllShopAfterOrder()
{
var shopList = venderBusiness.GetShopList();
//SyncRefundOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncAfterOrder(shop, string.Empty, isAuto: true),
System.Threading.CancellationToken.None,
TaskCreationOptions.LongRunning,
taskSchedulerManager.SyncAfterOrderTaskScheduler);
}
}
}
}

32
BBWY.Server.Business/Sync/BaseSyncBusiness.cs

@ -0,0 +1,32 @@
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Model;
using Microsoft.Extensions.Options;
using NLog;
using Yitter.IdGenerator;
namespace BBWY.Server.Business
{
public class BaseSyncBusiness : BasePlatformRelayBusiness, IDenpendency
{
protected ILogger logger;
protected IFreeSql fsql;
protected IIdGenerator idGenerator;
protected TaskSchedulerManager taskSchedulerManager;
protected VenderBusiness venderBusiness;
public BaseSyncBusiness(RestApiService restApiService,
IOptions<GlobalConfig> options,
ILogger logger,
IFreeSql fsql,
IIdGenerator idGenerator,
TaskSchedulerManager taskSchedulerManager,
VenderBusiness venderBusiness) : base(restApiService, options)
{
this.logger = logger;
this.fsql = fsql;
this.idGenerator = idGenerator;
this.venderBusiness = venderBusiness;
}
}
}

605
BBWY.Server.Business/Sync/OrderSyncBusiness.cs

@ -0,0 +1,605 @@
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Business.PlatformSDK.DataExtension;
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;
namespace BBWY.Server.Business
{
public class OrderSyncBusiness : BaseSyncBusiness, IDenpendency
{
private IDictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>> syncOrderMethodDic;
public OrderSyncBusiness(RestApiService restApiService,
IOptions<GlobalConfig> options,
ILogger logger,
IFreeSql fsql,
IIdGenerator idGenerator,
TaskSchedulerManager taskSchedulerManager,
VenderBusiness venderBusiness) : base(restApiService,
options,
logger,
fsql,
idGenerator,
taskSchedulerManager,
venderBusiness)
{
syncOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>>()
{
{ Enums.Platform., SyncJDOrder }
};
}
/// <summary>
/// 同步订单
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderId"></param>
/// <param name="startTime">默认3小时前</param>
/// <param name="endTime">默认当前时间</param>
/// <exception cref="Exception"></exception>
public void SyncOrder(long shopId, string orderId, DateTime? startTime = null, DateTime? endTime = null)
{
var shop = venderBusiness.GetShopByShopId(shopId.ToString());
SyncOrder(shop, orderId, startTime, endTime);
}
private void SyncOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
{
try
{
logger.Info($"订单同步 {shop.ShopName} isAuto {isAuto}");
if (!syncOrderMethodDic.ContainsKey(shop.PlatformId))
throw new Exception("不支持的平台");
var shopId = long.Parse(shop.ShopId);
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
var orderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetOrderList", new SearchPlatformOrderRequest()
{
StartDate = startTime ?? DateTime.Now.AddHours(-3),
EndDate = endTime ?? DateTime.Now,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
PageIndex = 1,
PageSize = 100,
Platform = shop.PlatformId,
JDColType = string.IsNullOrEmpty(shop.ShopType) ? "0" : shop.ShopType,
//SaveResponseLog = true,
OrderId = orderId
}, null, HttpMethod.Post);
if (orderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
var orderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(orderListApiResult.Content);
if (!orderListResponse.Success)
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
if (orderListResponse.Data == null || orderListResponse.Data.Count == 0)
return;
syncOrderMethodDic[shop.PlatformId](orderListResponse.Data, shopId, relayAPIHost, shop.AppKey, shop.AppSecret, shop.AppToken, shop.PlatformCommissionRatio ?? 0.05M);
}
catch (Exception ex)
{
var shopData = JsonConvert.SerializeObject(shop);
logger.Error(ex, $"SyncOrder ShopData:{shopData}");
}
}
public void SyncOrderByDate(SyncOrderByDateRequest syncOrderByDateRequest)
{
if (fsql.Select<OrderSyncTask>().Where(ost => ost.ShopId == syncOrderByDateRequest.ShopId && ost.State == Enums.OrderSyncState.Running).Any())
throw new BusinessException("存在未结束的同步任务,请稍后同步");
syncOrderByDateRequest.EndTime = syncOrderByDateRequest.EndTime.Date.AddDays(1).AddSeconds(-1);
if ((syncOrderByDateRequest.EndTime - syncOrderByDateRequest.StartTime).Days > 7)
throw new BusinessException("同步任务时差最长7天");
var orderSyncTask = new OrderSyncTask()
{
Id = idGenerator.NewLong(),
ShopId = syncOrderByDateRequest.ShopId,
State = Enums.OrderSyncState.Running,
SyncStartTime = syncOrderByDateRequest.StartTime,
SyncEndTime = syncOrderByDateRequest.EndTime
};
fsql.Insert(orderSyncTask).ExecuteAffrows();
Task.Factory.StartNew(() =>
{
var currentStartTime = syncOrderByDateRequest.StartTime;
var currentEndTime = currentStartTime.AddHours(3);
var keeploop = true;
while (keeploop)
{
try
{
SyncOrder(syncOrderByDateRequest.ShopId, String.Empty, currentStartTime, currentEndTime);
}
catch (Exception ex) { }
finally
{
var lessHour = (syncOrderByDateRequest.EndTime - currentEndTime).TotalHours;
if (lessHour > 3)
{
currentStartTime = currentStartTime.AddHours(3);
currentEndTime = currentEndTime.AddHours(3);
}
else if (lessHour > 0 && lessHour < 3)
{
currentStartTime = currentEndTime;
currentEndTime = syncOrderByDateRequest.EndTime;
}
else if (lessHour <= 0)
{
keeploop = false;
}
}
}
try
{
fsql.Update<OrderSyncTask>(orderSyncTask.Id).Set(ost => ost.State, Enums.OrderSyncState.End).ExecuteAffrows();
}
catch (Exception ex) { }
}, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
private void SyncJDOrder(JArray orderTokenJArray, long shopId, string relayAPIHost, string appKey, string appSecret, string appToken, decimal platformCommissionRatio)
{
var orderTokenList = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") != 0);
var interfaceOrderIdList = orderTokenList.Select(orderJToken => orderJToken.Value<string>("orderId"));
var interfaceCanceledOrderIdList = orderTokenList.Where(orderJToken => orderJToken.Value<string>("orderState").Equals("TRADE_CANCELED"))
.Select(orderJToken => orderJToken.Value<string>("orderId")); //接口查询结果中取消状态的订单Id
var dbOrderList = fsql.Select<Order>().Where(o => interfaceOrderIdList.Contains(o.Id)).ToList(o => new Order()
{
Id = o.Id,
OrderState = o.OrderState,
StorageType = o.StorageType
}); //数据库订单
var dbOrderConsigneeList = fsql.Select<OrderConsignee>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单收货信息
var dbOrderCostList = fsql.Select<OrderCost>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单成本信息
var dbOrderCouponList = fsql.Select<OrderCoupon>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单优惠信息
List<OrderCostDetail> dbOrderCostDetailList = null; //数据库成本明细
if (interfaceCanceledOrderIdList.Count() > 0 &&
dbOrderList.Any(dbOrder => interfaceCanceledOrderIdList.Contains(dbOrder.Id) && dbOrder.OrderState != Enums.OrderState.))
{
dbOrderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => interfaceCanceledOrderIdList.Contains(ocd.OrderId) && ocd.IsEnabled == true).ToList();
}
var orderSkuIds = new List<string>();
foreach (var orderJToken in orderTokenList)
{
var itemInfoList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuJToken => skuJToken.Value<string>("skuId"));
foreach (var skuId in itemInfoList)
{
if (!orderSkuIds.Contains(skuId))
orderSkuIds.Add(skuId);
}
}
var dbPurchaseOrderList = fsql.Select<PurchaseOrder>().Where(po => po.RemainingQuantity != 0 && orderSkuIds.Contains(po.SkuId)).ToList(); //数据库采购单
orderSkuIds.Clear();
#region 数据库操作
List<Order> insertOrderList = new List<Order>();
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
List<OrderCost> insertOrderCostList = new List<OrderCost>();
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
List<OrderCoupon> insertOrderCouponList = new List<OrderCoupon>();
IList<IUpdate<Order>> updateOrderList = new List<IUpdate<Order>>();
IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
#endregion
foreach (var orderJToken in orderTokenList)
{
var orderId = orderJToken.Value<string>("orderId");
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == orderId);
var isNewOrder = dbOrder == null;
#region 订单基本信息
var buyerRemark = orderJToken.Value<string>("orderRemark");
var venderRemark = orderJToken.Value<string>("venderRemark");
var modifyTime = orderJToken.Value<DateTime?>("modified");
var endTime = orderJToken.Value<DateTime?>("orderEndTime");
var waybillNo = orderJToken.Value<string>("waybill");
if (dbOrder == null)
{
dbOrder = new Order()
{
Id = orderId,
BuyerRemark = buyerRemark,
VenderRemark = venderRemark,
FreightPrice = orderJToken.Value<decimal>("freightPrice"),
EndTime = endTime,
StartTime = orderJToken.Value<DateTime>("orderStartTime"),
ModifyTime = modifyTime,
OrderPayment = orderJToken.Value<decimal>("orderPayment"),
SellerPreferentialAmount = orderJToken.Value<decimal>("sellerDiscount"),
OrderSellerPrice = orderJToken.Value<decimal>("orderSellerPrice"),
OrderTotalPrice = orderJToken.Value<decimal>("orderTotalPrice"),
OrderType = (Enums.OrderType)orderJToken.Value<int>("orderType"),
Platform = Enums.Platform.,
ShopId = shopId,
//VenderId = orderJToken.Value<long>("venderId"),
WaybillNo = waybillNo,
StoreOrder = orderJToken.Value<string>("storeOrder") ?? string.Empty,
StoreId = orderJToken.Value<string>("storeId")
};
if (dbOrder.StoreOrder.Contains("京仓"))
dbOrder.StorageType = Enums.StorageType.;
else if (dbOrder.StoreOrder.Contains("云仓"))
dbOrder.StorageType = Enums.StorageType.;
var payType = orderJToken.Value<string>("payType");
if (payType.Contains("-"))
dbOrder.PayType = (Enums.PayType)Convert.ToInt32(payType.Substring(0, 1));
insertOrderList.Add(dbOrder);
#region OrderSku
var orderSkuList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuToken => new OrderSku()
{
Id = idGenerator.NewLong(),
ItemTotal = skuToken.Value<int>("itemTotal"),
Price = skuToken.Value<decimal>("jdPrice"),
ProductId = skuToken.Value<string>("wareId"),
Title = skuToken.Value<string>("skuName").SimplifySkuName(),
ProductNo = skuToken.Value<string>("productNo"),
CreateTime = DateTime.Now,
OrderId = orderId,
SkuId = skuToken.Value<string>("skuId")
}).ToList();
insertOrderSkuList.AddRange(orderSkuList);
#endregion
}
#endregion
#region 收货人信息
if (dbOrderConsigneeList.FirstOrDefault(oc => oc.OrderId == orderId) == null)
{
var orderConsignee = new OrderConsignee()
{
OrderId = orderId,
//Address = orderJToken["consigneeInfo"].Value<string>("fullAddress"),
//ContactName = orderJToken["consigneeInfo"].Value<string>("fullname"),
//Mobile = orderJToken["consigneeInfo"].Value<string>("mobile"),
//TelePhone = orderJToken["consigneeInfo"].Value<string>("telephone"),
City = orderJToken["consigneeInfo"].Value<string>("city"),
Province = orderJToken["consigneeInfo"].Value<string>("province"),
County = orderJToken["consigneeInfo"].Value<string>("county"),
Town = orderJToken["consigneeInfo"].Value<string>("town"),
IsDecode = false,
CreateTime = DateTime.Now
};
insertOrderConsigneeList.Add(orderConsignee);
}
#endregion
#region 订单优惠
if (!dbOrderCouponList.Any(oc => oc.OrderId == orderId))
{
var orderCouponJArray = (JArray)orderJToken["couponDetailList"];
if (orderCouponJArray.HasValues)
{
foreach (var orderCouponJToken in orderCouponJArray)
{
var couponType = orderCouponJToken.Value<string>("couponType");
if (string.IsNullOrEmpty(couponType))
continue;
dbOrder.PreferentialAmount += orderCouponJToken.Value<decimal>("couponPrice");
insertOrderCouponList.Add(new OrderCoupon()
{
Id = idGenerator.NewLong(),
SkuId = orderCouponJToken.Value<string>("skuId"),
OrderId = orderId,
CreateTime = DateTime.Now,
CouponType = couponType,
CouponPrice = orderCouponJToken.Value<decimal>("couponPrice")
});
}
}
}
#endregion
#region 订单状态转换
var jdOrderState = orderJToken.Value<string>("orderState");
Enums.OrderState? orderState = null;
#region SOP状态翻译
if (jdOrderState.Equals("NOT_PAY")) //未付款
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_SELLER_STOCK_OUT")) //等待出库
{
orderState = Enums.OrderState.;
if (dbOrder.StorageType != null)
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WAIT_GOODS_RECEIVE_CONFIRM"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("FINISHED_L"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("POP_ORDER_PAUSE") || jdOrderState.Equals("PAUSE"))
{
orderState = Enums.OrderState.;
}
#endregion
#region FBP状态翻译
else if (jdOrderState.Equals("DengDaiDaYin") || jdOrderState.Equals("DengDaiChuKu") || jdOrderState.Equals("DengDaiDaBao") || jdOrderState.Equals("DengDaiFaHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("DengDaiQueRenShouHuo"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("WanCheng"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("SuoDing") || jdOrderState.Equals("LOCKED"))
{
orderState = Enums.OrderState.;
}
else if (jdOrderState.Equals("TRADE_CANCELED"))
{
orderState = Enums.OrderState.;
}
#endregion
#endregion
#region 取消订单恢复库存
if (orderState == Enums.OrderState. &&
!isNewOrder &&
dbOrder.OrderState != Enums.OrderState. &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType.)
{
var currentOrderCostDetailList = dbOrderCostDetailList.Where(ocd => ocd.OrderId == orderId);
if (currentOrderCostDetailList.Count() > 0)
{
foreach (var orderCostDetail in currentOrderCostDetailList)
{
var updateSql = fsql.Update<PurchaseOrder>(orderCostDetail.PurchaseOrderPKId)
.Set(po => po.RemainingQuantity + orderCostDetail.DeductionQuantity);
updatePurchaseOrderList.Add(updateSql);
}
}
}
#endregion
#region 扣减库存, 计算成本
if (dbOrder.StorageType != null &&
dbOrder.StorageType != Enums.StorageType.SD &&
dbOrder.StorageType != Enums.StorageType. &&
orderState != null &&
orderState != Enums.OrderState. &&
orderState != Enums.OrderState.)
{
var orderCost = dbOrderCostList.FirstOrDefault(oc => oc.OrderId == dbOrder.Id);
if (orderCost == null)
{
//再查询一次数据库,以防同步开始执行后被人为操作扣减库存,造成重复扣减库存
if (!fsql.Select<OrderCost>(dbOrder.Id).Any())
{
var orderSkuJArray = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M);
if (orderSkuJArray != null && orderSkuJArray.Count() > 0)
{
var orderCostPurchaseAmount = 0M;
var orderDeliveryExpressFreight = 0M; //发货总运费,sku购买数量第二个开始半价
#region 扣减库存
foreach (var orderSkuJToken in orderSkuJArray)
{
var orderSkuId = orderSkuJToken.Value<string>("skuId");
var itemTotal = orderSkuJToken.Value<int>("itemTotal"); //sku购买数量
var isReduceMultiTimes = false; //是否多次扣减库存
while (itemTotal != 0)
{
var purchaseOrder = dbPurchaseOrderList.FirstOrDefault(po => po.StorageType == dbOrder.StorageType &&
po.RemainingQuantity != 0 &&
po.SkuId == orderSkuId);
if (purchaseOrder == null)
break; //没有库存了
//本次扣减量
var deductionQuantity = purchaseOrder.RemainingQuantity >= itemTotal ? itemTotal : purchaseOrder.RemainingQuantity;
//本次扣减量的采购成本
var currentPurchaseAmount = purchaseOrder.UnitCost * deductionQuantity;
//本次扣减量的发货运费
var currentSkuDeliveryFreight = isReduceMultiTimes ?
(purchaseOrder.SingleDeliveryFreight / 2 * deductionQuantity) :
(purchaseOrder.SingleDeliveryFreight + purchaseOrder.SingleDeliveryFreight / 2 * (deductionQuantity - 1));
purchaseOrder.RemainingQuantity -= deductionQuantity;
itemTotal -= deductionQuantity;
//累计采购成本
orderCostPurchaseAmount += currentPurchaseAmount;
//累计发货运费(销售运费)
orderDeliveryExpressFreight += currentSkuDeliveryFreight;
isReduceMultiTimes = true;
var updateSql = fsql.Update<PurchaseOrder>(purchaseOrder.Id).Set(po => po.RemainingQuantity - deductionQuantity);
updatePurchaseOrderList.Add(updateSql);
var orderCostDetail = new OrderCostDetail()
{
Id = idGenerator.NewLong(),
OrderId = orderId,
ProductId = orderSkuJToken.Value<string>("wareId"),
SkuId = orderSkuId,
CreateTime = DateTime.Now,
PurchaseOrderPKId = purchaseOrder.Id,
UnitCost = purchaseOrder.UnitCost,
DeductionQuantity = deductionQuantity,
DeliveryExpressFreight = currentSkuDeliveryFreight,
TotalCost = currentPurchaseAmount,
ConsumableAmount = purchaseOrder.SingleConsumableAmount * deductionQuantity,
FirstFreight = purchaseOrder.SingleFirstFreight * deductionQuantity,
OperationAmount = purchaseOrder.SingleOperationAmount * deductionQuantity,
PurchaseFreight = purchaseOrder.SingleFreight * deductionQuantity,
SkuAmount = purchaseOrder.SingleSkuAmount * deductionQuantity,
StorageAmount = purchaseOrder.SingleStorageAmount * deductionQuantity
};
insertOrderCostDetailList.Add(orderCostDetail);
}
}
#endregion
#region 计算成本
orderCost = new OrderCost()
{
OrderId = orderId,
PlatformCommissionRatio = platformCommissionRatio,
PreferentialAmount = dbOrder.PreferentialAmount,
Profit = 0,
PurchaseAmount = orderCostPurchaseAmount,
DeliveryExpressFreight = orderDeliveryExpressFreight,
CreateTime = DateTime.Now
};
orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
orderCost.Profit = dbOrder.OrderSellerPrice +
dbOrder.FreightPrice -
orderCost.PurchaseAmount -
orderCost.DeliveryExpressFreight -
orderCost.PlatformCommissionAmount;
insertOrderCostList.Add(orderCost);
#endregion
}
}
}
}
#endregion
#region 检查订单信息是否变化
if (isNewOrder)
{
dbOrder.OrderState = orderState;
}
else if ((orderState != null && orderState != dbOrder.OrderState) ||
buyerRemark != dbOrder.BuyerRemark ||
venderRemark != dbOrder.VenderRemark ||
modifyTime != dbOrder.ModifyTime ||
endTime != dbOrder.EndTime ||
waybillNo != dbOrder.WaybillNo)
{
var updateSql = fsql.Update<Order>(orderId).SetIf(orderState != null && orderState != dbOrder.OrderState, o => o.OrderState, orderState)
.SetIf(buyerRemark != dbOrder.BuyerRemark, o => o.BuyerRemark, buyerRemark)
.SetIf(venderRemark != dbOrder.VenderRemark, o => o.VenderRemark, venderRemark)
.SetIf(modifyTime != dbOrder.ModifyTime, o => o.ModifyTime, modifyTime)
.SetIf(endTime != dbOrder.EndTime, o => o.EndTime, modifyTime)
.SetIf(waybillNo != dbOrder.WaybillNo, o => o.WaybillNo, waybillNo);
updateOrderList.Add(updateSql);
}
#endregion
}
#region 补齐sku logo
if (insertOrderSkuList.Count() > 0)
{
foreach (var orderSku in insertOrderSkuList)
{
if (!orderSkuIds.Contains(orderSku.SkuId))
orderSkuIds.Add(orderSku.SkuId);
}
var orderSkuRequestCount = (orderSkuIds.Count() - 1) / 50 + 1; //sku最多一次请求50条
for (var i = 0; i < orderSkuRequestCount; i++)
{
var orderSkuIdString = string.Join(",", orderSkuIds.Skip(i * 50).Take(50));
var skuHttpResult = restApiService.SendRequest(relayAPIHost, "Api/PlatformSDK/GetSimpleProductSkuList", new SearchProductSkuRequest()
{
AppKey = appKey,
AppSecret = appSecret,
AppToken = appToken,
Platform = Enums.Platform.,
Sku = orderSkuIdString
}, null, HttpMethod.Post);
if (skuHttpResult.StatusCode != System.Net.HttpStatusCode.OK)
continue;
var skuResponse = JsonConvert.DeserializeObject<ApiResponse<IList<SimpleProductSkuResponse>>>(skuHttpResult.Content);
if (!skuResponse.Success)
continue;
foreach (var sku in skuResponse.Data)
{
var insertSkus = insertOrderSkuList.Where(orderSku => orderSku.SkuId == sku.Id);
foreach (var insertSku in insertSkus) { insertSku.Logo = sku.Logo; }
}
}
}
#endregion
fsql.Transaction(() =>
{
if (insertOrderList.Count() > 0)
fsql.Insert(insertOrderList).ExecuteAffrows();
if (insertOrderSkuList.Count() > 0)
fsql.Insert(insertOrderSkuList).ExecuteAffrows();
if (insertOrderConsigneeList.Count() > 0)
fsql.Insert(insertOrderConsigneeList).ExecuteAffrows();
if (insertOrderCostList.Count() > 0)
fsql.Insert(insertOrderCostList).ExecuteAffrows();
if (insertOrderCostDetailList.Count() > 0)
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
if (insertOrderCouponList.Count() > 0)
fsql.Insert(insertOrderCouponList).ExecuteAffrows();
if (updatePurchaseOrderList.Count() > 0)
{
foreach (var update in updatePurchaseOrderList)
update.ExecuteAffrows();
}
if (updateOrderList.Count() > 0)
{
foreach (var update in updateOrderList)
update.ExecuteAffrows();
}
});
}
/// <summary>
/// 同步所有店铺的订单
/// </summary>
public void SyncAllShopOrder()
{
var shopList = venderBusiness.GetShopList();
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncOrder(shop, string.Empty, isAuto: true), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
}
}
}
}

147
BBWY.Server.Business/Sync/RefundOrderSyncBusiness.cs

@ -0,0 +1,147 @@
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 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;
namespace BBWY.Server.Business
{
public class RefundOrderSyncBusiness : BaseSyncBusiness, IDenpendency
{
private IDictionary<Enums.Platform, Action<JArray, ShopResponse>> syncRefundOrderMethodDic;
public RefundOrderSyncBusiness(RestApiService restApiService,
IOptions<GlobalConfig> options,
ILogger logger,
IFreeSql fsql,
IIdGenerator idGenerator,
TaskSchedulerManager taskSchedulerManager,
VenderBusiness venderBusiness) : base(restApiService,
options,
logger,
fsql,
idGenerator,
taskSchedulerManager,
venderBusiness)
{
syncRefundOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, ShopResponse>>()
{
{ Enums.Platform., SyncJDRefundOrder}
};
}
private void SyncJDRefundOrder(JArray refundOrderTokenJArray, ShopResponse shopResponse)
{
var shopId = long.Parse(shopResponse.ShopId);
var validRefundOrderTokenJArray = refundOrderTokenJArray.Where(j => j.Value<int>("status") == 13 && j.Value<decimal>("refoundAmount") != 0M).ToList();
var orderIds = validRefundOrderTokenJArray.Select(j => j["sameOrderServiceBill"]["orderId"].ToString()).Distinct().ToList();
var orderSkuIds = validRefundOrderTokenJArray.Select(j => j["sameOrderServiceBill"]["wareId"].ToString()).Distinct().ToList();
var updateOrders = fsql.Select<Order>().Where(o => orderIds.Contains(o.Id) && o.IsAfterSaleOrder == false).ToList();
var updateOrderSkus = fsql.Select<OrderSku>().Where(osku => orderIds.Contains(osku.OrderId) &&
orderSkuIds.Contains(osku.SkuId) &&
osku.IsRefund == false).ToList();
List<AfterSaleOrder> afterSaleOrders = new List<AfterSaleOrder>();
foreach (var refundOrderJToken in validRefundOrderTokenJArray)
{
var skuId = refundOrderJToken["sameOrderServiceBill"]["wareId"].ToString();
var orderId = refundOrderJToken["sameOrderServiceBill"]["orderId"].ToString();
var updateSku = updateOrderSkus.FirstOrDefault(osku => osku.OrderId == orderId && osku.SkuId == skuId);
if (updateSku == null)
continue;
var refundAmount = refundOrderJToken.Value<decimal>("refoundAmount");
var refundCompleteTime = refundOrderJToken.Value<long>("completeTime").StampToDateTime();
afterSaleOrders.Add(new AfterSaleOrder()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
OrderId = updateSku.OrderId,
ProductId = updateSku.ProductId,
RefundAmount = refundAmount,
RefundTime = refundCompleteTime,
SkuId = skuId,
ShopId = shopId
});
}
fsql.Transaction(() =>
{
if (updateOrders.Count() > 0)
foreach (var updateOrder in updateOrders)
fsql.Update<Order>(updateOrder.Id).Set(o => o.IsAfterSaleOrder, true).ExecuteAffrows();
if (updateOrderSkus.Count() > 0)
foreach (var updateOrderSku in updateOrderSkus)
fsql.Update<OrderSku>(updateOrderSku.Id).Set(osku => osku.IsRefund, true).ExecuteAffrows();
if (afterSaleOrders.Count() > 0)
fsql.Insert(afterSaleOrders).ExecuteAffrows();
});
}
private void SyncRefundOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
{
try
{
logger.Info($"退款订单同步 {shop.ShopName} isAuto {isAuto}");
if (!syncRefundOrderMethodDic.ContainsKey(shop.PlatformId))
throw new Exception("不支持的平台");
var shopId = long.Parse(shop.ShopId);
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
var refundOrderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetRefundList", new SearchRefundPlatformOrderRequest()
{
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
}, null, HttpMethod.Post);
if (refundOrderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取退款订单失败 {refundOrderListApiResult.Content}");
var refundOrderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(refundOrderListApiResult.Content);
if (!refundOrderListResponse.Success)
throw new Exception($"获取退款订单失败 {refundOrderListApiResult.Content}");
if (refundOrderListResponse.Data == null || refundOrderListResponse.Data.Count == 0)
return;
syncRefundOrderMethodDic[shop.PlatformId](refundOrderListResponse.Data, shop);
}
catch (Exception ex)
{
var shopData = JsonConvert.SerializeObject(shop);
logger.Error(ex, $"SyncRefundOrder ShopData:{shopData}");
}
}
public void SyncAllShopRefundOrder()
{
var shopList = venderBusiness.GetShopList();
//SyncRefundOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncRefundOrder(shop, string.Empty, isAuto: true), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncRefundOrderTaskScheduler);
}
}
}
}

3
BBWY.Server.Business/TaskSchedulerManager.cs

@ -8,12 +8,15 @@ namespace BBWY.Server.Business
public LimitedConcurrencyLevelTaskScheduler SyncRefundOrderTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler SyncAfterOrderTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler PurchaseOrderCallbackTaskScheduler { get; private set; }
public TaskSchedulerManager()
{
SyncOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncRefundOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncAfterOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
}
}

46
BBWY.Server.Business/TestBusiness.cs

@ -0,0 +1,46 @@
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Model;
using BBWY.Server.Model.Db.Mds;
using FreeSql;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
namespace BBWY.Server.Business
{
public class TestBusiness : BasePlatformRelayBusiness, IDenpendency
{
private FreeSqlMultiDBManager freeSqlMultiDBManager;
private VenderBusiness venderBusiness;
public TestBusiness(RestApiService restApiService,
IOptions<GlobalConfig> options,
FreeSqlMultiDBManager freeSqlMultiDBManager,
VenderBusiness venderBusiness) : base(restApiService, options)
{
this.freeSqlMultiDBManager = freeSqlMultiDBManager;
this.venderBusiness = venderBusiness;
}
public void SyncVenderId()
{
var noVenderShops = freeSqlMultiDBManager.MDSfsql.Select<Shops>().Where(s => !string.IsNullOrEmpty(s.AppToken) && !string.IsNullOrEmpty(s.ShopId) && string.IsNullOrEmpty(s.VenderId)).ToList();
//IList < IUpdate < Shops >> updateShops = new List<IUpdate<Shops>>();
foreach (var noVenderShop in noVenderShops)
{
if (string.IsNullOrEmpty(noVenderShop.AppKey))
{
}
var venderResponse = venderBusiness.GetVenderInfo(new Model.Dto.PlatformRequest()
{
AppKey = noVenderShop.AppKey,
AppSecret = noVenderShop.AppSecret,
AppToken = noVenderShop.AppToken,
Platform = (Enums.Platform)noVenderShop.PlatformId
});
freeSqlMultiDBManager.MDSfsql.Update<Shops>(noVenderShop.Id).Set(s => s.VenderId, venderResponse.VenderId).ExecuteAffrows();
}
}
}
}

8
BBWY.Server.Business/Vender/VenderBusiness.cs

@ -67,7 +67,8 @@ namespace BBWY.Server.Business
venderResponse.ShopName,
venderResponse.ShopId,
ShopType = venderResponse.ColType,
AppToken = jDShopToken.Access_Token
AppToken = jDShopToken.Access_Token,
venderResponse.VenderId
}, new Dictionary<string, string>() { { "qy", "qy" } }, HttpMethod.Post);
}
@ -224,5 +225,10 @@ namespace BBWY.Server.Business
{
return freeSqlMultiDBManager.MDSfsql.Select<Shops>().Where(s => !string.IsNullOrEmpty(s.ShopId)).ToList<ShopResponse>();
}
public ShopResponse GetShopByShopId(string shopId)
{
return freeSqlMultiDBManager.MDSfsql.Select<Shops>().Where(s => s.ShopId == shopId).ToOne<ShopResponse>();
}
}
}

6
BBWY.Server.Model/Db/Mds/Shops.cs

@ -74,6 +74,12 @@ namespace BBWY.Server.Model.Db.Mds
[Column(StringLength = 50)]
public string PurchasePlatformId { get; set; }
/// <summary>
/// 商家编号
/// </summary>
public string VenderId { get; set; }
/// <summary>
/// 店铺ID
/// </summary>

20
BBWY.Server.Model/Dto/Request/Sync/SyncAfterOrderRequest.cs

@ -0,0 +1,20 @@
using BBWY.Server.Model.Dto;
using System;
namespace BBWY.Server.Model
{
public class SyncAfterOrderRequest : PlatformRequest
{
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int PageIndex { get; set; }
public int PageSize { get; set; }
public string OrderId { get; set; }
public string VenderId { get; set; }
}
}

2
BBWY.Server.Model/Dto/Response/Vender/ShopResponse.cs

@ -10,6 +10,8 @@ namespace BBWY.Server.Model.Dto
public string ShopId { get; set; }
public string VenderId { get; set; }
public string ShopName { get; set; }
/// <summary>

21
BBWY.Test/Program.cs

@ -30,12 +30,19 @@ namespace BBWY.Test
var token = "2ace3023200c4ea9aa682bbf8bffee18jztm";
var jdClient = GetJdClient(appKey, appSecret);
AscQueryListRequest req = new AscQueryListRequest();
req.buId = "10598776";
req.operatePin = "开发测试";
req.operateNick = "开发测试";
req.orderId = 249263452032;
//AscQueryListRequest req = new AscQueryListRequest();
//req.buId = "10598776";
//req.operatePin = "开发测试";
//req.operateNick = "开发测试";
//req.finishTimeBegin = DateTime.Now.AddDays(-30);
//req.finishTimeEnd = DateTime.Now;
//req.pageNumber = "1";
//req.pageSize = "20";
//req.orderId = 164569571399;
//req.serviceId = 123L;
//req.orderId = 123L;
//req.applyTimeBegin = new Date();
@ -55,8 +62,8 @@ namespace BBWY.Test
//req.pageSize = 123;
//req.extJsonStr = "abc";
AscQueryListResponse response = jdClient.Execute(req, token, DateTime.Now.ToLocalTime());
Console.WriteLine(JsonConvert.SerializeObject(response));
//AscQueryListResponse response = jdClient.Execute(req, token, DateTime.Now.ToLocalTime());
//Console.WriteLine(JsonConvert.SerializeObject(response));
Console.ReadKey();
}
}

Loading…
Cancel
Save