增强打印预览功能,新增离线打印功能,新增缩放控制按钮以提升用户体验。优化打印数据准备逻辑,支持实时预览缩放,确保打印效果的一致性。同时,重构相关视图和服务以增强系统的可维护性和扩展性。
This commit is contained in:
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration;
|
||||
using YY.Admin.Core.Helper;
|
||||
using YY.Admin.Core.Session;
|
||||
using YY.Admin.FluentValidation;
|
||||
using YY.Admin.Helper;
|
||||
using YY.Admin.Services;
|
||||
using YY.Admin.Services.Service.Auth;
|
||||
using YY.Admin.Services.Service.Jeecg;
|
||||
@@ -220,6 +221,31 @@ namespace YY.Admin.ViewModels
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
bool connected = false;
|
||||
var settings = ServerSettingsStore.Load();
|
||||
if (settings.DisconnectConnection)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
IsBackendConnected = false;
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略窗口关闭后的调度异常
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(ConnectivityCheckIntervalSeconds), cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 每轮都重新读取配置,保存服务器设置后可即时生效
|
||||
@@ -269,6 +295,11 @@ namespace YY.Admin.ViewModels
|
||||
{
|
||||
if (r.Result == ButtonResult.OK)
|
||||
{
|
||||
var settings = ServerSettingsStore.Load();
|
||||
if (settings.DisconnectConnection)
|
||||
{
|
||||
IsBackendConnected = false;
|
||||
}
|
||||
LoginMessage = "服务器配置已保存";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -108,6 +108,9 @@ public class RawMaterialEntryOperationViewModel : RawMaterialEntryEditDialogView
|
||||
public DelegateCommand ResplitCommand { get; }
|
||||
public DelegateCommand SaveAndPrintCommand { get; }
|
||||
public DelegateCommand RefreshPrintersCommand { get; }
|
||||
public DelegateCommand ZoomOutPrintPreviewCommand { get; }
|
||||
public DelegateCommand ZoomInPrintPreviewCommand { get; }
|
||||
public DelegateCommand ResetPrintPreviewZoomCommand { get; }
|
||||
|
||||
/// <summary>PrintDot 桥接器返回的打印机列表(与打印模板页一致)。</summary>
|
||||
public ObservableCollection<PrintDotPrinter> Printers { get; } = new();
|
||||
@@ -169,6 +172,27 @@ public class RawMaterialEntryOperationViewModel : RawMaterialEntryEditDialogView
|
||||
private set => SetProperty(ref _printPreviewStatus, value);
|
||||
}
|
||||
|
||||
private const double PrintPreviewMinZoom = 0.5d;
|
||||
private const double PrintPreviewMaxZoom = 2.0d;
|
||||
private const double PrintPreviewDefaultZoom = 0.7d;
|
||||
private const double PrintPreviewZoomStep = 0.1d;
|
||||
|
||||
private double _printPreviewZoomFactor = PrintPreviewDefaultZoom;
|
||||
/// <summary>打印预览缩放倍率(WebView2 ZoomFactor)。</summary>
|
||||
public double PrintPreviewZoomFactor
|
||||
{
|
||||
get => _printPreviewZoomFactor;
|
||||
set
|
||||
{
|
||||
var clamped = Math.Round(Math.Clamp(value, PrintPreviewMinZoom, PrintPreviewMaxZoom), 2);
|
||||
if (!SetProperty(ref _printPreviewZoomFactor, clamped)) return;
|
||||
RaisePropertyChanged(nameof(PrintPreviewZoomText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>打印预览缩放显示文本(百分比)。</summary>
|
||||
public string PrintPreviewZoomText => $"{Math.Round(PrintPreviewZoomFactor * 100):0}%";
|
||||
|
||||
/// <summary>由 View 订阅,在 UI 线程将 HTML 交给 WebView2。</summary>
|
||||
public event EventHandler<string>? PrintPreviewHtmlReady;
|
||||
|
||||
@@ -220,6 +244,9 @@ public class RawMaterialEntryOperationViewModel : RawMaterialEntryEditDialogView
|
||||
.ObservesProperty(() => Entry);
|
||||
SaveAndPrintCommand = new DelegateCommand(async () => await SaveAndPrintAsync());
|
||||
RefreshPrintersCommand = new DelegateCommand(async () => await RefreshPrintersAsync(verbose: true));
|
||||
ZoomOutPrintPreviewCommand = new DelegateCommand(() => PrintPreviewZoomFactor -= PrintPreviewZoomStep);
|
||||
ZoomInPrintPreviewCommand = new DelegateCommand(() => PrintPreviewZoomFactor += PrintPreviewZoomStep);
|
||||
ResetPrintPreviewZoomCommand = new DelegateCommand(() => PrintPreviewZoomFactor = PrintPreviewDefaultZoom);
|
||||
// 集合变化:批量重订阅 item.PropertyChanged 监听 HasCard/Portions,并同步刷新两个 Can*。
|
||||
SplitCodeDetails.CollectionChanged += OnSplitCodeDetailsCollectionChangedForCanFlags;
|
||||
_ = RefreshPrintersAsync(verbose: false);
|
||||
@@ -808,7 +835,8 @@ public class RawMaterialEntryOperationViewModel : RawMaterialEntryEditDialogView
|
||||
string html;
|
||||
try
|
||||
{
|
||||
html = NativePrintRenderService.RenderToHtml(_previewTemplateJson, dataObj);
|
||||
// 实时预览关闭模板内部 fitPage 自适应,避免与 WebView2 外层缩放叠加后出现“越放大越小”。
|
||||
html = NativePrintRenderService.RenderToHtml(_previewTemplateJson, dataObj, enableScreenAutoFit: false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1057,42 +1057,76 @@
|
||||
Margin="8,0,10,0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource SecondaryTextBrush}"/>
|
||||
<ToggleButton Grid.Column="2"
|
||||
IsChecked="{Binding IsPrintPreviewExpanded, Mode=TwoWay}"
|
||||
MinWidth="56"
|
||||
Height="24"
|
||||
Background="Transparent"
|
||||
BorderThickness="1"
|
||||
Padding="8,0"
|
||||
FocusVisualStyle="{x:Null}"
|
||||
Cursor="Hand"
|
||||
VerticalAlignment="Center">
|
||||
<ToggleButton.Template>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="2"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</ToggleButton.Template>
|
||||
<TextBlock FontSize="12"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="展开"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=ToggleButton}}" Value="True">
|
||||
<Setter Property="Text" Value="折叠"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</ToggleButton>
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding IsPrintPreviewExpanded, Converter={StaticResource Boolean2VisibilityConverter}}">
|
||||
<Button Content="-"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Padding="0"
|
||||
FontSize="12"
|
||||
Command="{Binding ZoomOutPrintPreviewCommand}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
ToolTip="缩小预览"/>
|
||||
<Button Content="{Binding PrintPreviewZoomText}"
|
||||
MinWidth="56"
|
||||
Height="24"
|
||||
Margin="4,0,4,0"
|
||||
Padding="10,0"
|
||||
FontSize="11"
|
||||
Command="{Binding ResetPrintPreviewZoomCommand}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
ToolTip="重置为 70%"/>
|
||||
<Button Content="+"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Padding="0"
|
||||
FontSize="12"
|
||||
Command="{Binding ZoomInPrintPreviewCommand}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
ToolTip="放大预览"/>
|
||||
</StackPanel>
|
||||
<ToggleButton IsChecked="{Binding IsPrintPreviewExpanded, Mode=TwoWay}"
|
||||
MinWidth="56"
|
||||
Height="24"
|
||||
Background="Transparent"
|
||||
BorderThickness="1"
|
||||
Padding="8,0"
|
||||
FocusVisualStyle="{x:Null}"
|
||||
Cursor="Hand"
|
||||
VerticalAlignment="Center">
|
||||
<ToggleButton.Template>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="2"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</ToggleButton.Template>
|
||||
<TextBlock FontSize="12"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="展开"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=ToggleButton}}" Value="True">
|
||||
<Setter Property="Text" Value="折叠"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border BorderBrush="{DynamicResource BorderBrush}"
|
||||
|
||||
@@ -49,10 +49,22 @@ public partial class RawMaterialEntryOperationView : UserControl
|
||||
// null/空 表示“所有属性”通知(Prism/BindableBase 批量刷新时),需同步分割布局
|
||||
if (!string.IsNullOrEmpty(e.PropertyName)
|
||||
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.IsRightPanelExpanded)
|
||||
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth))
|
||||
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth)
|
||||
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.PrintPreviewZoomFactor))
|
||||
return;
|
||||
|
||||
_ = Dispatcher.InvokeAsync(ApplySplitLayout);
|
||||
if (string.IsNullOrEmpty(e.PropertyName)
|
||||
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.IsRightPanelExpanded)
|
||||
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth))
|
||||
{
|
||||
_ = Dispatcher.InvokeAsync(ApplySplitLayout);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(e.PropertyName)
|
||||
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.PrintPreviewZoomFactor))
|
||||
{
|
||||
_ = Dispatcher.InvokeAsync(ApplyPrintPreviewZoom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>按钮 Click 在 Command 之后执行,用于兜底刷新列宽(不重复切换状态)。</summary>
|
||||
@@ -66,6 +78,7 @@ public partial class RawMaterialEntryOperationView : UserControl
|
||||
EnsureVmAttached();
|
||||
|
||||
ApplySplitLayout();
|
||||
ApplyPrintPreviewZoom();
|
||||
|
||||
if (DataContext is RawMaterialEntryOperationViewModel vm && !_initialized)
|
||||
{
|
||||
@@ -92,6 +105,7 @@ public partial class RawMaterialEntryOperationView : UserControl
|
||||
try
|
||||
{
|
||||
await PrintPreviewWebView.EnsureCoreWebView2Async();
|
||||
ApplyPrintPreviewZoom();
|
||||
PrintPreviewWebView.NavigateToString(html ?? string.Empty);
|
||||
}
|
||||
catch
|
||||
@@ -100,6 +114,15 @@ public partial class RawMaterialEntryOperationView : UserControl
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyPrintPreviewZoom()
|
||||
{
|
||||
var vm = _vm ?? DataContext as RawMaterialEntryOperationViewModel;
|
||||
if (vm == null) return;
|
||||
if (PrintPreviewWebView?.CoreWebView2 == null) return;
|
||||
// 实时预览已关闭 HTML 内部 fitPage,自定义缩放直接映射到 WebView2 即可(+ 放大,- 缩小)。
|
||||
PrintPreviewWebView.ZoomFactor = vm.PrintPreviewZoomFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ViewModel 同步右侧栏与分割条:展开时使用持久化宽度;折叠时右栏与分割条占宽均为 0(完全隐藏)。
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user