using _29WxOrderWpf.CefHelper; using WxOrder.Framework.Commons; using AllBase; using CefSharp; using CefSharp.Handler; using CefSharp.Wpf; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using Work._29Tools.CefTools; using Work.BaseForms; using WxOrder.Framework.Helpers; namespace _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels; public partial class PDDInvoiceViewModel { /// /// 订单列表浏览器 /// public ChromiumWebBrowser Browser { get; private set; } private IFrame frame; partial void InitBrowser() { BrowserZIndex = -1; Browser = WPFCEFBrowser.CreateChromiumWebBrowser("about:blank", false); LocalResourceRequestHandler resourceRequestHandler = new LocalResourceRequestHandler(); //resourceRequestHandler.BeforeResourceLoadEvent += RequestHandler_BeforeResourceLoad; resourceRequestHandler.ResourceLoadCompleteEvent += RequestHandler_ResourceLoadComplete; Browser.RequestHandler = new LocalRequestHandler(resourceRequestHandler); Browser.LifeSpanHandler = new LocalLifeSpanHandler(PopWindowType.SelfWindow); Browser.KeyboardHandler = new KeyboardHandler(); Browser.LoadingStateChanged += Browser_LoadingStateChanged; } private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e) { if (e.IsLoading == false) { var b = (ChromiumWebBrowser)sender; b.Dispatcher.InvokeAsync(async () => { if (b.Address != null && b.Address.StartsWith("https://mobile.yangkeduo.com/orders.html"))//加载完成 加载 js { frame = b.GetMainFrame(); string content = ResourceHelper.GetResourceText("/Ctrls/PDDInvoice/Resources/order.js", "29WxFindOrder"); if (string.IsNullOrEmpty(content)) return; Install(frame, content); if (await IsInstalledAsync(frame)) { StartAutoScroll(); //await b.EvaluateScriptAsync(frame, content); } else { BaseMsgForm.ShowError("订单读取失败"); } } }); } } public ICommand CloseInvoiceDetailCommand => new DelegateCommand(HidenOrderBrowserDetail); public int BrowserZIndex { get => GetValue(); set => SetValue(value); } /// /// 显示主浏览器 /// public void ShowOrderBrowser() { BrowserZIndex = 10; BrowserDetailZIndex = -1; } public void HidenOrderBrowser() { BrowserZIndex = -1; } public bool IsReadOrder { get => GetValue(); set => SetValue(value); } private int top = 0; private DateTime lastGetOrderDataTime = DateTime.Now; private string lastOrderSN = "0"; private void RequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData, IRequest request) { if (url.StartsWith("https://mobile.yangkeduo.com/proxy/api/api/aristotle/order_list_v")) { lastGetOrderDataTime = DateTime.Now; parserData(responseData, out lastOrderSN); Debug.WriteLine($"LastOrder:{lastOrderSN}"); //File.WriteAllText(@$"E:\{Guid.NewGuid().ToString()}.txt", responseData); } } public void StartAutoScroll() { if (frame == null) { StopAutoScroll(); return; } if (IsReadOrder) return; IsReadOrder = true; //_ = autoScroll(_cancellationTokenSource.Token); _ = autoLoadOrderData(_cancellationTokenSource.Token); } // 停止滚动 public void StopAutoScroll() { IsReadOrder = false; _cancellationTokenSource?.Cancel(); Application.Current?.Dispatcher.BeginInvoke(new Action(() => { BottomMsg = $"订单读取结束"; })); CompleteProgress(); } private async Task autoLoadOrderData(CancellationToken token) { string templastOrderSN = ""; while (IsReadOrder && !token.IsCancellationRequested) { if (lastOrderSN == templastOrderSN) { await Task.Delay(500); continue; } string jsStr = $"PDDOrders.trigger({{offset:'MO-01-{lastOrderSN}',type:0,size:10,mode:'store'}})"; templastOrderSN = lastOrderSN; await frame.EvaluateScriptAsync(jsStr); await Task.Delay(Randomx.GetId(1000, 3000)); //Thread.Sleep(); } } /// 文档创建时注入(每个 document 注入一次即可,脚本本身幂等) public void Install(IFrame frame, string hookJs) { if (frame == null || string.IsNullOrEmpty(hookJs)) return; frame.ExecuteJavaScriptAsync(hookJs); } /// 脚本是否已就绪(注入后自检用;异步,不会卡 UI 线程) public async Task 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; } //private async Task autoScroll(CancellationToken token) //{ // while (IsReadOrder && !token.IsCancellationRequested) // { // if ((DateTime.Now - lastGetOrderDataTime).Seconds > 30) StopAutoScroll(); // top += Randomx.GetId(450, 600); // var jsStr = @"window.scroll({ // top: " + top + @", // left: 0, // behavior: 'smooth' // 可选,使滚动平滑 // });"; // var client = Browser.GetDevToolsClient(); // if (client != null) // { // var result = client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true); // result.Wait(5000); // } // await Task.Delay(Randomx.GetId(100, 300)); // //Thread.Sleep(); // } //} }