新增打印模板管理功能,包含免密接口和实时通知机制,支持桌面端打印模板的查询和列表展示。更新相关控制器、服务和视图,优化用户体验并增强系统的实时数据同步能力。
This commit is contained in:
@@ -162,6 +162,10 @@ public class StompWebSocketService : ISignalRService
|
||||
await SendFrameAsync(
|
||||
BuildSubscribeFrame("sub-mes-warehouse-areas", "/topic/sync/mes-warehouse-areas"),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
// 打印模板变更:订阅 /topic/sync/print-templates
|
||||
await SendFrameAsync(
|
||||
BuildSubscribeFrame("sub-print-templates", "/topic/sync/print-templates"),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 订阅服务端 PONG 回复(应用层假在线检测)
|
||||
await SendFrameAsync(
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
|
||||
namespace YY.Admin.Infrastructure.Print;
|
||||
|
||||
/// <summary>
|
||||
/// 使用隐藏 WebView2 窗口将 HTML 字符串渲染为 PDF base64。
|
||||
/// 所有调用必须最终在 WPF UI 线程执行,由内部 Dispatcher 保证。
|
||||
/// </summary>
|
||||
public static class HtmlToPdfRenderer
|
||||
{
|
||||
public static Task<string> RenderAsync(string html, double widthMm = 210, double heightMm = 297)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await RenderOnUiThreadAsync(html, widthMm, heightMm);
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
});
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private static async Task<string> RenderOnUiThreadAsync(string html, double widthMm, double heightMm)
|
||||
{
|
||||
var tempHtml = Path.ChangeExtension(Path.GetTempFileName(), ".html");
|
||||
var tempPdf = Path.ChangeExtension(Path.GetTempFileName(), ".pdf");
|
||||
Window? win = null;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(tempHtml, html, Encoding.UTF8);
|
||||
|
||||
var env = await CoreWebView2Environment.CreateAsync();
|
||||
var wv = new WebView2();
|
||||
|
||||
win = new Window
|
||||
{
|
||||
Width = 1,
|
||||
Height = 1,
|
||||
Left = -99999,
|
||||
Top = -99999,
|
||||
ShowInTaskbar = false,
|
||||
WindowStyle = WindowStyle.None,
|
||||
Visibility = Visibility.Visible
|
||||
};
|
||||
win.Content = wv;
|
||||
win.Show();
|
||||
|
||||
await wv.EnsureCoreWebView2Async(env);
|
||||
|
||||
var navTcs = new TaskCompletionSource();
|
||||
wv.CoreWebView2.NavigationCompleted += (_, _) => navTcs.TrySetResult();
|
||||
wv.CoreWebView2.Navigate(new Uri(tempHtml).AbsoluteUri);
|
||||
await navTcs.Task;
|
||||
|
||||
// 短暂等待 JS/CSS 完成渲染
|
||||
await Task.Delay(200);
|
||||
|
||||
var settings = env.CreatePrintSettings();
|
||||
settings.PageWidth = widthMm / 25.4;
|
||||
settings.PageHeight = heightMm / 25.4;
|
||||
settings.MarginTop = 0;
|
||||
settings.MarginBottom = 0;
|
||||
settings.MarginLeft = 0;
|
||||
settings.MarginRight = 0;
|
||||
settings.ShouldPrintHeaderAndFooter = false;
|
||||
settings.ShouldPrintBackgrounds = true;
|
||||
|
||||
await wv.CoreWebView2.PrintToPdfAsync(tempPdf, settings);
|
||||
|
||||
var pdfBytes = File.ReadAllBytes(tempPdf);
|
||||
return Convert.ToBase64String(pdfBytes);
|
||||
}
|
||||
finally
|
||||
{
|
||||
win?.Close();
|
||||
try { File.Delete(tempHtml); } catch { }
|
||||
try { File.Delete(tempPdf); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user