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

595 lines
26 KiB
C#

using Aspose.Pdf.Operators;
using NetLibrary.Log;
using NetLibrary.OnlineTrade;
using NPOI.HSSF.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using TradeManage;
namespace TradeManageNew
{
public class Shein
{
public string ShopName { get; set; }
public string AppKey { get; set; }
public string AppSecret { get; set; }
public DateTime StartTime { get; set; }
JavaScriptSerializer JsonConvert = null;
public Shein()
{
JsonConvert = new JavaScriptSerializer();
}
public List<OrderModel> GetOrders(out string errorMessage)
{
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤1:APPkey:" + AppKey + " APPSecret:" + AppSecret);
var orderModels = new List<OrderModel>();
try
{
if (string.IsNullOrEmpty(AppKey) || string.IsNullOrEmpty(AppSecret))
{
errorMessage = "店铺未授权";
return null;
}
int pageIndex = 1;
int pageCount = 1;
while (pageIndex<=pageCount)
{
var orders = GetSheinOrder(pageIndex, out pageCount, out errorMessage);
if (!string.IsNullOrEmpty(errorMessage))
throw new Exception(errorMessage);
if (orders != null)
{
var orderIds = orders.Select(r => r.orderNo).ToList();
var orderDetails = GetSheinOrderDetail(orderIds);
var orderAddrs = GetSheinOrderBuyerAddress(orderIds);
foreach (var order in orders)
{
var detail = orderDetails == null ? null : orderDetails.Where(r => r.orderNo == order.orderNo).FirstOrDefault();
var addr = orderAddrs == null ? null : orderAddrs.Where(r => r.orderNo == order.orderNo).FirstOrDefault();
if (detail != null)
{
var rmodel=ToOrderModel(detail, addr);
if(rmodel!=null)
orderModels.Add(rmodel);
}
}
}
pageIndex++;
}
errorMessage = "";
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
return orderModels;
}
/// <summary>
/// 获取订单列表
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageCount"></param>
/// <param name="errorMessage"></param>
/// <returns></returns>
public List<SheinOrderListModel> GetSheinOrder(int pageIndex,out int pageCount,out string errorMessage )
{
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤2 ");
errorMessage = "";
var rmodel =new List<SheinOrderListModel>();
try
{
string prodUrl = "https://openapi.sheincorp.com";//正式地址域名
string API_PATH = "/open-api/order/order-list"; //接口api地址
//var timeStamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var timeStamp = GetTimeStamp();
errorMessage += "1:"+timeStamp.ToString();
var signString = AppKey + "&" + timeStamp + "&" + API_PATH;
string randomKey = Guid.NewGuid().ToString().Substring(0, 5);
string randomSecretKey = AppSecret + randomKey;
string hashValue = ComputeHMAC(signString, randomSecretKey);
string base64Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(hashValue));
string signature = randomKey + base64Value;
string url = prodUrl + API_PATH;
errorMessage += " 2:" + signature;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤3 ");
using (HttpClient client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
var requestData = new { queryType = 1, startTime = StartTime.Date.ToString("yyyy-MM-dd HH:mm:ss"), endTime = StartTime.AddDays(2).Date.ToString("yyyy-MM-dd HH:mm:ss"), page = pageIndex, pageSize = 30 };
var json = JsonConvert.Serialize(requestData);
errorMessage += " 3:" + json;
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤4 ");
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Headers.Add("x-lt-openKeyId", AppKey);
request.Headers.Add("x-lt-timestamp", timeStamp.ToString());
request.Headers.Add("x-lt-signature", signature);
request.Version = HttpVersion.Version11;
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤4.1 ");
var response = client.SendAsync(request);
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤4.2 ");
//errorMessage += " 4:" + response.Result.StatusCode.ToString();
//errorMessage += " 5:" + response.Result.ToString();
//errorMessage += " 6:" + response.Result.Content.ToString();
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤5 ");
string responseContent = response.Result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
//string responseContent = await response.Content.ReadAsStringAsync();
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤6 ");
//errorMessage += " 7:" + responseContent;
var obj = JsonConvert.Deserialize<SheinOrderListApiModel>(responseContent);
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤7 ");
if (obj!=null && obj.code == "0" && obj.info!=null)
{
pageCount = (obj.info.count % 30 == 0) ? (obj.info.count / 30) : (obj.info.count / 30 + 1);
errorMessage = "";
rmodel = obj.info.orderList;
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤8 ");
}
else
{
errorMessage += "同步Shein订单出错:"+ responseContent;
rmodel = null;
pageCount = 0;
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤9 ");
}
}
}
catch(AggregateException ex)
{
if (ex.InnerExceptions.Count > 0)
{
var innerException = ex.InnerExceptions[0];
if (innerException is HttpRequestException)
{
Console.WriteLine("请求发生错误: " + innerException.Message);
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤10 请求发生错误: " + innerException.Message);
if (innerException.InnerException != null)
{
Console.WriteLine("内部异常: " + innerException.InnerException.Message);
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤10.1 内部错误: " + innerException.InnerException.Message);
}
}
else
{
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤10.2 其它内部异常: " + innerException.GetType().ToString());
}
}
//ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤10 请求发生错误: " + ex.Message);
//if (ex.InnerException != null)
//{
// ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤10.1 内部错误: " + ex.InnerException.Message);
//}
//errorMessage += " 同步Shein订单出错:" + ex.Message;
pageCount = 0;
rmodel = null;
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
}
return rmodel;
}
/// <summary>
/// 获取订单详情信息
/// </summary>
/// <param name="orderIds"></param>
/// <returns></returns>
public List<SheinOrderDetailApiInfoModel> GetSheinOrderDetail(List<string> orderIds)
{
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤11 ");
var rmodel=new List<SheinOrderDetailApiInfoModel>();
try
{
string prodUrl = "https://openapi.sheincorp.com";//正式地址域名
string API_PATH = "/open-api/order/order-detail"; //接口api地址
var timeStamp = GetTimeStamp();
var signString = AppKey + "&" + timeStamp + "&" + API_PATH;
string randomKey = Guid.NewGuid().ToString().Substring(0, 5);
string randomSecretKey = AppSecret + randomKey;
string hashValue = ComputeHMAC(signString, randomSecretKey);
string base64Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(hashValue));
string signature = randomKey + base64Value;
string url = prodUrl + API_PATH;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
using (HttpClient client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
//var requestData = new { orderNoList = new List<string> { "GSUNAF060002WGA", "GSUNAF42N001BD8", "GSUNAF56N00176A" } };
var requestData = new { orderNoList = orderIds };
var json = JsonConvert.Serialize(requestData);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Headers.Add("x-lt-openKeyId", AppKey);
request.Headers.Add("x-lt-timestamp", timeStamp.ToString());
request.Headers.Add("x-lt-signature", signature);
var response = client.SendAsync(request);
string responseContent = response.Result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var detailObj = JsonConvert.Deserialize<SheinOrderDetailApiModel>(responseContent);
rmodel = detailObj.info;
}
}
catch(Exception ex)
{
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, "获取订单详情出错:" + ex.Message);
rmodel = null;
}
return rmodel;
}
/// <summary>
/// 获取订单收件人地址信息
/// </summary>
/// <param name="orderIds"></param>
/// <returns></returns>
public List<SheinOrderExportAddressInfoReceiveMsg> GetSheinOrderBuyerAddress(List<string> orderIds)
{
ErrorFollow.TraceWrite("自动导入Shein订单", "店铺名称:" + ShopName, "步骤12 ");
var rmodel = new List<SheinOrderExportAddressInfoReceiveMsg>();
string prodUrl = "https://openapi.sheincorp.com";//正式地址域名
string API_PATH = "/open-api/order/export-address"; //接口api地址
foreach (var orderId in orderIds)
{
try
{
var timeStamp = GetTimeStamp();
var signString = AppKey + "&" + timeStamp + "&" + API_PATH;
string randomKey = Guid.NewGuid().ToString().Substring(0, 5);
string randomSecretKey = AppSecret + randomKey;
string hashValue = ComputeHMAC(signString, randomSecretKey);
string base64Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(hashValue));
string signature = randomKey + base64Value;
string url = prodUrl + API_PATH;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
using (HttpClient client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
var requestData = new { orderNo = orderId, handleType = 1 };
var json = JsonConvert.Serialize(requestData);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Headers.Add("x-lt-openKeyId", AppKey);
request.Headers.Add("x-lt-timestamp", timeStamp.ToString());
request.Headers.Add("x-lt-signature", signature);
var response = client.SendAsync(request);
string responseContent = response.Result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var obj = JsonConvert.Deserialize<SheinOrderExportAddressApiModel>(responseContent);
if(obj!=null && obj.info!=null && obj.info.receiveMsgList != null)
{
rmodel.Add(obj.info.receiveMsgList.FirstOrDefault());
}
}
}
catch (Exception ex)
{
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, "获取订单地址出错:" + ex.Message);
continue;
}
}
return rmodel;
}
public OrderModel ToOrderModel(SheinOrderDetailApiInfoModel detail, SheinOrderExportAddressInfoReceiveMsg addr )
{
OrderModel rmodel = new OrderModel();
try
{
rmodel.OrderCode = detail.orderNo;
rmodel.PlatOrderCode = detail.orderNo;
rmodel.TotalPrice = detail.productTotalPrice - detail.storeDiscountTotalPrice - detail.promotionDiscountTotalPrice - detail.totalCommission;
rmodel.MoneyCode = detail.orderCurrency;
rmodel.OrderDate = detail.orderTime;
rmodel.OrderState = 1;
if (addr != null)
{
rmodel.BuyerName = addr.firstName + " " + (string.IsNullOrEmpty(addr.middleName) ? "" : addr.middleName + "") + addr.lastName;
rmodel.BuyerCountry=addr.country;
rmodel.BuyerAddr=addr.address;
rmodel.BuyerPhone=addr.phone;
rmodel.BuyerZip = addr.postCode;
//rmodel.BuyerProvince=addr.province;
var proviceCode = DataNew.GetProvinceCode(addr.province);
rmodel.BuyerProvince = string.IsNullOrEmpty(proviceCode) ? addr.province : proviceCode;
rmodel.BuyerCity=addr.city;
rmodel.BuyerArea = addr.district;
}
if (detail.paymentTime != null)
rmodel.PayDate = detail.paymentTime;
else
rmodel.PayDate = rmodel.OrderDate;
rmodel.OutOrderDate= DateTime.Now.AddDays(7);
if (rmodel.OrderDate != null && rmodel.OrderDate.Value <= Convert.ToDateTime("1753-01-01"))
{
rmodel.OrderDate = DateTime.Now;
}
if (rmodel.PayDate != null && rmodel.PayDate.Value <= Convert.ToDateTime("1753-01-01"))
{
rmodel.PayDate = DateTime.Now;
}
if (rmodel.OutOrderDate != null && rmodel.OutOrderDate.Value <= Convert.ToDateTime("1753-01-01"))
{
rmodel.OutOrderDate = DateTime.Now.AddDays(7);
}
if (detail.packageWaybillList != null && detail.packageWaybillList.Count>0)
rmodel.PostInfo = detail.packageWaybillList[0].carrier;
rmodel.ListModel = new List<OrderDetailModel>();
if (detail.orderGoodsInfoList != null && detail.orderGoodsInfoList.Count>0)
{
foreach (var item2 in detail.orderGoodsInfoList)
{
OrderDetailModel model2 = new OrderDetailModel();
//model2.TypeDesc = item2.newGoodsStatus.ToString();
model2.OrderItemId = item2.goodsId.ToString();
model2.GoodsNum = 1;
model2.GoodsName = item2.goodsTitle;
model2.GoodsSKU = item2.sellerSku;
rmodel.ListModel.Add(model2);
}
}
}
catch (Exception ex)
{
rmodel = null;
}
return rmodel;
}
public string ComputeHMAC(string message, string secretKey)
{
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)))
{
byte[] hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return BitConverter.ToString(hashValue).Replace("-", "").ToLower();
}
}
/// <summary>
/// 获取当前时间十三位的时间戳
/// </summary>
/// <returns></returns>
public long GetTimeStamp()
{
DateTimeOffset currentTime = DateTimeOffset.UtcNow;
long unixTimestamp = (long)(currentTime - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalMilliseconds;
return unixTimestamp;
}
}
public class SheinOrderListApiModel
{
public string code { get; set; }
public string msg { get; set; }
public SheinOrderListApiInfoModel info { get; set; }
}
public class SheinOrderListApiInfoModel
{
public int count { get; set; }
public List<SheinOrderListModel> orderList { get; set; }
}
public class SheinOrderListModel
{
public string orderNo { get; set; }
public string orderStatus { get; set; }
public DateTime? orderCreateTime { get; set; }
public DateTime? orderUpdateTime { get; set; }
}
public class SheinOrderDetailApiModel
{
public string code { get; set; }
public string msg { get; set; }
public List<SheinOrderDetailApiInfoModel> info { get; set; }
}
public class SheinOrderDetailApiInfoModel
{
public string orderNo { get; set; }
public List<int> unProcessReason { get; set; }
public int? isOverLimitOrder { get; set; }
public int? orderType { get; set; }
public string performanceType { get; set; }
public int? orderStatus { get; set; }
public int? isCod { get; set; }
public int? orderTag { get; set; }
public int? deliveryType { get; set; }
public int? printOrderStatus { get; set; }
public int? invoiceStatus { get; set; }
public decimal? settleActuallyPrice { get; set; }
public List<SheinOrderDetailGoodsInfoModel> orderGoodsInfoList { get; set; }
public List<SheinOrderDetailPackageWaybillList> packageWaybillList { get; set; }
public List<SheinOrderDetailPackageInvoiceProblems> packageInvoiceProblems { get; set; }
public string orderCurrency { get; set; }
public decimal? productTotalPrice { get; set; }
public decimal? storeDiscountTotalPrice { get; set; }
public decimal? promotionDiscountTotalPrice { get; set; }
public decimal? totalCommission { get; set; }
public decimal? totalServiceCharge { get; set; }
public decimal? totalPerformanceServiceCharge { get; set; }
public decimal? estimatedGrossIncome { get; set; }
public decimal? totalSaleTax { get; set; }
public DateTime? orderAllocateTime { get; set; }
public DateTime? requestDeliveryTime { get; set; }
public DateTime? printingTime { get; set; }
public DateTime? scheduleDeliveryTime { get; set; }
public DateTime? pickUpTime { get; set; }
public DateTime? orderReceiptTime { get; set; }
public DateTime? orderReturnTime { get; set; }
public DateTime? orderMsgUpdateTime { get; set; }
public DateTime? orderTime { get; set; }
public DateTime? paymentTime { get; set; }
public DateTime? sellerDeliveryTime { get; set; }
public DateTime? warehouseDeliveryTime { get; set; }
public DateTime? orderRejectionTime { get; set; }
public DateTime? orderReportedLossTime { get; set; }
public string billNo { get; set; }
public int? salesArea { get; set; }
public int? stockMode { get; set; }
public string salesSite { get; set; }
public long? storeCode { get; set; }
public string expectedCollectTime { get; set; }
}
public class SheinOrderDetailGoodsInfoModel
{
public long? goodsId { get; set; }
public string skuCode { get; set; }
public string skc { get; set; }
public string goodsSn { get; set; }
public string sellerSku { get; set; }
public int? goodsStatus { get; set; }
public int? newGoodsStatus { get; set; }
public List<SheinOrderDetailSKUAttribute> skuAttribute { get; set; }
public string goodsTitle { get; set; }
public string spuPicURL { get; set; }
public decimal? goodsWeight { get; set; }
public int? storageTag { get; set; }
public int? performanceTag { get; set; }
public long? goodsExchangeTag { get; set; }
public long? beExchangeEntityId { get; set; }
public string orderCurrency { get; set; }
public decimal? sellerCurrencyPrice { get; set; }
public decimal? orderCurrencyStoreCouponPrice { get; set; }
public decimal? orderCurrencyPromotionPrice { get; set; }
public decimal? commission { get; set; }
public decimal? commissionRate { get; set; }
public decimal? serviceCharge { get; set; }
public decimal? performanceServiceCharge { get; set; }
public decimal? estimatedIncome { get; set; }
public string spuName { get; set; }
public decimal? saleTax { get; set; }
public string warehouseCode { get; set; }
public string warehouseName { get; set; }
public decimal? sellerCurrencyDiscountPrice { get; set; }
public string unpackingGroupNo { get; set; }
}
public class SheinOrderDetailSKUAttribute
{
public string attrValueId { get; set; }
public string attrName { get; set; }
public string language { get; set; }
}
public class SheinOrderDetailPackageWaybillList
{
public string packageNo { get; set; }
public string waybillNo { get; set; }
public string carrier { get; set; }
public string carrierCode { get; set; }
public List<SheinOrderDetailProductInventoryList> productInventoryList { get; set; }
public string packageLabel { get; set; }
public string sortingCode { get; set; }
public string expressSortingCode { get; set; }
public Int64? isCutOffSeller { get; set; }
}
public class SheinOrderDetailProductInventoryList
{
public string productId { get; set; }
}
public class SheinOrderDetailPackageInvoiceProblems
{
public string problemCode { get; set; }
public string problemDescEnglish { get; set; }
public string problemField { get; set; }
public string proposalEnglish { get; set; }
public string packageNo { get; set; }
}
public class SheinOrderExportAddressApiModel
{
public string code { get; set; }
public string msg { get; set; }
public SheinOrderExportAddressApiInfoModel info { get; set; }
}
public class SheinOrderExportAddressApiInfoModel
{
public List<SheinOrderExportAddressInfoReceiveMsg> receiveMsgList { get; set; }
}
public class SheinOrderExportAddressInfoReceiveMsg
{
public string orderNo { get; set; }
public string lastName { get; set; }
public string middleName { get; set; }
public string firstName { get; set; }
public string country { get; set; }
public string province { get; set; }
public string city { get; set; }
public string district { get; set; }
public string street { get; set; }
public string address { get; set; }
public string addressExt { get; set; }
public string phone { get; set; }
public string postCode { get; set; }
public string taxNo { get; set; }
}
}