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 _allTemplates = new(); public ObservableCollection Templates { get; } = new(); // ── PrintDot 打印机选择 ──────────────────────────────────────────────── public ObservableCollection 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 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(ShowPreview); ResetCommand = new DelegateCommand(() => { FilterCode = null; FilterName = null; FilterCategory = null; ApplyFilter(); }); RefreshPrintersCommand = new DelegateCommand(async () => await RefreshPrintersAsync(verbose: true)); _changeToken = _eventAggregator .GetEvent() .Subscribe(_ => { RefreshSilentlyAsync().ConfigureAwait(false); }, ThreadOption.UIThread); // 先用缓存立即填充,再后台静默刷新 ShowCached(); _ = RefreshSilentlyAsync(); // 后台静默连接 PrintDot 桥接器,初次加载打印机 _ = RefreshPrintersAsync(verbose: false); } /// /// 通过 PrintDot 桥接器拉取打印机列表,与后端 web 列表页的 fetchPrintDotPrinters 行为对齐。 /// 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 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(); } }