步步为盈
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

531 lines
28 KiB

2 years ago
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.Model;
using BBWY.Server.Model.Dto;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
2 years ago
using System.Net.Http;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using System.Linq;
using BBWY.Server.Model.Db;
2 years ago
using FreeSql;
2 years ago
namespace BBWY.Server.Business.Sync
{
public class JDServiceOrderSyncBusiness : BaseSyncBusiness, IDenpendency
{
2 years ago
private IList<LogisticsCompanyRelationship> jd_kd100_logisticsCompanyDictionary;
2 years ago
private IList<int> kuaiDi100PushStateList;
2 years ago
2 years ago
public JDServiceOrderSyncBusiness(RestApiService restApiService, IOptions<GlobalConfig> options, NLogManager nLogManager, IFreeSql fsql, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager, VenderBusiness venderBusiness, YunDingBusiness yunDingBusiness) : base(restApiService, options, nLogManager, fsql, idGenerator, taskSchedulerManager, venderBusiness, yunDingBusiness)
{
2 years ago
/*
yuantong
yunda
zhongtong
shentong
jtexpress
youzhengguonei
shunfeng
ems EMS
jd
youzhengbk
fengwang
debangkuaidi
debangwuliu
zhongtongkuaiyun
danniao
subida
lianhaowuliu
yundakuaiyun
annengwuliu
kuayue
jingdongkuaiyun
huitongkuaidi
*/
2 years ago
kuaiDi100PushStateList = new List<int>()
{
0, //在途
1, //揽收
3, //签收
5, //派件
};
2 years ago
2 years ago
jd_kd100_logisticsCompanyDictionary = new List<LogisticsCompanyRelationship>()
{
2 years ago
new LogisticsCompanyRelationship(){ SourceName="圆通速递",TargetName="圆通速递",TargetCode="yuantong"},
new LogisticsCompanyRelationship(){ SourceName="圆通快递",TargetName="圆通速递",TargetCode="yuantong"},
new LogisticsCompanyRelationship(){ SourceName="韵达快递",TargetName="韵达快递",TargetCode="yunda"},
new LogisticsCompanyRelationship(){ SourceName="韵达快运",TargetName="韵达快运",TargetCode="yundakuaiyun"},
new LogisticsCompanyRelationship(){ SourceName="中通快递",TargetName="中通快递",TargetCode="zhongtong"},
new LogisticsCompanyRelationship(){ SourceName="中通速递",TargetName="中通快递",TargetCode="zhongtong"},
new LogisticsCompanyRelationship(){ SourceName="中通快运",TargetName="中通快运",TargetCode="zhongtongkuaiyun"},
new LogisticsCompanyRelationship(){ SourceName="极兔速递",TargetName="极兔速递",TargetCode="jtexpress"},
new LogisticsCompanyRelationship(){ SourceName="极兔快递",TargetName="极兔速递",TargetCode="jtexpress"},
new LogisticsCompanyRelationship(){ SourceName="邮政快递包裹",TargetName="邮政快递包裹",TargetCode="youzhengguonei"},
new LogisticsCompanyRelationship(){ SourceName="顺丰速运",TargetName="顺丰速运",TargetCode="shunfeng"},
new LogisticsCompanyRelationship(){ SourceName="顺丰快递",TargetName="顺丰速运",TargetCode="shunfeng"},
new LogisticsCompanyRelationship(){ SourceName="EMS",TargetName="EMS",TargetCode="ems"},
new LogisticsCompanyRelationship(){ SourceName="京东物流",TargetName="京东物流",TargetCode="jd"},
new LogisticsCompanyRelationship(){ SourceName="京东快递",TargetName="京东快运",TargetCode="jingdongkuaiyun"},
new LogisticsCompanyRelationship(){ SourceName="德邦快递",TargetName="德邦快递",TargetCode="debangkuaidi"},
new LogisticsCompanyRelationship(){ SourceName="德邦",TargetName="德邦",TargetCode="debangwuliu"},
new LogisticsCompanyRelationship(){ SourceName="丹鸟",TargetName="丹鸟",TargetCode="danniao"},
new LogisticsCompanyRelationship(){ SourceName="其他-丹鸟KD",TargetName="丹鸟",TargetCode="danniao"},
new LogisticsCompanyRelationship(){ SourceName="百世快递",TargetName="百世快递",TargetCode="huitongkuaidi"},
new LogisticsCompanyRelationship(){ SourceName="百世快运",TargetName="百世快递",TargetCode="huitongkuaidi"},
2 years ago
};
2 years ago
}
2 years ago
public void SyncServiceOrder()
2 years ago
{
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.);
//SyncAfterOrder(shopList.FirstOrDefault(s => s.ShopName == "布莱特玩具专营店"), string.Empty, isAuto: true);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncServiceOrder(shop, string.Empty, isAuto: true),
System.Threading.CancellationToken.None,
TaskCreationOptions.LongRunning,
2 years ago
taskSchedulerManager.SyncServiceOrderTaskScheduler);
2 years ago
}
}
2 years ago
public void SyncServiceOrder(long shopId, string serviceId)
{
var shopList = venderBusiness.GetShopList(shopId);
Task.Factory.StartNew(() => SyncServiceOrder(shopList[0], serviceId, isAuto: true),
System.Threading.CancellationToken.None,
TaskCreationOptions.LongRunning,
taskSchedulerManager.SyncServiceOrderTaskScheduler);
}
2 years ago
private void SyncServiceOrder(ShopResponse shop, long shopId, IList<JToken> jtokenList, string relayAPIHost, string appKey, string appSecret, string token)
2 years ago
{
2 years ago
var serviceIdList = jtokenList.Select(j => j.Value<string>("serviceId")).ToList();
var dbServiceOrderList = fsql.Select<ServiceOrder>().Where(s => s.ShopId == shop.ShopId && serviceIdList.Contains(s.ServiceId)).ToList();
var dbServiceIdList = dbServiceOrderList.Select(s => s.ServiceId).ToList();
var exceptServiceIdList = serviceIdList.Except(dbServiceIdList);
2 years ago
2 years ago
var apiOrderIdList = jtokenList.Where(j => exceptServiceIdList.Contains(j.Value<string>("serviceId"))).Select(j => j.Value<string>("orderId")).ToList();
var dbOrderSkuList = fsql.Select<OrderSku, Order>().InnerJoin((osku, o) => osku.OrderId == o.Id)
2 years ago
.Where((osku, o) => osku.ShopId == shopId && apiOrderIdList.Contains(osku.OrderId) && osku.Price != 0)
2 years ago
.ToList((osku, o) => new
{
Id = osku.Id,
ProductId = osku.ProductId,
SkuId = osku.SkuId,
OrderId = osku.OrderId,
ItemTotal = osku.ItemTotal,
StorageType = o.StorageType
});
2 years ago
List<ServiceOrder> insertServiceOrderList = new List<ServiceOrder>();
List<IUpdate<ServiceOrder>> updateServiceOrderList = new List<IUpdate<ServiceOrder>>();
2 years ago
foreach (var serviceOrderJToken in jtokenList)
{
var serviceId = serviceOrderJToken.Value<string>("serviceId");
var status = serviceOrderJToken.Value<int>("sserviceOrderJToken");
2 years ago
var statusUpdateTime = serviceOrderJToken.Value<DateTime>("updateTime");
2 years ago
var dbServiceOrder = dbServiceOrderList.FirstOrDefault(s => s.ServiceId == serviceId);
if (dbServiceOrder == null)
{
var serviceOrderId = serviceOrderJToken.Value<string>("orderId");
var skuId = serviceOrderJToken.Value<string>("skuId");
var dbOsku = dbOrderSkuList.FirstOrDefault(osku => osku.OrderId == serviceOrderId && osku.SkuId == skuId);
if (dbOsku == null)
continue;
var isNeedSubscribeKuaiDi100 = false;
2 years ago
var isTuiHuoCang = false;
2 years ago
#region 待收货服务单,检查是否需要订阅快递100
if (status == 10005)
{
if (dbOsku.StorageType == Enums.StorageType.)
isNeedSubscribeKuaiDi100 = true;
else
{
try
{
var serviceOrderDetailResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetServiceOrderDetail", new QueryServiceOrderDetailRequest()
{
AppKey = appKey,
AppSecret = appSecret,
AppToken = token,
OrderId = serviceOrderId,
ServiceId = serviceId,
Platform = Enums.Platform.,
VenderId = shop.VenderId
}, GetYunDingRequestHeader(), HttpMethod.Post);
if (serviceOrderDetailResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取服务单详情失败 {serviceOrderDetailResult.Content}");
var serviceOrderDetailResponse = JsonConvert.DeserializeObject<ApiResponse<JToken>>(serviceOrderDetailResult.Content);
if (!serviceOrderDetailResponse.Success)
throw new Exception($"获取服务单详情失败 {serviceOrderDetailResponse.Msg}");
//检查退货城市是否为泉州
isNeedSubscribeKuaiDi100 = serviceOrderDetailResponse.Data["returnWareAddress"].Value<int>("cityCode") == 2812;
2 years ago
isTuiHuoCang = isNeedSubscribeKuaiDi100;
2 years ago
}
catch { }
}
}
#endregion
dbServiceOrder = new ServiceOrder()
{
Id = idGenerator.NewLong(),
ServiceId = serviceId,
OrderId = serviceOrderId,
ShopId = shop.ShopId,
ProductId = dbOsku.ProductId,
SkuItemCount = dbOsku.ItemTotal,
Status = status,
CreateTime = DateTime.Now,
SkuId = skuId,
2 years ago
StatusUpdateTime = statusUpdateTime,
2 years ago
IsSubscribeKuaiDi100 = false,
IsNeedSubscribeKuaiDi100 = isNeedSubscribeKuaiDi100,
2 years ago
ApplyTime = serviceOrderJToken.Value<DateTime>("applyTime"),
2 years ago
};
2 years ago
if (isTuiHuoCang)
dbServiceOrder.ReturnDirection = 0;
2 years ago
insertServiceOrderList.Add(dbServiceOrder);
}
else if (dbServiceOrder.Status != status)
{
var update = fsql.Update<ServiceOrder>(dbServiceOrder.Id).Set(s => s.Status, status)
.Set(s => s.StatusUpdateTime, statusUpdateTime);
updateServiceOrderList.Add(update);
2 years ago
}
}
2 years ago
fsql.Transaction(() =>
{
if (insertServiceOrderList.Count() > 0)
fsql.Insert(insertServiceOrderList).ExecuteAffrows();
if (updateServiceOrderList.Count() > 0)
foreach (var update in updateServiceOrderList)
update.ExecuteAffrows();
});
2 years ago
}
2 years ago
private void SyncServiceOrder(ShopResponse shop, string serviceId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false)
2 years ago
{
/*
:
: 10001
: 10002
: 10012
: 10005
: 10011
: 10004
: 10009
: 10010
:
: 10007
:7060
:7023
线:7090
: 13000
*/
2 years ago
var loggerName = $"新服务单同步-{shop.ShopName}";
2 years ago
try
{
var shopId = long.Parse(shop.ShopId);
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
var serviceStatusList = new List<int>() { 10005, 10011, 10010 };
2 years ago
var request = new QueryServiceOrderRequest()
2 years ago
{
UpdateTimeBegin = startTime ?? DateTime.Now.Date.AddHours(-1),
2 years ago
UpdateTimeEnd = endTime ?? DateTime.Now,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
PageIndex = 1,
PageSize = 50,
Platform = shop.PlatformId,
SaveResponseLog = true,
2 years ago
ServiceId = serviceId,
VenderId = shop.VenderId
};
2 years ago
List<JToken> jtokenList = new List<JToken>();
foreach (var serviceStatus in serviceStatusList)
{
2 years ago
if (string.IsNullOrEmpty(serviceId))
request.ServiceStatus = serviceStatus;
var serviceOrderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetServiceOrderList", request, GetYunDingRequestHeader(), HttpMethod.Post);
if (serviceOrderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取服务单失败 {serviceOrderListApiResult.Content}");
var serviceOrderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(serviceOrderListApiResult.Content);
if (!serviceOrderListResponse.Success)
throw new Exception($"获取服务单失败 {serviceOrderListResponse.Msg}");
2 years ago
if (serviceOrderListResponse.Data != null && serviceOrderListResponse.Data.Count() > 0)
jtokenList.AddRange(serviceOrderListResponse.Data);
2 years ago
if (!string.IsNullOrEmpty(serviceId))
break;
}
2 years ago
2 years ago
SyncServiceOrder(shop, shopId, jtokenList, relayAPIHost, request.AppKey, request.AppSecret, request.AppToken);
2 years ago
}
catch (Exception ex)
{
2 years ago
nLogManager.GetLogger(loggerName).Error(ex, $"SyncServiceOrder ShopName:{shop.ShopName} ShopId:{shop.ShopId}");
2 years ago
}
}
2 years ago
public void SubscribeKuaiDi100()
{
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.);
foreach (var shop in shopList)
{
2 years ago
Task.Factory.StartNew(() => SubscribeKuaiDi100(shop),
2 years ago
System.Threading.CancellationToken.None,
TaskCreationOptions.LongRunning,
taskSchedulerManager.SyncServiceOrderTaskScheduler);
}
}
2 years ago
public void SubscribeKuaiDi100(long shopId)
{
var shop = venderBusiness.GetShopList(shopId).FirstOrDefault();
2 years ago
Task.Factory.StartNew(() => SubscribeKuaiDi100(shop),
2 years ago
System.Threading.CancellationToken.None,
TaskCreationOptions.LongRunning,
taskSchedulerManager.SyncServiceOrderTaskScheduler);
}
2 years ago
private void SubscribeKuaiDi100(ShopResponse shop)
{
2 years ago
var loggerName = $"订阅快递100-{shop.ShopName}";
try
2 years ago
{
2 years ago
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
2 years ago
var serviceOrderList = fsql.Select<ServiceOrder>().Where(s => s.ShopId == shop.Id &&
2 years ago
s.IsNeedSubscribeKuaiDi100 == true &&
s.IsSubscribeKuaiDi100 == false)
2 years ago
.OrderByDescending(s => s.StatusUpdateTime)
2 years ago
.Page(1, 50)
2 years ago
.ToList();
2 years ago
List<IUpdate<ServiceOrder>> updateSerivceOrderList = new List<IUpdate<ServiceOrder>>();
2 years ago
List<ExpressOrder> insertExpressOrderList = new List<ExpressOrder>();
2 years ago
foreach (var serviceOrder in serviceOrderList)
2 years ago
{
2 years ago
bool isUpdateDelivery = false, isUpdateSubscribe = false;
2 years ago
if (string.IsNullOrEmpty(serviceOrder.WayBillNo) || string.IsNullOrEmpty(serviceOrder.ExpressName))
2 years ago
{
2 years ago
2 years ago
try
{
#region 查询服务单运单详情
var serviceOrderDeliveryResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetServiceOrderDeliveryDetail", new QueryServiceOrderDetailRequest()
{
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
OrderId = serviceOrder.OrderId,
ServiceId = serviceOrder.ServiceId,
Platform = Enums.Platform.,
VenderId = shop.VenderId
}, GetYunDingRequestHeader(), HttpMethod.Post);
if (serviceOrderDeliveryResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"获取服务单运单详情失败 {serviceOrderDeliveryResult.Content}");
var serviceOrderDeliveryResponse = JsonConvert.DeserializeObject<ApiResponse<JToken>>(serviceOrderDeliveryResult.Content);
if (!serviceOrderDeliveryResponse.Success)
throw new Exception($"获取服务单运单详情失败 {serviceOrderDeliveryResponse.Msg}");
if (serviceOrderDeliveryResponse.Data != null)
{
2 years ago
serviceOrder.WayBillNo = serviceOrderDeliveryResponse.Data.Value<string>("expressCode");
serviceOrder.ExpressName = serviceOrderDeliveryResponse.Data.Value<string>("expressCompany");
2 years ago
2 years ago
isUpdateDelivery = !string.IsNullOrEmpty(serviceOrder.WayBillNo) && !string.IsNullOrEmpty(serviceOrder.ExpressName);
2 years ago
}
#endregion
}
catch (Exception ex)
{
nLogManager.GetLogger(loggerName).Error(ex, $"SubscribeKuaiDi100 ShopName:{shop.ShopName} ShopId:{shop.ShopId} ServiceId:{serviceOrder.ServiceId}");
}
}
2 years ago
if (!string.IsNullOrEmpty(serviceOrder.WayBillNo) && !string.IsNullOrEmpty(serviceOrder.ExpressName))
2 years ago
{
#region 订阅快递100
2 years ago
try
{
2 years ago
var kuaidi100CompanyCode = ConvertToKuaiDi100CompanyCode(serviceOrder.ExpressName);
2 years ago
var paramStr = JsonConvert.SerializeObject(new
2 years ago
{
2 years ago
company = kuaidi100CompanyCode,
number = serviceOrder.WayBillNo,
key = "SdcRPzxo8802",
parameters = new
2 years ago
{
2 years ago
callbackurl = "https://bbwy.qiyue666.com/api/ServiceOrderSync/ReceiveKuaiDi100Push",
salt = Guid.NewGuid(),
resultv2 = "4"
2 years ago
}
2 years ago
});
var subscribeResult = restApiService.SendRequest("https://poll.kuaidi100.com", "poll", $"schema=json&param={paramStr}", null, HttpMethod.Post, RestApiService.ContentType_Form);
2 years ago
if (subscribeResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"订阅快递100失败 {subscribeResult.Content}");
var subscribeResponse = JsonConvert.DeserializeObject<KuaiDi100Response>(subscribeResult.Content);
if (!subscribeResponse.result)
throw new Exception($"订阅快递100失败 {subscribeResponse.message}");
2 years ago
isUpdateSubscribe = true;
}
catch (Exception ex)
{
nLogManager.GetLogger(loggerName).Error(ex, $"SubscribeKuaiDi100 ShopName:{shop.ShopName} ShopId:{shop.ShopId} ServiceId:{serviceOrder.ServiceId}");
}
2 years ago
#endregion
}
2 years ago
if (isUpdateSubscribe || isUpdateDelivery)
2 years ago
{
2 years ago
var update = fsql.Update<ServiceOrder>(serviceOrder.Id)
.SetIf(isUpdateDelivery, e => e.WayBillNo, serviceOrder.WayBillNo)
.SetIf(isUpdateDelivery, e => e.ExpressName, serviceOrder.ExpressName)
.SetIf(isUpdateSubscribe, s => s.IsSubscribeKuaiDi100, true);
2 years ago
updateSerivceOrderList.Add(update);
2 years ago
if (isUpdateDelivery)
{
insertExpressOrderList.Add(new ExpressOrder()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
ExpressName = serviceOrder.ExpressName,
WayBillNo = serviceOrder.WayBillNo,
OrderId = serviceOrder.OrderId,
PackageType = 1,
UpdateTime = DateTime.Now
});
}
2 years ago
}
}
2 years ago
2 years ago
fsql.Transaction(() =>
2 years ago
{
2 years ago
if (insertExpressOrderList.Count() > 0)
fsql.Insert(insertExpressOrderList).ExecuteAffrows();
2 years ago
if (updateSerivceOrderList.Count() > 0)
2 years ago
foreach (var update in updateSerivceOrderList)
update.ExecuteAffrows();
2 years ago
});
2 years ago
}
catch (Exception ex)
{
nLogManager.GetLogger(loggerName).Error(ex, $"SubscribeKuaiDi100 ShopName:{shop.ShopName} ShopId:{shop.ShopId}");
2 years ago
}
}
2 years ago
private string ConvertToKuaiDi100CompanyCode(string sourceExpressName)
{
var result = jd_kd100_logisticsCompanyDictionary.FirstOrDefault(l => l.SourceName == sourceExpressName);
if (result == null)
throw new Exception($"匹配快递100公司失败,原快递名称 {sourceExpressName}");
return result.TargetCode;
}
2 years ago
public void ReceiveKuaiDi100Push(string param)
{
JObject jobject = JObject.Parse(param);
var waybillNo = jobject["lastResult"].Value<string>("nu");
var state = jobject["lastResult"].Value<int>("state");
if (!kuaiDi100PushStateList.Contains(state))
return;
var serviceOrderList = fsql.Select<ServiceOrder>().Where(s => s.WayBillNo == waybillNo).ToList();
if (serviceOrderList.Count() == 0)
throw new Exception($"快递单号{waybillNo} 未找到对应的服务单");
var expressOrder = fsql.Select<ExpressOrder>().Where(e => e.WayBillNo == waybillNo).ToOne();
if (expressOrder == null)
throw new Exception($"快递单号{waybillNo} 未找到对应的快递单");
if (expressOrder.TransportStatus == 1) //已入库
return;
IUpdate<ExpressOrder> updateExpressOrder = null;
List<IUpdate<ServiceOrder>> updateServiceOrderList = new List<IUpdate<ServiceOrder>>();
/*
0, //在途
1, //揽收
3, //签收
5, //派件
*/
var isUpdate = false;
var newStatus = 0;
DateTime? signTime = null;
if (state == 0 || state == 1)
{
//在途 //揽收
if (expressOrder.TransportStatus != 3)
{
isUpdate = true;
newStatus = 3;
}
}
else if (state == 3)
{
if (expressOrder.TransportStatus != 0)
{
isUpdate = true;
newStatus = 0;
var data = jobject["lastResult"]["data"].Children().FirstOrDefault(d => d.Value<int>("statusCode") == 3);
if (data != null)
signTime = DateTime.Parse(data.Value<string>("ftime"));
}
}
else if (state == 5)
{
if (expressOrder.TransportStatus != 2)
{
isUpdate = true;
newStatus = 2;
}
}
if (isUpdate)
{
fsql.Transaction(() =>
{
fsql.Update<ExpressOrder>(expressOrder.Id).Set(e => e.TransportStatus, newStatus)
.SetIf(state == 3, e => e.SignTime, signTime)
.ExecuteAffrows(); //签收
foreach (var serviceOrder in serviceOrderList)
{
if (serviceOrder.TransportDetails == 1)
continue;
fsql.Update<ServiceOrder>(serviceOrder.Id).Set(s => s.TransportDetails, newStatus)
.ExecuteAffrows();
}
});
}
}
2 years ago
}
}