Files
KJD/Store.Management.Framework/Apis/WXApi.cs
T
2026-09-11 19:11:12 +08:00

709 lines
28 KiB
C#

using MAX.Core.DependencyInjection;
using MAX.Core.Helpers;
using Store.Client.HttpExtension;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Store.Framework;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Store.Management.Framework.Apis;
public class WXApi : ITransientDependency
{
private const string Host = "https://store.weixin.qq.com";
private const string WxUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36";
private const string E57UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36";
private const string JsonAccept = "application/json, text/plain, */*";
private const string HtmlAccept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
private const string JsonContentType = "application/json";
private const string WxAcceptLanguage = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6";
private const string E57AcceptLanguage = "zh-CN,zh;q=0.9";
/// <summary>
/// 执行底层 HTTP 请求。
/// </summary>
protected HttpResult Send(HttpItem item)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (string.IsNullOrWhiteSpace(item.URL))
{
throw new ArgumentException("请求地址不能为空。", nameof(item));
}
#if RELEASE
item.WebProxy = null;
#endif
if (!item.URL.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
item.URL = Host + "/" + item.URL.TrimStart('/');
}
item.Encoding = Encoding.UTF8;
if (item.PostEncoding == null)
{
item.PostEncoding = Encoding.UTF8;
}
HttpResult result = HttpHelper.Request(item);
return result;
}
public HttpResult WeiXinAssistantPostResponse(string cookie, string url, string data, string referer)
{
HttpItem item = CreateWxItem(cookie, url, referer);
AddCommonWxHeaders(item, string.Empty, GetCookieValue(cookie, "talent_magic"));
PrepareJsonPost(item, data);
return Send(item);
}
public HttpResult WeiXinPostResponse(string cookie, string url, string data, string referer)
{
HttpItem item = CreateWxItem(cookie, url, referer);
AddCommonWxHeaders(item, GetCookieValue(cookie, "biz_magic"), string.Empty);
PrepareJsonPost(item, data);
return Send(item);
}
public HttpResult WeiXinTalentOpenKfPostResponse(string cookie, string url, string data, string referer)
{
HttpItem item = CreateWxItem(cookie, url, referer);
AddCommonWxHeaders(item, GetCookieValue(cookie, "biz_magic"), string.Empty);
item.Header["user_scene"] = "1002";
item.Header["kf_scene"] = "6";
item.Header["logistics_magic"] = string.Empty;
PrepareJsonPost(item, data);
return Send(item);
}
public HttpResult WeiXinImgPostResponse(string cookie, string url, string data, string disK, long disT, string ext, string openid, string referer = "https://store.weixin.qq.com/")
{
HttpItem item = CreateWxItem(cookie, url, referer);
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["sec-ch-ua"] = "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"";
item.Header["sec-ch-ua-mobile"] = "?0";
item.Header["X-Requested-With"] = "XMLHttpRequest";
item.Header["X-Arguments"] = "dis_k=" + disK + "&dis_t=" + disT.ToString(CultureInfo.InvariantCulture) + "&ext=" + ext + "&apptype=160&filetype=20304&openid=" + openid + "&groupid=0&taskid=" + Guid.NewGuid().ToString();
item.Header["Origin"] = Host;
item.Header["Sec-Fetch-Site"] = "same-site";
item.Header["Sec-Fetch-Mode"] = "cors";
item.Header["Sec-Fetch-Dest"] = "empty";
item.Header["Accept-Encoding"] = "gzip";
item.Header["Accept-Language"] = "zh-CN,zh;q=0.9";
item.Method = MethodType.Post;
item.ContentType = JsonContentType;
item.PostDataType = PostDataType.Byte;
item.PostdataByte = System.Convert.FromBase64String(data ?? string.Empty);
return Send(item);
}
public HttpResult WeiXinUploadResponse(string cookie, string url, string body, string boundaryStr, string referer)
{
HttpItem item = CreateWxItem(GetBizCookies(cookie), url, referer);
AddCommonWxHeaders(item, GetCookieValue(cookie, "biz_magic"), string.Empty, includeMobileHeader: false);
item.ContentType = "multipart/form-data; boundary=" + boundaryStr;
item.Method = MethodType.Post;
item.PostDataType = PostDataType.Byte;
item.PostdataByte = BuildMultipartBody(body);
return Send(item);
}
public HttpResult WeiXinGetResponse(string cookie, string url, string referer = "", bool isGetDocument = false)
{
string cookies = GetBizCookies(cookie);
HttpItem item = CreateWxItem(cookies, url, isGetDocument ? string.Empty : referer, isGetDocument ? HtmlAccept : JsonAccept);
if (isGetDocument)
{
item.Header["sec-ch-ua"] = "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"";
item.Header["sec-ch-ua-mobile"] = "?0";
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["Upgrade-Insecure-Requests"] = "1";
item.Header["Sec-Fetch-Site"] = "none";
item.Header["Sec-Fetch-Mode"] = "navigate";
item.Header["Sec-Fetch-User"] = "?1";
item.Header["Sec-Fetch-Dest"] = "document";
}
else
{
AddCommonWxHeaders(item, GetCookieValue(cookie, "biz_magic"), string.Empty);
}
return Send(item);
}
public HttpResult kdniaoPostResponse(string url, string data, string referer, Dictionary<string, object> reqDic, string kdnAuth = null, string kdnAuthKey = "Auth")
{
HttpItem item = CreateWxItem(string.Empty, url, referer, "application/json, text/javascript, */*; q=0.01");
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["sec-ch-ua"] = "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"";
item.Header["sec-ch-ua-mobile"] = "?0";
item.Header["Origin"] = "https://56.kdniao.com";
item.Header["Accept-Language"] = "zh-CN,zh;q=0.9";
item.Header["Sec-Fetch-Site"] = "same-site";
item.Header["Sec-Fetch-Mode"] = "cors";
item.Header["Sec-Fetch-Dest"] = "empty";
if (reqDic != null)
{
foreach (string key in reqDic.Keys)
{
if (item.Header.AllKeys.Contains(key, StringComparer.OrdinalIgnoreCase))
{
continue;
}
item.Header[key] = reqDic[key]?.ToString() ?? string.Empty;
}
}
item.Header["Accept-Encoding"] = "gzip";
item.Method = MethodType.Post;
item.ContentType = "application/x-www-form-urlencoded";
item.Postdata = data ?? string.Empty;
item.WebProxy = null;
return Send(item);
}
public HttpResult e57PostResponse(string cookie, string url, string data, string referer, string authorization = null)
{
string token = ResolveAuthorization(cookie, authorization);
HttpItem item = CreateE57Item(cookie, token, url, referer);
item.Method = MethodType.Post;
item.ContentType = JsonContentType;
item.Postdata = data ?? string.Empty;
return Send(item);
}
public HttpResult e57GetResponse(string cookie, string url, string referer)
{
string token = ResolveAuthorization(cookie, null);
HttpItem item = CreateE57Item(cookie, token, url, referer);
return Send(item);
}
#region WXUpload 业务接口
public HttpResult searchProduct(string cookie, string extCode, string extCode2 = "")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" +
"token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=5&spuCode=" + extCode;
if (!string.IsNullOrEmpty(extCode2))
{
url += "," + extCode2;
}
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON");
}
public HttpResult searchProductWithSpuId(string cookie, string spuId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" +
"token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=-1&spuId=" + spuId;
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/list");
}
public HttpResult searchProductWithTitle(string cookie, string urlEncodeTitle)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" +
"token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=-1&title=" + urlEncodeTitle;
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/list");
}
public HttpResult getUploadTempImgAuth(string cookie, int uploadScene = 3)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecchannelspicture/cgi/getUploadTempImgAuth?token=&lang=zh_CN&uploadScene=" + uploadScene;
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult adtimageupload(string cookie, string openid, string imgBase64, string disK, long disT, string ext)
{
return WeiXinImgPostResponse(cookie, "https://westorealpha.video.qq.com/adtimageupload", imgBase64, disK, disT, ext, openid, "https://store.weixin.qq.com/");
}
public HttpResult getProductClassify(string cookie, string goodsName, List<string> goodImgUrlsLst)
{
string boundaryStr = CreateBoundary();
string url = "https://store.weixin.qq.com/shop-faas/cgi/common/productClassify?from=B&title=" + WebUtility.UrlEncode(goodsName) + "&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = "--" + boundaryStr + "\r\n";
foreach (string imgFullPath in goodImgUrlsLst ?? new List<string>())
{
string fileName = Path.GetFileName(imgFullPath);
body += "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n" +
"Content-Type: image/jpeg\r\n\r\n" +
"<!>" + imgFullPath + "<!>\r\n--" + boundaryStr;
}
body += "--\r\n";
return WeiXinUploadResponse(cookie, url, body, boundaryStr, referer);
}
public HttpResult getCategoryOnShelf(string cookie, List<long> catIdLst, string brandId = "2100000000")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/getCategoryOnShelfV2?token=&lang=zh_CN";
string body = "{\"catIdList\":[" + string.Join(",", catIdLst) + "],\"brandId\":" + brandId + "}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getMixBrand(string cookie, string catId = "547591")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/getMixBrand?token=&lang=zh_CN";
string body = "{\"categoryId\":\"" + catId + "\"}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult batchCheckCategoryRelation(string cookie, long catId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/batchCheckCategoryRelation?token=&lang=zh_CN";
string body = "{\"categoryIdList\":[" + catId + "]}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult addFinderCategoryV2(string cookie, long catId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/addFinderCategoryV2?token=&lang=zh_CN";
string body = "{\"categoryInfo\":{\"categories\":[{\"id\":\"" + catId + "\"}]},\"brandIdList\":[],\"leafCategoryId\":\"" + catId + "\",\"reuse\":0,\"applyType\":1}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getSingleCategoryData(string cookie, long catId, List<long> catIdLst)
{
string catIds = BuildQuotedArray(catIdLst);
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/getSingleCategoryData?token=&lang=zh_CN&categoryId=" + catId;
string referer = "https://store.weixin.qq.com/shop/brandAndCat/category/apply?defaultCategoryIds=" + WebUtility.UrlEncode(catIds) + "&source=goods&type=apply";
return WeiXinGetResponse(cookie, url, referer);
}
public HttpResult wxCateAuth(string cookie, List<long> catIdLst, string requestJson)
{
string catIds = BuildQuotedArray(catIdLst);
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/addFinderCategoryV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/brandAndCat/category/apply?defaultCategoryIds=" + WebUtility.UrlEncode(catIds) + "&source=goods&type=apply";
return WeiXinPostResponse(cookie, url, requestJson, referer);
}
public HttpResult genProductShortTitle(string cookie, string requestJson)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/genProductShortTitle?token=&lang=zh_CN";
return WeiXinPostResponse(cookie, url, requestJson, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getFreightTemplate(string cookie)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/express/cgi/goods/getFreightTemplate?token=&lang=zh_CN";
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getAddress(string cookie, string searchText = "")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?token=&lang=zh_CN";
if (!string.IsNullOrEmpty(searchText))
{
url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?searchStr=" + WebUtility.UrlEncode(searchText) + "&token=&lang=zh_CN";
}
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getAddressById(string cookie, string addressId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?offset=0&limit=20&includeBlock=1&addressId=" + addressId + "&token=&lang=zh_CN";
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/address/expressAddressMgmt");
}
public HttpResult uploadProductDraft(string cookie, string productJson)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/uploadProductDraft?token=&lang=zh_CN";
productJson = SetJsonProperty(productJson, "type", 1);
return WeiXinPostResponse(cookie, url, WrapData(productJson), "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult upProductV2(string cookie, string productJson)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN";
return WeiXinPostResponse(cookie, url, WrapData(productJson), "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult checkProductUpload(string cookie, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/checkUploadProductDraftStatus?token=&lang=zh_CN&productKey=%7B%22productId%22:" + productId + "%7D&preview=false";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo=" +
"{%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
return WeiXinGetResponse(cookie, url, referer);
}
public HttpResult SearchProductUpload(string cookie, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?token=&lang=zh_CN&pageSize=20&productStatus[]=-1" +
"&productSource=[1,16,32]&searchSource=1&useNew=true&fromProductManager=1&pageNum=1&status[]=2&spuId=" + productId;
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_EDIT");
}
public HttpResult upProductJObjectV2(string cookie, string prodStr)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN";
return WeiXinPostResponse(cookie, url, WrapData(prodStr), "https://store.weixin.qq.com/shop/goods/entry");
}
public HttpResult getEditProductV2(string cookie, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/getEditProductV2?token=&lang=zh_CN&productKey=%7B%22productId%22:" + productId + "%7D&needRealStock=true&preview=false&release=false";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo={%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
return WeiXinGetResponse(cookie, url, referer);
}
public HttpResult initUploadPart(string cookie, string submitJson, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/initUploadPart?token=&lang=zh_CN";
string referer = BuildAuditFreeReferer(prodId, time1, time2);
return WeiXinPostResponse(cookie, url, submitJson, referer);
}
public HttpResult listingAuditFree(string cookie, string productJson, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/listingAuditFree?token=&lang=zh_CN";
string referer = BuildAuditFreeReferer(prodId, time1, time2);
return WeiXinPostResponse(cookie, url, WrapData(productJson), referer);
}
public HttpResult uploadPartBinary(string cookie, string initFileName, string blobPath, string uploadId, string prodId, int time1, int time2)
{
string boundaryStr = CreateBoundary();
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/uploadPartBinary?token=&lang=zh_CN";
string referer = BuildAuditFreeReferer(prodId, time1, time2);
string body = "--" + boundaryStr + "\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" + initFileName + "\r\n" +
"--" + boundaryStr + "\r\n" +
"Content-Disposition: form-data; name=\"uploadId\"\r\n\r\n" + uploadId + "\r\n" +
"--" + boundaryStr + "\r\n" +
"Content-Disposition: form-data; name=\"partSeq\"\r\n\r\n1\r\n" +
"--" + boundaryStr + "\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"blob\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n" +
"<!>" + blobPath + "<!>\r\n--" + boundaryStr + "--\r\n";
return WeiXinUploadResponse(cookie, url, body, boundaryStr, referer);
}
public HttpResult completeUploadPart(string cookie, string completeJson, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/completeUploadPart?token=&lang=zh_CN";
string referer = BuildAuditFreeReferer(prodId, time1, time2);
return WeiXinPostResponse(cookie, url, completeJson, referer);
}
public HttpResult addAddress(string cookie, string provinceName, string cityName, string countyName, string detailInfo, string userName, string telNumber)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/address/addAddress?token=&lang=zh_CN";
string address = JsonConvert.SerializeObject(new
{
addressInfo = new
{
provinceName,
cityName,
countyName,
detailInfo,
userName,
telNumber,
location = new JObject()
},
defaultSend = 0,
defaultRecv = 0
});
return WeiXinPostResponse(cookie, url, WrapData(address), "https://store.weixin.qq.com/shop/address/expressAddressMgmt");
}
public HttpResult GetApiServiceList(string cookie)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeservicemarket/service/GetMyServiceList?offset=0&limit=20&status=2&token=&lang=zh_CN";
return WeiXinGetResponse(cookie, url, "https://store.weixin.qq.com/shop/servicemarket/myServices?status=2");
}
public HttpResult GetAndUpdateWebStatus(string cookie)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradehome/home/getAndUpdateWebStatus?token=&lang=zh_CN";
long startMs = ToTimestampMilliseconds(DateTime.Now.Date.AddDays(-1));
long endMs = ToTimestampMilliseconds(DateTime.Now.Date.AddSeconds(-1));
string body = "{\"timeQuery\":{\"startMs\":" + startMs + ",\"endMs\":" + endMs + "}}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/home");
}
public HttpResult addLeagueItemForUpdatingProduct(string cookie, int itemSwitch, int itemRatio, int headSupplierItemSwitch, int headSupplierItemRatio, long prodId, int updType = 2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/addLeagueItemForUpdatingProduct?token=&lang=zh_CN";
string body = "{\"itemSwitch\":" + itemSwitch + ",\"itemRatio\":" + itemRatio + ",\"headSupplierPublicItemSwitch\":" + headSupplierItemSwitch +
",\"headSupplierPublicItemServiceRatio\":" + headSupplierItemRatio + ",\"productId\":" + prodId + ",\"scene\":2,\"updType\":" + updType + "}";
return WeiXinPostResponse(cookie, url, body, "https://store.weixin.qq.com/shop/home");
}
public HttpResult generalProductInfoRecommend(string cookie, string productId, string requestJson)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/aiRecommendCompat/cgi/goods/generalProductInfoRecommend?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo={%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
return WeiXinPostResponse(cookie, url, requestJson, referer);
}
public HttpResult wxGetAssistant(string cookie, string prodId, string pageContext = null, string spu_id = null)
{
var NULL = (object)null;
string url = "https://store.weixin.qq.com/shop-faas/mmeckolpoolnode/ecSearchSelectionSpuItems?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/talent/pool/home";
if (!string.IsNullOrEmpty(prodId))
{
referer += "?keyword=" + prodId;
}
object data = new
{
filter = new
{
spuFilter = new
{
monthlySalesRange = NULL,
goodEvaluationRatioRange = NULL,
shopScoreRange = NULL
},
spuSort = new
{
sortOrder = 0,
sortType = 0
},
category = NULL
},
pageContext = new
{
pageContext = pageContext,
limit = 15
},
requestContext = new
{
sessionId = DateHelper.GetUnixTimestampInMilliseconds(DateTime.Now.AddSeconds(-RandomHelper.GetRandomNumber(10, 100))),
requestId = DateHelper.GetUnixTimestampInMilliseconds(DateTime.Now),
parentSearchId = 53,
displayedSpus =
string.IsNullOrEmpty(spu_id) ? NULL : new
{
spuId = spu_id,
}
},
keyword = prodId
};
string body = JsonConvert.SerializeObject(data);
var result = WeiXinAssistantPostResponse(cookie, url, body, referer);
return result;
}
#endregion
private static HttpItem CreateWxItem(string cookie, string url, string referer, string accept = JsonAccept)
{
return new HttpItem
{
URL = url,
Cookie = cookie ?? string.Empty,
Referer = referer ?? string.Empty,
KeepAlive = true,
Expect100Continue = false,
UserAgent = WxUserAgent,
Accept = accept,
PostEncoding = Encoding.UTF8
};
}
private static HttpItem CreateE57Item(string cookie, string token, string url, string referer)
{
HttpItem item = new HttpItem
{
URL = url,
Cookie = BuildAuthorizationCookie(cookie, token),
KeepAlive = true,
Expect100Continue = false,
UserAgent = E57UserAgent,
Accept = HtmlAccept,
PostEncoding = Encoding.UTF8,
WebProxy = null
};
if (url != null && url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
item.ProtocolVersion = HttpVersion.Version10;
}
item.Header["sec-ch-ua"] = "\"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"144\", \"Google Chrome\";v=\"144\"";
item.Header["sec-ch-ua-mobile"] = "?0";
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["Upgrade-Insecure-Requests"] = "1";
item.Header["Authorization"] = "Bearer " + token;
item.Header["Sec-Fetch-Site"] = "none";
item.Header["Sec-Fetch-Mode"] = "navigate";
item.Header["Sec-Fetch-User"] = "?1";
item.Header["Sec-Fetch-Dest"] = "document";
item.Header["Accept-Encoding"] = "gzip";
item.Header["Accept-Language"] = E57AcceptLanguage;
return item;
}
private static void AddCommonWxHeaders(HttpItem item, string bizMagic, string talentMagic, bool includeMobileHeader = true)
{
item.Header["wecom_magic"] = string.Empty;
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["supplier_magic"] = string.Empty;
item.Header["sec-ch-ua"] = "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"";
if (includeMobileHeader)
{
item.Header["sec-ch-ua-mobile"] = "?0";
}
item.Header["potter-scene"] = "weixinShop";
item.Header["biz_magic"] = bizMagic ?? string.Empty;
item.Header["talent_magic"] = talentMagic ?? string.Empty;
item.Header["mcn_magic"] = string.Empty;
item.Header["Origin"] = Host;
item.Header["Sec-Fetch-Site"] = "same-origin";
item.Header["Sec-Fetch-Mode"] = "cors";
item.Header["Sec-Fetch-Dest"] = "empty";
item.Header["Accept-Encoding"] = "gzip";
item.Header["Accept-Language"] = WxAcceptLanguage;
}
private static void PrepareJsonPost(HttpItem item, string data)
{
item.Method = MethodType.Post;
item.ContentType = JsonContentType;
item.Postdata = data ?? string.Empty;
}
private static string CreateBoundary()
{
return "----WebKitFormBoundary" + Guid.NewGuid().ToString("N").Substring(0, 16);
}
private static string BuildQuotedArray(List<long> values)
{
return "[\"" + string.Join("\",\"", values ?? new List<long>()) + "\"]";
}
private static string WrapData(string data)
{
return JsonConvert.SerializeObject(new { data = data ?? string.Empty });
}
private static string SetJsonProperty(string json, string propertyName, JToken value)
{
if (string.IsNullOrWhiteSpace(json))
{
return json;
}
try
{
JObject obj = JObject.Parse(json);
obj[propertyName] = value;
return obj.ToString(Formatting.None);
}
catch
{
return json;
}
}
private static string BuildAuditFreeReferer(string prodId, int time1, int time2)
{
return "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId +
"&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" +
"{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," +
"%22listingTime%22:" + time2 + "}";
}
private static long ToTimestampMilliseconds(DateTime time)
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
return (long)(time - startTime).TotalMilliseconds;
}
private static string GetCookieValue(string cookie, string name)
{
if (string.IsNullOrWhiteSpace(cookie))
{
return string.Empty;
}
foreach (string part in cookie.Split(';'))
{
string value = part.Trim();
int index = value.IndexOf('=');
if (index <= 0)
{
continue;
}
string key = value.Substring(0, index).Trim();
if (key.Equals(name, StringComparison.OrdinalIgnoreCase))
{
return value.Substring(index + 1).Trim();
}
}
return string.Empty;
}
private static string GetBizCookies(string cookie)
{
if (string.IsNullOrWhiteSpace(cookie))
{
return string.Empty;
}
return string.Join(";", cookie
.Split(';')
.Select(part => part.Trim())
.Where(part =>
{
int index = part.IndexOf('=');
return index > 0 && part.Substring(0, index).Trim().StartsWith("biz", StringComparison.OrdinalIgnoreCase);
}));
}
private static string ResolveAuthorization(string cookie, string authorization)
{
if (!string.IsNullOrWhiteSpace(authorization))
{
string value = authorization.Trim();
return value.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)
? value.Substring("Bearer ".Length).Trim()
: value;
}
string token = GetCookieValue(cookie, "Admin-Token");
if (!string.IsNullOrWhiteSpace(token))
{
return token;
}
return string.IsNullOrWhiteSpace(cookie) ? string.Empty : cookie.Trim();
}
private static string BuildAuthorizationCookie(string cookie, string token)
{
if (!string.IsNullOrWhiteSpace(cookie) && cookie.IndexOf('=') >= 0)
{
return cookie;
}
return string.IsNullOrWhiteSpace(token) ? string.Empty : "Admin-Token=" + token;
}
private static byte[] BuildMultipartBody(string body)
{
if (string.IsNullOrEmpty(body))
{
return Array.Empty<byte>();
}
using (MemoryStream stream = new MemoryStream())
{
foreach (string part in Regex.Split(body, @"<!>"))
{
byte[] bytes = File.Exists(part)
? File.ReadAllBytes(part)
: Encoding.UTF8.GetBytes(part.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n"));
stream.Write(bytes, 0, bytes.Length);
}
return stream.ToArray();
}
}
}