From e2ad48981f5c19c7e47cd51573a5badfcd684200 Mon Sep 17 00:00:00 2001 From: shanj <18996038927@163.com> Date: Sun, 4 Sep 2022 05:43:09 +0800 Subject: [PATCH] 1 --- .../APIServices/PurchaseProductAPIService.cs | 168 ++++++++++++++++++ BBWY.Client/Extensions/EncryptionExtension.cs | 85 +++++++++ BBWY.Client/Models/Enums.cs | 9 + .../Ware/BindingPurchaseProductViewModel.cs | 6 +- 4 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 BBWY.Client/APIServices/PurchaseProductAPIService.cs create mode 100644 BBWY.Client/Extensions/EncryptionExtension.cs diff --git a/BBWY.Client/APIServices/PurchaseProductAPIService.cs b/BBWY.Client/APIServices/PurchaseProductAPIService.cs new file mode 100644 index 00000000..1f0507dd --- /dev/null +++ b/BBWY.Client/APIServices/PurchaseProductAPIService.cs @@ -0,0 +1,168 @@ +using BBWY.Client.Extensions; +using BBWY.Client.Models; +using BBWY.Common.Http; +using BBWY.Common.Models; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Text.RegularExpressions; + +namespace BBWY.Client.APIServices +{ + public class PurchaseProductAPIService : IDenpendency + { + private RestApiService restApiService; + private string oneBoundKey = "t5060712539"; + private string oneBoundSecret = "20211103"; + + private IDictionary _1688ProductDetailRequestHeader; + + public PurchaseProductAPIService(RestApiService restApiService) + { + this.restApiService = restApiService; + _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"} + }; + } + + public (Purchaser purchaser, IList purchaseSchemeProductSkus)? GetProductInfo(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode, PurchaseProductAPIMode apiMode) + { + (Purchaser purchaser, IList purchaseSchemeProductSkus)? data = null; + if (apiMode == PurchaseProductAPIMode.Spider) + { + data = LoadFromSpider(platform, productId, skuId, purchaseProductId, priceMode); + } + else if (apiMode == PurchaseProductAPIMode.OneBound) + { + data = LoadFromOneBound(platform, productId, skuId, purchaseProductId, priceMode); + } + + return data; + } + + 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 j = JObject.Parse(result.Content); + var isOK = j.Value("error_code") == "0000"; + if (isOK) + { + var skuJArray = (JArray)j["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 = GetSkuLogo(j, (JArray)j["item"]["prop_imgs"]["prop_img"]) + }).ToList(); + + var purchaserId = j["item"]["seller_info"].Value("user_num_id"); + var purchaserName = j["item"]["seller_info"].Value("title"); + if (string.IsNullOrEmpty(purchaserName)) + purchaserName = j["item"]["seller_info"].Value("shop_name"); + var purchaserLocation = j["item"].Value("location"); + + return ( + new Purchaser() + { + Id = purchaserId, + Name = purchaserName, + Location = purchaserLocation + }, + list); + } + } + catch { } + { + return null; + } + } + + private string GetSkuLogo(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.阿里巴巴: + LoadFrom1688Spider(platform, productId, skuId, purchaseProductId, priceMode); + break; + case Platform.拼多多: + + break; + } + 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 + 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); + + if (_1688pageResult.StatusCode != System.Net.HttpStatusCode.OK) + return null; + + var match = Regex.Match(_1688pageResult.Content, @"(window\.__INIT_DATA=)(.*)(\s?)"); + if (!match.Success) + return null; + + var jsonStr = match.Groups[2].Value; + var j = JObject.Parse(jsonStr); + + return null; + } + } +} diff --git a/BBWY.Client/Extensions/EncryptionExtension.cs b/BBWY.Client/Extensions/EncryptionExtension.cs new file mode 100644 index 00000000..8154d6aa --- /dev/null +++ b/BBWY.Client/Extensions/EncryptionExtension.cs @@ -0,0 +1,85 @@ +using System; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace BBWY.Client.Extensions +{ + public static class EncryptionExtension + { + + public static string Md5Encrypt(this string originStr) + { + using (var md5 = MD5.Create()) + { + return string.Join(string.Empty, md5.ComputeHash(Encoding.UTF8.GetBytes(originStr)).Select(x => x.ToString("x2"))); + } + } + + //AES加密 传入,要加密的串和, 解密key + public static string AESEncrypt(this string input) + { + var key = "dataplatform2019"; + var ivStr = "1012132405963708"; + + var encryptKey = Encoding.UTF8.GetBytes(key); + var iv = Encoding.UTF8.GetBytes(ivStr); //偏移量,最小为16 + using (var aesAlg = Aes.Create()) + { + using (var encryptor = aesAlg.CreateEncryptor(encryptKey, iv)) + { + using (var msEncrypt = new MemoryStream()) + { + using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, + CryptoStreamMode.Write)) + + using (var swEncrypt = new StreamWriter(csEncrypt)) + { + swEncrypt.Write(input); + } + var decryptedContent = msEncrypt.ToArray(); + + return Convert.ToBase64String(decryptedContent); + } + } + } + } + + public static string AESDecrypt(this string cipherText) + { + var fullCipher = Convert.FromBase64String(cipherText); + + var ivStr = "1012132405963708"; + var key = "dataplatform2019"; + + var iv = Encoding.UTF8.GetBytes(ivStr); + var decryptKey = Encoding.UTF8.GetBytes(key); + + using (var aesAlg = Aes.Create()) + { + using (var decryptor = aesAlg.CreateDecryptor(decryptKey, iv)) + { + string result; + using (var msDecrypt = new MemoryStream(fullCipher)) + { + using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) + { + using (var srDecrypt = new StreamReader(csDecrypt)) + { + result = srDecrypt.ReadToEnd(); + } + } + } + + return result; + } + } + } + + public static string Base64Encrypt(this string originStr) + { + return Convert.ToBase64String(Encoding.UTF8.GetBytes(originStr)); + } + } +} diff --git a/BBWY.Client/Models/Enums.cs b/BBWY.Client/Models/Enums.cs index fa09e0bd..aebdfec9 100644 --- a/BBWY.Client/Models/Enums.cs +++ b/BBWY.Client/Models/Enums.cs @@ -30,6 +30,15 @@ 代发 = 1 } + /// + /// 采购商品API模式 + /// + public enum PurchaseProductAPIMode + { + Spider = 0, + OneBound = 1 + } + /// /// 仓储类型 /// diff --git a/BBWY.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs b/BBWY.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs index 53a5d04f..a9ca386c 100644 --- a/BBWY.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs +++ b/BBWY.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs @@ -21,6 +21,7 @@ namespace BBWY.Client.ViewModels private GlobalContext globalContext; private OneBoundAPIService oneBoundAPIService; private PurchaseService purchaseService; + private PurchaseProductAPIService purchaseProductAPIService; private string purchaserName; private bool isLoading; @@ -53,11 +54,12 @@ namespace BBWY.Client.ViewModels #endregion #region Methods - public BindingPurchaseProductViewModel(OneBoundAPIService oneBoundAPIService, PurchaseService purchaseService, GlobalContext globalContext) + public BindingPurchaseProductViewModel(PurchaseProductAPIService purchaseProductAPIService, OneBoundAPIService oneBoundAPIService, PurchaseService purchaseService, GlobalContext globalContext) { this.globalContext = globalContext; this.oneBoundAPIService = oneBoundAPIService; this.purchaseService = purchaseService; + this.purchaseProductAPIService = purchaseProductAPIService; ClosingCommand = new RelayCommand(Closing); AddPurchaseProductCommand = new RelayCommand(AddPurchaseProduct); RemovePurchaseSchemeProductCommand = new RelayCommand(RemovePurchaseSchemeProduct); @@ -175,7 +177,7 @@ namespace BBWY.Client.ViewModels var jobject = response.Data; purchaserId = jobject["item"]["seller_info"].Value("user_num_id"); purchaserName = jobject["item"]["seller_info"].Value("title"); - if(string.IsNullOrEmpty(purchaserName)) + if (string.IsNullOrEmpty(purchaserName)) purchaserName = jobject["item"]["seller_info"].Value("shop_name"); purchaserLocation = jobject["item"].Value("location"); if (checkPurchaserFunc != null)