359 lines
23 KiB
C#
359 lines
23 KiB
C#
using AllBase;
|
|
using AllBase.Helper;
|
|
using AllBase.Model.Result;
|
|
using AllBase.Model.Result.WXResult;
|
|
using NaiBa.Util.Extension;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using TemuKJD.WXForms.ShopForms;
|
|
using Work;
|
|
|
|
namespace TemuKJD.BLL.Wx
|
|
{
|
|
public class WxPlatformRecommendProdManage
|
|
{
|
|
public static int minViewUv { get; set; } = 500;
|
|
public static int getInterval { get; set; } = 3;
|
|
public static bool isGetOnce { get; set; } = true;
|
|
|
|
public void GetPlatformRecommendProduct()
|
|
{
|
|
|
|
Task.Run(() =>
|
|
{
|
|
if (!Directory.Exists("wxPlatformRecommendUpdate"))
|
|
Directory.CreateDirectory("wxPlatformRecommendUpdate");
|
|
|
|
while (true)
|
|
{
|
|
int cnt = 0;
|
|
foreach (var shop in GlobalConfig.ShopLoginList)
|
|
{
|
|
if (shop.LoginStatus != "登录成功")
|
|
continue;
|
|
|
|
if (shop.ShopId == "wx8fd533b89195d717")
|
|
{
|
|
|
|
}
|
|
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
|
|
WXPlatformRecommendUpdateInfo info = new WXPlatformRecommendUpdateInfo() { shopId = shop.ShopId, updateDay = DateTime.Now.ToString("yyMMdd") };
|
|
try
|
|
{
|
|
info = NaiBa.Util.Helper.ConfigHelper.LoadConfig<WXPlatformRecommendUpdateInfo>("wxPlatformRecommendUpdate\\" + shop.ShopId);
|
|
if (info == null)
|
|
info = new WXPlatformRecommendUpdateInfo() { shopId = shop.ShopId, updateDay = DateTime.MinValue.ToString("yyMMdd") };
|
|
|
|
if (info.updateDay == DateTime.Now.ToString("yyMMdd") && isGetOnce)
|
|
{
|
|
// 已查询过,跳过,暂时关闭改为每次打开都查询
|
|
continue;
|
|
}
|
|
|
|
info.failReason = "";
|
|
|
|
long endMs = BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date) - 1;
|
|
long startMs = BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date.AddDays(-30));
|
|
string result = "";
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
result = getPlatformRecommend(shop, startMs, endMs, i + 1);
|
|
if (!result.Contains("\"code\":0"))
|
|
{
|
|
WXForms.ShopForms.WXShopListForm.CheckShopLogin(shop);
|
|
|
|
info.failReason = "读取失败,推荐商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
break;
|
|
}
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
|
|
try
|
|
{
|
|
var jArr = JsonHelper.JObjectParse(result)["data"]["data"]["list"];
|
|
List<WXPlatformRecommendProdInfo> recommendProds = JsonHelper.DeserializeJsonToList<WXPlatformRecommendProdInfo>(JsonHelper.SerializeObject(jArr));
|
|
foreach (var recommendProd in recommendProds)
|
|
{
|
|
if (recommendProd.product_view_uv.ParseToInt() < minViewUv)
|
|
{
|
|
i = 999999;
|
|
break;
|
|
}
|
|
|
|
cnt++;
|
|
if (cnt % 20 == 0)
|
|
{
|
|
var url0 = BaseClass.BuildObjString("product/is_get_wx_recommend_hot_prod");
|
|
var data0 = "";
|
|
data0 = UserLogin.GetSignaturex();
|
|
var html0 = GetHtml.PostUtf8(url0, data0);
|
|
if (!html0.Contains("\"code\":200"))
|
|
html0 = GetHtml.PostUtf8(url0, data0);
|
|
if (html0.Contains("\"is_get\":\"true\""))
|
|
{
|
|
minViewUv = Math.Max(100, BaseRegex.GetIntJson(ref html0, "minViewUv"));
|
|
getInterval = Math.Max(3, BaseRegex.GetIntJson(ref html0, "getViewUvInterval"));
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Thread.Sleep(getInterval * 1000);
|
|
|
|
#region 查询爆款数据是否已存在
|
|
var url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
var data = "";
|
|
data = UserLogin.GetSignaturex() +
|
|
"&search_prod_name_in=" + GetHtml.UrlEncodeUtf8(recommendProd.title) + //"&wx_safe_status=" + "安全商品,未校验" +
|
|
"&special_prod_type=爆款数据" +
|
|
"&is_not_count=true";
|
|
var html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
var prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
List<KJDDBProduct> dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
var dbProdHotLst = dbProdLst.Where(p => p.special_prod_type == "爆款数据").ToList();
|
|
var existHotProd = dbProdHotLst.FirstOrDefault();
|
|
if (existHotProd != null) // 爆款数据商品已存在,更新下曝光量view_uv后继续
|
|
{
|
|
if(existHotProd.view_uv.ParseToInt() < recommendProd.product_view_uv.ParseToInt())
|
|
{
|
|
url = BaseClass.BuildObjString("product/mdy_best_sale_prod");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&spu_id=" + existHotProd.spu_id +
|
|
"&view_uv=" + recommendProd.product_view_uv;
|
|
html = GetHtml.PostUtf8(url, data);
|
|
}
|
|
continue;
|
|
}
|
|
#endregion
|
|
|
|
WXGetEditProductInfoLite wxProdInfoLite = null;
|
|
var rst1 = new WXShopBrowserObject().GetWxProduct(shop, recommendProd.product_id, ref wxProdInfoLite, true);
|
|
if (rst1 != "success")
|
|
{
|
|
info.failReason = "读取失败,微信商品详情查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
string spuCode = wxProdInfoLite.product.info.spuCode.ParseToString(); // 2042905570314301442
|
|
|
|
#region 查询原始数据
|
|
dbProdLst.Clear();
|
|
if (spuCode.Length == 19)
|
|
{
|
|
url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&search_secret_spu_ids=" + spuCode +
|
|
"&special_prod_type=普通商品,书籍" +
|
|
"&is_not_count=true";
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
}
|
|
|
|
if (dbProdLst.Count == 0 && spuCode.StartsWith("EC1") && spuCode.EndsWith("A"))
|
|
{
|
|
spuCode = spuCode.Substring(3, spuCode.Length - 4);
|
|
url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&search_spu=" + spuCode +
|
|
"&special_prod_type=普通商品,书籍" +
|
|
"&is_not_count=true";
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
}
|
|
|
|
if (dbProdLst.Count == 0 && spuCode.Length > 10)
|
|
{
|
|
url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&ext_code_in=" + spuCode +
|
|
"&special_prod_type=普通商品,书籍" +
|
|
"&is_not_count=true";
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
}
|
|
|
|
if (dbProdLst.Count == 0)
|
|
{
|
|
url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&search_prod_name_in=" + GetHtml.UrlEncodeUtf8(recommendProd.title) +
|
|
"&special_prod_type=普通商品,书籍" +
|
|
"&is_not_count=true";
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
}
|
|
|
|
if (dbProdLst.Count == 0 && spuCode.Length > 10)
|
|
{
|
|
url = BaseClass.BuildPDDObjString("product/get_product_list");
|
|
data = UserLogin.GetSignaturex() +
|
|
"&ext_code_in=" + GetHtml.UrlEncodeUtf8(recommendProd.title) +
|
|
"&special_prod_type=普通商品,书籍" +
|
|
"&is_not_count=true";
|
|
html = GetHtml.PostUtf8(url, data);
|
|
if (!html.Contains("\"code\":200"))
|
|
{
|
|
info.failReason = "读取失败,库存商品查询失败";
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
prodObjs = JsonHelper.JObjectParse(html)["data"];
|
|
dbProdLst = JsonHelper.DeserializeJsonToList<KJDDBProduct>(JsonHelper.SerializeObject(prodObjs));
|
|
}
|
|
#endregion
|
|
|
|
var dbProdNormalLst = dbProdLst.Where(p => p.special_prod_type != "爆款数据").ToList();
|
|
var normalJstProd = dbProdNormalLst
|
|
.FirstOrDefault(p => p.product_get_type_text == "厂商直采" && p.secret_spu_id == wxProdInfoLite.product.info.spuCode);
|
|
|
|
string prodId = recommendProd.product_id;
|
|
string coid = normalJstProd?.skc_id;
|
|
string real_coid = string.IsNullOrEmpty(normalJstProd?.real_coid) ? coid : normalJstProd?.real_coid;
|
|
string wx_safe_status = !dbProdNormalLst.Any(p => p.wx_safe_status == "违规商品") ? "安全商品" : "违规商品";
|
|
int? view_uv = recommendProd.product_view_uv.IsNullOrEmpty() ? (int?)null : recommendProd.product_view_uv.ParseToInt();
|
|
var rst2 = new WXShopBrowserObject()
|
|
.SaveWxProd(shop, prodId, wxProdInfoLite, "爆款数据", coid, real_coid, view_uv, wx_safe_status);
|
|
|
|
if (!rst2.Contains("微信商品采集入库成功"))
|
|
{
|
|
info.failReason = "查询失败," + rst2;
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.failReason = "读取失败" + ex.Message;
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
continue;
|
|
}
|
|
|
|
var total = BaseRegex.GetIntJson(ref result, "list_total");
|
|
var totalPage = Math.Ceiling(1.0m * total / 10).ParseToInt();
|
|
if (totalPage <= i + 1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (!result.Contains("\"code\":0"))
|
|
continue;
|
|
|
|
if (string.IsNullOrEmpty(info.failReason))
|
|
info.updateDay = DateTime.Now.ToString("yyMMdd");
|
|
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxPlatformRecommendUpdate\\" + shop.ShopId, info);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
// 不循环获取
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
public static string getPlatformRecommend(ShopLoginInfo shop, long startMs, long endMs, int page = 1, int pageSize = 10, int dateRange = 30)
|
|
{
|
|
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradebase/cgi/shop/getShopRecommendProducts?token=&lang=zh_CN";
|
|
string data = @"{""isToday"":false,""offset"":" + Math.Max(0, page - 1) * pageSize + @",""limit"":" + pageSize + @",""sort"":[""product_view_uv"",""desc""]," +
|
|
@"""time_query"":{""dateFormat"":2,""dateType"":0,""dateRange"":" + dateRange + @",""startMs"":" + startMs + @",""endMs"":" + endMs + @"}}";
|
|
// 不含当天
|
|
//{"isToday":false,"offset":0,"limit":10,"sort":["product_view_uv","desc"],"time_query":{"dateFormat":2,"dateType":0,"dateRange":7,"startMs":1777996800000,"endMs":1778601599999}}
|
|
//{"isToday":false,"offset":0,"limit":10,"sort":["product_view_uv","desc"],"time_query":{"dateFormat":2,"dateType":0,"dateRange":30,"startMs":1775836800000,"endMs":1778428799999}}
|
|
string referer = "https://store.weixin.qq.com/shop/platformrecommend/recommendationFeed";
|
|
var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, data, referer);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public class WXPlatformRecommendUpdateInfo
|
|
{
|
|
public string shopId { get; set; }
|
|
public string updateDay { get; set; } // yyMMdd
|
|
public string failReason { get; set; } // "", "掉线"...
|
|
}
|
|
|
|
public class WXPlatformRecommendProdInfo
|
|
{
|
|
public string title { get; set; } // "微喇西装裤女春夏2026新款高腰垂感修身显瘦时尚休闲宽松喇叭裤子",
|
|
public string product_id { get; set; } // "10000675790067",
|
|
public string img_url { get; set; } // "https://wst.wxapp.tc.qq.com/161/20304/snscosdownload/SH/reserved/69cbce98000dfa510ed4e417e15f1b15000000a100004f50",
|
|
public int? market_price { get; set; } // 3190,
|
|
public int? selling_price { get; set; } // 3190,
|
|
public int? status { get; set; } // 1,
|
|
public string pay_order_cnt { get; set; } // "20", // 支付订单数
|
|
public string product_view_to_click_uv_ratio { get; set; } // "0.036331", // 曝光点击率
|
|
public string product_view_to_click_cnt_ratio { get; set; } // "0.032594",
|
|
public string product_view_cnt { get; set; } // "12855",
|
|
public string product_click_to_pay_cnt_ratio { get; set; } // "0.047733",
|
|
public string product_click_uv { get; set; } // "400", // 点击人数
|
|
public string product_click_to_pay_uv_ratio { get; set; } // "0.05", // 点击转化率
|
|
public string pay_uv { get; set; } // "20", // 支付人数
|
|
public string pay_product_cnt { get; set; } // "20",
|
|
public string pay_gmv { get; set; } // "61800", // 支付金额,单位分
|
|
public string product_view_uv { get; set; } // "11010", // 曝光人数
|
|
public string product_click_cnt { get; set; } // "419", // 商品点击数
|
|
public string pay_order_cnt_hb { get; set; } // "",
|
|
public string product_view_to_click_uv_ratio_hb { get; set; } // "",
|
|
public string product_view_to_click_cnt_ratio_hb { get; set; } // "",
|
|
public string product_view_cnt_hb { get; set; } // "134.315789",
|
|
public string product_click_to_pay_cnt_ratio_hb { get; set; } // "",
|
|
public string product_click_uv_hb { get; set; } // "",
|
|
public string product_click_to_pay_uv_ratio_hb { get; set; } // "",
|
|
public string pay_uv_hb { get; set; } // "",
|
|
public string pay_product_cnt_hb { get; set; } // "",
|
|
public string pay_gmv_hb { get; set; } // "",
|
|
public string product_view_uv_hb { get; set; } // "117.387097",
|
|
public string product_click_cnt_hb { get; set; } // ""
|
|
|
|
}
|
|
}
|