using BBWY.Client.Extensions; using BBWYB.Client.Extensions; using BBWYB.Client.Models; using BBWYB.Common.Http; using BBWYB.Common.Models; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; namespace BBWYB.Client.APIServices { public class PurchaseProductAPIService : IDenpendency { private RestApiService restApiService; private IMemoryCache memoryCache; private string oneBoundKey = "t5060712539"; private string oneBoundSecret = "20211103"; //private string qtAppId = "BBWY2023022001"; //private string qtAppSecret = "908e131365d5448ca651ba20ed7ddefe"; private TimeSpan purchaseProductCacheTimeSpan; //private TimeSpan _1688SessionIdTimeSpan; //private ConcurrentDictionary purchaseSchemeProductSkus)> productChaches; private IDictionary _1688ProductDetailRequestHeader; public PurchaseProductAPIService(RestApiService restApiService, IMemoryCache memoryCache) { this.restApiService = restApiService; this.memoryCache = memoryCache; _1688ProductDetailRequestHeader = new Dictionary() { { "Host","detail.1688.com"}, { "User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"}, { "Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, { "Accept-Encoding","gzip, deflate, br"}, { "Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"} }; purchaseProductCacheTimeSpan = TimeSpan.FromDays(1); } public (Purchaser purchaser, IList purchaseSchemeProductSkus)? GetProductInfo(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode, PurchaseProductAPIMode apiMode) { if (memoryCache.TryGetValue<(Purchaser, IList)>($"{purchaseProductId}_{priceMode}", out var tuple)) return tuple.Copy(); (Purchaser purchaser, IList purchaseSchemeProductSkus)? data = null; if (apiMode == PurchaseProductAPIMode.Spider) { data = LoadFromSpider(platform, productId, skuId, purchaseProductId, priceMode); if (data == null) data = LoadFromOneBound(platform, productId, skuId, purchaseProductId, priceMode); } else if (apiMode == PurchaseProductAPIMode.OneBound) { data = LoadFromOneBound(platform, productId, skuId, purchaseProductId, priceMode); if (data == null) data = LoadFromSpider(platform, productId, skuId, purchaseProductId, priceMode); } if (data != null) { try { memoryCache.Set<(Purchaser, IList)>($"{purchaseProductId}_{priceMode}", data.Value, purchaseProductCacheTimeSpan); } catch { } } return data?.Copy(); } private (Purchaser purchaser, IList purchaseSchemeProductSkus)? LoadFromOneBound(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) { try { string platformStr = string.Empty; if (platform == Platform.阿里巴巴) platformStr = "1688"; if (string.IsNullOrEmpty(platformStr)) return null; var result = restApiService.SendRequest("https://api-gw.onebound.cn/", $"{platformStr}/item_get", $"key={oneBoundKey}&secret={oneBoundSecret}&num_iid={purchaseProductId}&lang=zh-CN&cache=no&agent={(priceMode == PurchaseOrderMode.批发 ? 0 : 1)}", null, HttpMethod.Get, paramPosition: ParamPosition.Query, enableRandomTimeStamp: true); if (result.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception($"{result.StatusCode} {result.Content}"); var jobject = JObject.Parse(result.Content); var isOK = jobject.Value("error_code") == "0000"; if (isOK) { var skuJArray = (JArray)jobject["item"]["skus"]["sku"]; if (skuJArray.Count == 0) { //errorMsg = $"商品{purchaseSchemeProduct.PurchaseProductId}缺少sku信息"; return null; } var list = skuJArray.Select(j => new PurchaseSchemeProductSku() { ProductId = productId, SkuId = skuId, PurchaseProductId = purchaseProductId, Price = j.Value("price"), PurchaseSkuId = j.Value("sku_id"), PurchaseSkuSpecId = j.Value("spec_id"), Title = j.Value("properties_name"), Logo = GetOneBoundSkuLogo(j, (JArray)jobject["item"]["prop_imgs"]["prop_img"]) }).ToList(); var purchaserId = jobject["item"]["seller_info"].Value("user_num_id"); var purchaserName = jobject["item"]["seller_info"].Value("title"); if (string.IsNullOrEmpty(purchaserName)) purchaserName = jobject["item"]["seller_info"].Value("shop_name"); var purchaserLocation = jobject["item"].Value("location"); return (new Purchaser() { Id = purchaserId, Name = purchaserName, Location = purchaserLocation }, list); } } catch { } { return null; } } private string GetOneBoundSkuLogo(JToken skuJToken, JArray prop_img) { if (!prop_img.HasValues) return "pack://application:,,,/Resources/Images/defaultItem.png"; var properties = skuJToken.Value("properties").Split(';', StringSplitOptions.RemoveEmptyEntries); foreach (var p in properties) { var imgJToken = prop_img.FirstOrDefault(g => g.Value("properties") == p); if (imgJToken != null) return imgJToken.Value("url"); } return "pack://application:,,,/Resources/Images/defaultItem.png"; } private (Purchaser purchaser, IList purchaseSchemeProductSkus)? LoadFromSpider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) { switch (platform) { case Platform.阿里巴巴: return LoadFrom1688Spider(platform, productId, skuId, purchaseProductId, priceMode); //case Platform.拳探: // return LoadFromQTSpider(platform, productId, skuId, purchaseProductId, priceMode); } return null; } private (Purchaser purchaser, IList purchaseSchemeProductSkus)? LoadFrom1688Spider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) { //https://detail.1688.com/offer/672221374773.html?clickid=65f3772cd5d16f190ce4991414607&sessionid=3de47a0c26dcbfde4692064bd55861&sk=order //globalData/tempModel/sellerUserId //globalData/tempModel/companyName //data/1081181309101/data/location //data/1081181309582/data/pirceModel/[currentPrices]/[0]price try { var _1688pageResult = restApiService.SendRequest("https://detail.1688.com", $"offer/{purchaseProductId}.html", $"clickid={Guid.NewGuid().ToString().Md5Encrypt()}&sessionid={Guid.NewGuid().ToString().Md5Encrypt()}&sk={(priceMode == PurchaseOrderMode.批发 ? "order" : "consign")}", _1688ProductDetailRequestHeader, HttpMethod.Get, httpClientName: "gzip"); if (_1688pageResult.StatusCode != System.Net.HttpStatusCode.OK) return null; var match = Regex.Match(_1688pageResult.Content, @"(window\.__INIT_DATA=)(.*)(\r*\n*\s*)"); if (!match.Success) return null; var jsonStr = match.Groups[2].Value; var jobject = JObject.Parse(jsonStr); //16347413030323 var purchaser = new Purchaser() { Id = jobject["globalData"]["tempModel"]["sellerUserId"].ToString(), Name = jobject["globalData"]["tempModel"]["companyName"].ToString(), Location = jobject["data"]["1081181309101"] != null ? jobject["data"]["1081181309101"]["data"]["location"].ToString() : jobject["data"]["16347413030323"]["data"]["location"].ToString() }; var colorsProperty = jobject["globalData"]["skuModel"]["skuProps"].FirstOrDefault(j => j.Value("fid") == 3216 || j.Value("fid") == 1627207 || j.Value("fid") == 1234 || j.Value("fid") == 3151)["value"] .Children() .Select(j => new { name = j.Value("name"), imageUrl = j.Value("imageUrl") }).ToList(); var firstPrice = jobject["data"]["1081181309582"] != null ? jobject["data"]["1081181309582"]["data"]["priceModel"]["currentPrices"][0].Value("price") : jobject["data"]["16347413030316"]["data"]["priceModel"]["currentPrices"][0].Value("price"); var purchaseSchemeProductSkus = new List(); foreach (var jsku in jobject["globalData"]["skuModel"]["skuInfoMap"].Children()) { var jskuProperty = jsku as JProperty; var name = jskuProperty.Name; var matchName = name.Contains(">") ? name.Substring(0, name.IndexOf(">")) : name; var value = jskuProperty.Value; var skuPrice = value.Value("price"); purchaseSchemeProductSkus.Add(new PurchaseSchemeProductSku() { ProductId = productId, SkuId = skuId, PurchaseProductId = purchaseProductId, Price = skuPrice == 0M ? firstPrice : skuPrice, Title = name, PurchaseSkuId = value.Value("skuId"), PurchaseSkuSpecId = value.Value("specId"), Logo = colorsProperty.FirstOrDefault(c => c.name == matchName)?.imageUrl ?? "pack://application:,,,/Resources/Images/defaultItem.png" }); } return (purchaser, purchaseSchemeProductSkus); } catch { return null; } } //private (Purchaser purchaser, IList purchaseSchemeProductSkus)? LoadFromQTSpider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) //{ // try // { // var response = quanTanProductClient.GetProductInfo(purchaseProductId, qtAppId, qtAppSecret); // if (response.Status != 200) // return null; // return (new Purchaser() // { // Id = response.Data.Supplier.VenderId, // Name = response.Data.Supplier.VerdenName, // Location = response.Data.Supplier.Location // }, response.Data.ProductSku.Select(qtsku => new PurchaseSchemeProductSku() // { // ProductId = productId, // SkuId = skuId, // PurchaseProductId = purchaseProductId, // Price = qtsku.Price, // Title = qtsku.Title, // PurchaseSkuId = qtsku.SkuId, // PurchaseSkuSpecId = string.Empty, // Logo = qtsku.Logo // }).ToList()); // } // catch // { // return null; // } //} } }