Files
qhmes/yy-admin-master/YY.Admin/ViewModels/Print/PrintTemplateListViewModel.cs

278 lines
9.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.ObjectModel;
using System.Windows;
using Prism.Commands;
using Prism.Events;
using YY.Admin.Core;
using YY.Admin.Core.Entity;
using YY.Admin.Core.Events;
using YY.Admin.Core.Services;
using YY.Admin.Services.Service.Print;
using YY.Admin.Views.Print;
namespace YY.Admin.ViewModels.Print;
public class PrintTemplateListViewModel : BaseViewModel
{
private readonly IPrintTemplateService _printTemplateService;
private readonly IPrintDotService _printDotService;
private readonly IEventAggregator _eventAggregator;
private SubscriptionToken? _changeToken;
private List<PrintTemplate> _allTemplates = new();
public ObservableCollection<PrintTemplate> Templates { get; } = new();
// ── PrintDot 打印机选择 ────────────────────────────────────────────────
public ObservableCollection<PrintDotPrinter> Printers { get; } = new();
private bool _suppressPrinterSave;
private PrintDotPrinter? _selectedPrinter;
public PrintDotPrinter? SelectedPrinter
{
get => _selectedPrinter;
set
{
if (!SetProperty(ref _selectedPrinter, value)) return;
if (_suppressPrinterSave) return;
// 持久化用户选择,预览窗口和后续会话使用
var s = PrintDotSettings.Load();
s.SelectedPrinter = value?.Name ?? string.Empty;
s.Save();
}
}
private string _printerStatus = string.Empty;
public string PrinterStatus
{
get => _printerStatus;
set => SetProperty(ref _printerStatus, value);
}
private string _statusMessage = string.Empty;
public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}
private string? _filterCode;
public string? FilterCode
{
get => _filterCode;
set => SetProperty(ref _filterCode, value);
}
private string? _filterName;
public string? FilterName
{
get => _filterName;
set => SetProperty(ref _filterName, value);
}
private string? _filterCategory;
public string? FilterCategory
{
get => _filterCategory;
set => SetProperty(ref _filterCategory, value);
}
public DelegateCommand SearchCommand { get; }
public DelegateCommand ResetCommand { get; }
public DelegateCommand<PrintTemplate> PreviewCommand { get; }
public DelegateCommand RefreshPrintersCommand { get; }
public PrintTemplateListViewModel(
IPrintTemplateService printTemplateService,
IPrintDotService printDotService,
IEventAggregator eventAggregator,
IContainerExtension container,
IRegionManager regionManager) : base(container, regionManager)
{
_printTemplateService = printTemplateService;
_printDotService = printDotService;
_eventAggregator = eventAggregator;
SearchCommand = new DelegateCommand(ApplyFilter);
PreviewCommand = new DelegateCommand<PrintTemplate>(ShowPreview);
ResetCommand = new DelegateCommand(() =>
{
FilterCode = null;
FilterName = null;
FilterCategory = null;
ApplyFilter();
});
RefreshPrintersCommand = new DelegateCommand(async () => await RefreshPrintersAsync(verbose: true));
_changeToken = _eventAggregator
.GetEvent<PrintTemplateChangedEvent>()
.Subscribe(_ => { RefreshSilentlyAsync().ConfigureAwait(false); }, ThreadOption.UIThread);
// 先用缓存立即填充,再后台静默刷新
ShowCached();
_ = RefreshSilentlyAsync();
// 后台静默连接 PrintDot 桥接器,初次加载打印机
_ = RefreshPrintersAsync(verbose: false);
}
/// <summary>
/// 通过 PrintDot 桥接器拉取打印机列表,与后端 web 列表页的 fetchPrintDotPrinters 行为对齐。
/// </summary>
private async Task RefreshPrintersAsync(bool verbose)
{
if (verbose) PrinterStatus = "刷新打印机中...";
var savedName = PrintDotSettings.Load().SelectedPrinter;
try
{
var list = await _printDotService.GetPrintersAsync();
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
Printers.Clear();
foreach (var p in list) Printers.Add(p);
// 选中规则:上次保存 > 系统默认 > 首台
var match = list.FirstOrDefault(p => p.Name == savedName)
?? list.FirstOrDefault(p => p.IsDefault)
?? (list.Count > 0 ? list[0] : null);
_suppressPrinterSave = true;
SelectedPrinter = match;
_suppressPrinterSave = false;
PrinterStatus = list.Count > 0 ? $"共 {list.Count} 台打印机" : "未检测到打印机";
});
}
catch (Exception ex)
{
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
Printers.Clear();
_suppressPrinterSave = true;
SelectedPrinter = null;
_suppressPrinterSave = false;
PrinterStatus = verbose
? $"PrintDot 未连接:{ex.Message}"
: "PrintDot 未连接";
});
}
}
private void ShowCached()
{
var cached = _printTemplateService.GetCached();
if (cached.Count == 0) return;
_allTemplates = cached.ToList();
ApplyFilter();
UpdateStatus();
}
private async Task RefreshSilentlyAsync()
{
try
{
var list = await _printTemplateService.RefreshCacheAsync().ConfigureAwait(false);
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
_allTemplates = list.ToList();
ApplyFilter();
UpdateStatus();
});
}
catch
{
// 静默失败:保留当前缓存内容不动,不显示错误
var cached = _printTemplateService.GetCached();
if (cached.Count > 0 && _allTemplates.Count == 0)
{
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
_allTemplates = cached.ToList();
ApplyFilter();
UpdateStatus();
});
}
}
}
private void ApplyFilter()
{
IEnumerable<PrintTemplate> result = _allTemplates;
if (!string.IsNullOrWhiteSpace(FilterCode))
result = result.Where(t => (t.TemplateCode ?? string.Empty)
.Contains(FilterCode, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(FilterName))
result = result.Where(t => (t.TemplateName ?? string.Empty)
.Contains(FilterName, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(FilterCategory))
result = result.Where(t => (t.Category ?? string.Empty)
.Contains(FilterCategory, StringComparison.OrdinalIgnoreCase));
var filtered = result.ToList();
// 原地差量更新,避免滚动位置重置和闪烁
for (int i = Templates.Count - 1; i >= 0; i--)
{
if (!filtered.Any(t => t.Id == Templates[i].Id))
Templates.RemoveAt(i);
}
for (int i = 0; i < filtered.Count; i++)
{
var item = filtered[i];
var existingIdx = -1;
for (int j = 0; j < Templates.Count; j++)
{
if (Templates[j].Id == item.Id) { existingIdx = j; break; }
}
if (existingIdx < 0)
Templates.Insert(i, item);
else
{
if (existingIdx != i) Templates.Move(existingIdx, i);
Templates[i] = item;
}
}
}
private void UpdateStatus()
{
var hasFilter = !string.IsNullOrWhiteSpace(FilterCode)
|| !string.IsNullOrWhiteSpace(FilterName)
|| !string.IsNullOrWhiteSpace(FilterCategory);
StatusMessage = hasFilter
? $"筛选结果 {Templates.Count} / {_allTemplates.Count} 个"
: _allTemplates.Count > 0
? $"共 {_allTemplates.Count} 个模板"
: "暂无模板";
}
private void ShowPreview(PrintTemplate template)
{
if (template == null) return;
ShowPreviewAsync(template);
}
private async Task ShowPreviewAsync(PrintTemplate template)
{
// 列表缓存可能不含 templateJson大字段按需通过 queryByCode 单独拉取
var json = template.TemplateJson;
if (string.IsNullOrWhiteSpace(json) || json == "{}")
{
try
{
var full = await _printTemplateService.GetByCodeAsync(template.TemplateCode ?? "");
json = full?.TemplateJson;
}
catch { /* 保持 json 为 null预览窗口显示"尚未设计" */ }
}
var win = new PrintPreviewWindow(template, json, _printDotService, SelectedPrinter?.Name)
{
Owner = Application.Current.MainWindow
};
win.Show();
}
}