using _29WxOrderWpf.CefHelper;
using CefSharp;
using CefSharp.Handler;
using CefSharp.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Controls;
using Work._29Tools.CefTools;
using Work.BaseForms;
using WxOrder.Framework.Helpers;
namespace _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
public partial class PDDInvoiceViewModel
{
///
/// 内容浏览器
/// 订单详情
/// 发票详情
/// 申请发票
///
public ChromiumWebBrowser BrowserDetail { get; private set; }
partial void InitBrowserDetail()
{
BrowserDetailZIndex = -1;
BrowserDetail = WPFCEFBrowser.CreateChromiumWebBrowser("about:blank", false);
LocalResourceRequestHandler resourceRequestHandler = new LocalResourceRequestHandler();
LocalResourceRequestHandler detailResourceRequestHandler = new LocalResourceRequestHandler();
detailResourceRequestHandler.ResourceLoadCompleteEvent += DetailRequestHandler_ResourceLoadComplete;
BrowserDetail.RequestHandler = new LocalRequestHandler(resourceRequestHandler);
BrowserDetail.LifeSpanHandler = new LocalLifeSpanHandler(PopWindowType.SelfWindow);
BrowserDetail.KeyboardHandler = new KeyboardHandler();
BrowserDetail.LoadingStateChanged += BrowserDetail_LoadingStateChanged;
}
public int BrowserDetailZIndex
{
get => GetValue();
set => SetValue(value);
}
///
/// 显示子浏览器
///
public void ShowOrderBrowserDetail()
{
BrowserZIndex = -1;
BrowserDetailZIndex = 10;
}
public void HidenOrderBrowserDetail()
{
BrowserDetailZIndex = -1;
}
private void BrowserDetail_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/transac_return_compensation.html"))
{
string orderSN = Regex.Match(b.Address, "order_sn=(?\\d+-\\d+)").Groups["sn"].Value;
string html = await b.GetBrowser().GetSourceAsync();
if (html.Contains("window.rawData"))
{
await ExecuteInvoiceApplyScriptAsync(b, orderSN);
}
else
{
// 页面异常(未渲染出发票表单)时直接判定失败,避免批量开票长时间等待
_currentInvoiceTcs?.TrySetResult(false);
}
}
});
}
}
///
/// 注入发票填写脚本并执行。
/// 单张申请模式保持原有行为;批量开票模式下轮询脚本写入的
/// window.__invoiceApplyResult,完成后通过 回传结果。
///
private async Task ExecuteInvoiceApplyScriptAsync(ChromiumWebBrowser b, string orderSn)
{
string content = ResourceHelper.GetResourceText("/Ctrls/PDDInvoice/Resources/invoice.js", "29WxFindOrder");
content = content.Replace("{公司}", Config.Title);
content = content.Replace("{税号}", Config.TaxNo);
if (string.IsNullOrEmpty(content)) return;
await b.EvaluateScriptAsync(content);
if (_currentInvoiceTcs == null)
{
var temp = Orders?.FirstOrDefault(a => a.order_sn == orderSn);
if (temp != null) temp.IsInvoiced = true;
return; // 单张申请模式:保持原有行为
}
// 捕获当前 TCS,避免批量循环超时进入下一个订单后,迟到的轮询误触发新订单的结果
var tcs = _currentInvoiceTcs;
// 检查是否注入成功
if (await IsInstalledDetailAsync(b) == false)
{
IsBatchInvoicing = false;
BaseMsgForm.ShowError("JS错误,开票失败");
tcs.TrySetResult(false);
return;
}
for (int i = 0; i < 120; i++)
{
await Task.Delay(500);
try
{
var res = await b.EvaluateScriptAsync("window.__invoiceApplyResult");
if (res.Success && res.Result != null)
{
tcs.TrySetResult(Convert.ToBoolean(res.Result));
return;
}
}
catch
{
}
}
tcs.TrySetResult(false);
}
public async Task IsInstalledDetailAsync(ChromiumWebBrowser frame, int timeoutMs = 3000)
{
var deadline = DateTime.Now.AddMilliseconds(timeoutMs);
while (DateTime.Now < deadline)
{
var r = await frame.EvaluateScriptAsync("!!(window.InvoiceApply && window.InvoiceApply.__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 void DetailRequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData, IRequest request)
{
if (url.StartsWith("https://mobile.yangkeduo.com/transac_return_compensation.html"))
{
}
}
}