拼多多买手读单优化

This commit is contained in:
wule committed 2026-10-21 11:59:12 +08:00
1 parent b63dacfe7e
commit 4d7fd2c157
1 file changed
+172 -187
@@ -86,6 +86,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
}
Dictionary<BuyerLoginInfo, string> dicPddAftersaleNextQueryCreatedAt = new Dictionary<BuyerLoginInfo, string>();
Dictionary<BuyerLoginInfo, string> dicPddOrderOffset = new Dictionary<BuyerLoginInfo, string>();
Dictionary <BuyerLoginInfo, PddPickInfo> dicPddPickInfo = new Dictionary<BuyerLoginInfo, PddPickInfo>();
ConcurrentList<yh_sync_logistics> lstSyncLogistics = new ConcurrentList<yh_sync_logistics>();
@@ -753,8 +754,11 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
var list = JsonHelper.DeserializeJsonToList<PddBuyerOrderLiteInfo>(JsonHelper.JObjectParse(data)["orders"].ParseToString());
// 提取拼多多外采订单列表
var out_order_nos = string.Join(",", list.Select(bo => bo.order_sn));
if (list.Count > 0)
dicPddOrderOffset[buyer] = list.LastOrDefault().order_sn;
// 提取拼多多外采订单列表
var out_order_nos = string.Join(",", list.Select(bo => bo.order_sn));
if (out_order_nos.Contains("260817-535832839751006"))
{
@@ -1502,8 +1506,12 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
async Task GetOrderAndAfterSale()
{
await JsGetPddOrder();
//ScrollGetPddOrder();
bool isScroll = false;
if (isScroll == false)
await JsGetPddOrder();
else
ScrollGetPddOrder();
//MakeWxToPddAfterSales();
nextGetOrderTime = DateTime.Now.AddMinutes(25);
@@ -1528,7 +1536,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
{
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(null, "已取消读取");
ShowBuyerOrderReadInfo(null, "已取消读取");
break;
}
Thread.Sleep(500);
@@ -1588,181 +1596,43 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
buyer.wpf_browser.Load("https://mobile.yangkeduo.com/psnl_goods_help.html?_t_module_name=assistant_search&refer_scene=no_pickup_package_express&refer_page_name=goods_express");
Thread.Sleep(Randomx.GetId(2000, 3000));
string readBuyer = "";
int top = 0;
int times = 0;
#region 售后
if (1 == 1)
{
await JsGetPddAftersaleOrder(buyer, tokenSource);
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
await JsGetPddAftersale(buyer, tokenSource);
if (buyer.status != "在线") { continue; }
if (isSkipNext) { isSkipNext = false; continue; }
if (tokenSource.IsCancellationRequested) { ShowBuyerOrderReadInfo(buyer, "已取消读取"); break; }
Thread.Sleep(Randomx.GetId(2000, 3000));
}
#endregion
#region 待发货
readBuyer = buyer.buyer_id;
currentReadBuyer = buyer.buyer_id;
buyer.wpf_browser.Load("https://mobile.yangkeduo.com/orders.html?type=2");
BindBuyerOrderReadInfo(buyer, "正在读取待发货");
Dispatcher.Invoke(new Action(() =>
if (2 == 2)
{
Panel.SetZIndex(buyer.wpf_browser, maxZIndex++);
if (buyer.IsSelect != true)
{
foreach (var b in GlobalConfig.PDDBuyerLoginList)
{
b.IsSelect = false;
}
buyer.IsSelect = true;
}
}));
Thread.Sleep(Randomx.GetId(2000, 3000));
await JsGetPddOrder(buyer, 2, tokenSource);
top = 0;
lastCefReadOrderTime = DateTime.Now;
while (currentReadBuyer == readBuyer)
{
if (isSkipNext)
break;
if (buyer.status != "在线") { continue; }
if (isSkipNext) { isSkipNext = false; continue; }
if (tokenSource.IsCancellationRequested) { ShowBuyerOrderReadInfo(buyer, "已取消读取"); break; }
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30))
{
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
if (times % 100 == 0)
{
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
}
if (buyer.status != "在线")
break;
times++;
top += Randomx.GetId(450, 600);
Thread.Sleep(Randomx.GetId(100, 300));
var jsStr = @"window.scroll({
top: " + top + @",
left: 0,
behavior: 'smooth' // 可选,使滚动平滑
});";
//var t1 = cefWebBrowser.GetMainFrame().EvaluateScriptAsync(jsStr);
//t1.Wait(1000);
var client = buyer.wpf_browser.GetDevToolsClient();
if (client != null)
{
var result = client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true);
result.Wait(5000);
}
Thread.Sleep(Randomx.GetId(2000, 3000));
}
if (isSkipNext)
{
isSkipNext = false;
continue;
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
Thread.Sleep(Randomx.GetId(2000, 3000));
#endregion
#region 已发货
readBuyer = buyer.buyer_id;
currentReadBuyer = buyer.buyer_id;
buyer.wpf_browser.Load("https://mobile.yangkeduo.com/orders.html?type=3");
BindBuyerOrderReadInfo(buyer, "正在读取已发货");
Dispatcher.Invoke(new Action(() =>
if (3 == 3)
{
Panel.SetZIndex(buyer.wpf_browser, maxZIndex++);
if (buyer.IsSelect != true)
{
foreach (var b in GlobalConfig.PDDBuyerLoginList)
{
b.IsSelect = false;
}
buyer.IsSelect = true;
}
}));
Thread.Sleep(Randomx.GetId(2000, 3000));
await JsGetPddOrder(buyer, 3, tokenSource);
top = 0;
lastCefReadOrderTime = DateTime.Now;
while (currentReadBuyer == readBuyer)
{
if (isSkipNext)
break;
if (buyer.status != "在线") { continue; }
if (isSkipNext) { isSkipNext = false; continue; }
if (tokenSource.IsCancellationRequested) { ShowBuyerOrderReadInfo(buyer, "已取消读取"); break; }
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30))
{
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
top += Randomx.GetId(450, 600);
Thread.Sleep(Randomx.GetId(100, 300));
var jsStr = @"window.scroll({
top: " + top + @",
left: 0,
behavior: 'smooth' // 可选,使滚动平滑
});";
//var t1 = cefWebBrowser.GetMainFrame().EvaluateScriptAsync(jsStr);
//t1.Wait(1000);
var client = buyer.wpf_browser.GetDevToolsClient();
if (client != null)
{
var result = client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true);
result.Wait(5000);
}
Thread.Sleep(Randomx.GetId(2000, 3000));
}
if (isSkipNext)
{
isSkipNext = false;
continue;
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
Thread.Sleep(Randomx.GetId(2000, 3000));
#endregion
}
catch (Exception ex)
@@ -1777,9 +1647,21 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
}
isReadBuyerOrder = false;
BindBuyerOrderReadInfo(null, "订单读取已结束,等待下次读取");
ShowBuyerOrderReadInfo(null, "订单读取已结束,等待下次读取");
}, cancellationTokenSource.Token);
}
public async Task<bool> IsInstalledAsync(IFrame frame, int timeoutMs = 3000)
{
var deadline = DateTime.Now.AddMilliseconds(timeoutMs);
while (DateTime.Now < deadline)
{
var r = await frame.EvaluateScriptAsync("!!(window.PDDOrders && window.PDDOrders.__installed)")
.ConfigureAwait(false);
if (r != null && r.Success && r.Result is bool && (bool)r.Result) return true;
await Task.Delay(100).ConfigureAwait(false);
}
return false;
}
public static async Task<bool> IsAftersaleJsInstalledAsync(IFrame frame, int timeoutMs = 3000)
{
@@ -1794,13 +1676,113 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
return false;
}
async Task JsGetPddAftersaleOrder(BuyerLoginInfo buyer, CancellationTokenSource tokenSource)
/// <summary>
///
/// </summary>
/// <param name="type">2待发货 3已发货</param>
/// <returns></returns>
async Task JsGetPddOrder(BuyerLoginInfo buyer, int type, CancellationTokenSource tokenSource)
{
var readBuyer = buyer.buyer_id;
currentReadBuyer = buyer.buyer_id;
buyer.wpf_browser.Load("https://mobile.yangkeduo.com/orders.html?type=" + type);
if (type == 2)
ShowBuyerOrderReadInfo(buyer, "正在读取待发货");
else if (type == 3)
ShowBuyerOrderReadInfo(buyer, "正在读取已发货");
else
ShowBuyerOrderReadInfo(buyer, "正在读取订单");
Dispatcher.Invoke(new Action(() =>
{
Panel.SetZIndex(buyer.wpf_browser, maxZIndex++);
if (buyer.IsSelect != true)
{
foreach (var b in GlobalConfig.PDDBuyerLoginList.ToList())
{
b.IsSelect = false;
}
buyer.IsSelect = true;
}
}));
Thread.Sleep(Randomx.GetId(2000, 3000));
var client = buyer.wpf_browser.GetDevToolsClient();
if (client == null)
return;
// 注入触发翻滚的js事件
string address = "";
Dispatcher.Invoke(() => { address = buyer.wpf_browser.Address; });
if (address.StartsWith("https://mobile.yangkeduo.com/orders.html?type="))
{
string content = ResourceHelper.GetResourceText("/Ctrls/PDDInvoice/Resources/order.js", "29WxFindOrder");
if (string.IsNullOrEmpty(content))
return;
await client.Runtime.EvaluateAsync(content, null, true, null, null, true, null, true);
var frame = cefWebBrowser.GetMainFrame();
if (await IsInstalledAsync(frame) != true)
{
ShowBuyerOrderReadInfo(buyer, "订单读取预加载失败!");
return;
}
}
lastCefReadOrderTime = DateTime.Now;
string tempOffset = "";
while (currentReadBuyer == readBuyer)
{
if (isSkipNext)
{
ShowBuyerOrderReadInfo(buyer, "已跳过当前买手订单读取");
break;
}
if (tokenSource.IsCancellationRequested)
{
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30))
{
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
ShowBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
ShowBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
if (!dicPddOrderOffset.ContainsKey(buyer))
dicPddOrderOffset[buyer] = "0";
if (dicPddOrderOffset[buyer] == tempOffset)
{
await Task.Delay(500);
continue;
}
else
{
}
tempOffset = dicPddOrderOffset[buyer];
string jsStr = $"PDDOrders.trigger({{offset:'MO-01-{dicPddOrderOffset[buyer]}',type:{type},size:10,mode:'store'}})";
await client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true);
await Task.Delay(Randomx.GetId(2000, 4000));
}
}
async Task JsGetPddAftersale(BuyerLoginInfo buyer, CancellationTokenSource tokenSource)
{
var readBuyer = buyer.buyer_id;
currentReadBuyer = buyer.buyer_id;
buyer.wpf_browser.Load("https://mobile.yangkeduo.com/complaint_list.html?refer_page_name=personal&refer_page_sn=10001&tab=all");
BindBuyerOrderReadInfo(buyer, "正在读取售后");
ShowBuyerOrderReadInfo(buyer, "正在读取售后");
Dispatcher.Invoke(new Action(() =>
{
@@ -1833,7 +1815,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
var frame = cefWebBrowser.GetMainFrame();
if (await IsAftersaleJsInstalledAsync(frame) != true)
{
BindBuyerOrderReadInfo(buyer, "售后单读取预加载失败!");
ShowBuyerOrderReadInfo(buyer, "售后单读取预加载失败!");
return;
}
}
@@ -1843,11 +1825,14 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
while (currentReadBuyer == readBuyer)
{
if (isSkipNext)
{
ShowBuyerOrderReadInfo(buyer, "已跳过当前买手售后读取");
break;
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
@@ -1856,10 +1841,10 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
ShowBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
ShowBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
@@ -1879,7 +1864,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
//string jsStr = $"PDDOrders.trigger({{offset:'MO-01-{lastOrderSN}',type:0,size:10,mode:'store'}})";
string jsStr = "PDAfterSale.trigger({cursor:'" + dicPddAftersaleNextQueryCreatedAt[buyer] + "',tab:'all'})";
await client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true);
await Task.Delay(Randomx.GetId(1000, 3000));
await Task.Delay(Randomx.GetId(2000, 4000));
}
}
@@ -1899,7 +1884,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
{
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(null, "已取消读取");
ShowBuyerOrderReadInfo(null, "已取消读取");
break;
}
Thread.Sleep(500);
@@ -1984,7 +1969,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
Thread.Sleep(Randomx.GetId(2000, 3000));
Dispatcher.Invoke(new Action(() => { MainWindow.Instance.Title = buyer.buyer_nick + " 售后读取中"; }));
BindBuyerOrderReadInfo(buyer, "正在读取售后");
ShowBuyerOrderReadInfo(buyer, "正在读取售后");
top = 0;
times = 0;
@@ -1996,7 +1981,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
@@ -2005,10 +1990,10 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
ShowBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
ShowBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
@@ -2036,7 +2021,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
Thread.Sleep(Randomx.GetId(2000, 3000));
@@ -2064,7 +2049,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
Thread.Sleep(Randomx.GetId(2000, 3000));
Dispatcher.Invoke(new Action(() => { MainWindow.Instance.Title = buyer.buyer_nick + " 待发货读取中"; }));
BindBuyerOrderReadInfo(buyer, "正在读取待发货");
ShowBuyerOrderReadInfo(buyer, "正在读取待发货");
top = 0;
lastCefReadOrderTime = DateTime.Now;
@@ -2075,7 +2060,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
@@ -2084,10 +2069,10 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
ShowBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
ShowBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
@@ -2128,13 +2113,13 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
Thread.Sleep(Randomx.GetId(2000, 3000));
Dispatcher.Invoke(new Action(() => { MainWindow.Instance.Title = buyer.buyer_nick + " 已发货读取中"; }));
BindBuyerOrderReadInfo(buyer, "正在读取已发货");
ShowBuyerOrderReadInfo(buyer, "正在读取已发货");
// 已发货
readBuyer = buyer.buyer_id;
@@ -2165,7 +2150,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
@@ -2174,10 +2159,10 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
PddMobileLoginViewModel.CheckBuyerLogin(new List<BuyerLoginInfo>() { buyer });
if (buyer.status != "在线")
{
BindBuyerOrderReadInfo(buyer, "店铺掉线");
ShowBuyerOrderReadInfo(buyer, "店铺掉线");
break;
}
BindBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
ShowBuyerOrderReadInfo(buyer, "停滞时间超过30秒,跳过");
break;
}
@@ -2210,7 +2195,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
}
if (tokenSource.IsCancellationRequested)
{
BindBuyerOrderReadInfo(buyer, "已取消读取");
ShowBuyerOrderReadInfo(buyer, "已取消读取");
break;
}
}
@@ -2227,11 +2212,11 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls
isReadBuyerOrder = false;
Dispatcher.Invoke(new Action(() => { MainWindow.Instance.Title = "订单读取已结束,等待下次读取"; }));
BindBuyerOrderReadInfo(null, "订单读取已结束,等待下次读取");
ShowBuyerOrderReadInfo(null, "订单读取已结束,等待下次读取");
}, cancellationTokenSource.Token);
}
private void BindBuyerOrderReadInfo(BuyerLoginInfo buyer, string msg = "", List<string> selectIds = null)
private void ShowBuyerOrderReadInfo(BuyerLoginInfo buyer, string msg = "", List<string> selectIds = null)
{
this.LblMsgStr = buyer?.buyer_name + " " + msg + " " + DateTime.Now.ToString("yyMMdd HH:mm:ss");
}