210 lines
6.5 KiB
C#
210 lines
6.5 KiB
C#
using FATrace.WPLApp.Core;
|
||
using FATrace.WPLApp.Services;
|
||
using Prism.Commands;
|
||
using System;
|
||
using System.Collections.ObjectModel;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
|
||
namespace FATrace.WPLApp.ViewModels
|
||
{
|
||
/// <summary>
|
||
/// 使用手册(PDF)查看页 VM
|
||
/// </summary>
|
||
public class HelpManualViewModel : NavigationViewModel
|
||
{
|
||
private readonly ILogService _log;
|
||
|
||
public HelpManualViewModel(ILogService log)
|
||
{
|
||
_log = log;
|
||
|
||
PdfFiles = new ObservableCollection<PdfFileItem>();
|
||
RefreshCommand = new DelegateCommand(async () => await LoadReportPdfsAsync(), () => !IsBusy)
|
||
.ObservesProperty(() => IsBusy);
|
||
}
|
||
|
||
private bool _isBusy;
|
||
/// <summary>
|
||
/// 是否忙碌(用于提示与禁用按钮)
|
||
/// </summary>
|
||
public bool IsBusy
|
||
{
|
||
get => _isBusy;
|
||
set { _isBusy = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private string? _statusText;
|
||
/// <summary>
|
||
/// 页面状态文本(例如:未找到PDF)
|
||
/// </summary>
|
||
public string? StatusText
|
||
{
|
||
get => _statusText;
|
||
set { _statusText = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Report 目录下的 PDF 文件列表
|
||
/// </summary>
|
||
public ObservableCollection<PdfFileItem> PdfFiles { get; }
|
||
|
||
private PdfFileItem? _selectedPdf;
|
||
/// <summary>
|
||
/// 当前选择的 PDF
|
||
/// </summary>
|
||
public PdfFileItem? SelectedPdf
|
||
{
|
||
get => _selectedPdf;
|
||
set
|
||
{
|
||
_selectedPdf = value;
|
||
RaisePropertyChanged();
|
||
PdfFilePath = _selectedPdf?.FullPath;
|
||
}
|
||
}
|
||
|
||
private string? _pdfFilePath;
|
||
/// <summary>
|
||
/// 当前打开的 PDF 文件路径(绑定到 Syncfusion PdfViewerControl.ItemSource)
|
||
/// </summary>
|
||
public string? PdfFilePath
|
||
{
|
||
get => _pdfFilePath;
|
||
set { _pdfFilePath = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 刷新/重新扫描 PDF 文件
|
||
/// </summary>
|
||
public DelegateCommand RefreshCommand { get; }
|
||
|
||
/// <summary>
|
||
/// 获取运行目录下 Report 文件夹绝对路径
|
||
/// </summary>
|
||
/// <returns>Report 文件夹绝对路径</returns>
|
||
private string GetReportFolder()
|
||
{
|
||
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||
var folder = Path.Combine(baseDir, "Report");
|
||
try
|
||
{
|
||
if (!Directory.Exists(folder))
|
||
{
|
||
Directory.CreateDirectory(folder);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_log.Error($"HelpManual: 创建Report目录失败: {ex}");
|
||
}
|
||
return folder;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 扫描 Report 目录并加载 PDF 列表(默认打开第一个)
|
||
/// </summary>
|
||
/// <returns>Task</returns>
|
||
private async Task LoadReportPdfsAsync()
|
||
{
|
||
if (IsBusy) return;
|
||
try
|
||
{
|
||
IsBusy = true;
|
||
StatusText = string.Empty;
|
||
|
||
var folder = GetReportFolder();
|
||
_log.Info($"HelpManual: 扫描PDF目录: {folder}");
|
||
|
||
var list = await Task.Run(() =>
|
||
{
|
||
if (!Directory.Exists(folder))
|
||
return Array.Empty<PdfFileItem>();
|
||
|
||
var files = Directory.GetFiles(folder, "*.pdf", SearchOption.TopDirectoryOnly)
|
||
.Select(p => new PdfFileItem(Path.GetFileName(p), p))
|
||
.OrderByDescending(a => a.FileName)
|
||
.ToArray();
|
||
|
||
return files;
|
||
});
|
||
|
||
Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
PdfFiles.Clear();
|
||
foreach (var f in list) PdfFiles.Add(f);
|
||
|
||
if (PdfFiles.Count == 0)
|
||
{
|
||
SelectedPdf = null;
|
||
PdfFilePath = null;
|
||
StatusText = "未在程序目录下的 Report 文件夹找到 PDF 文件,请将手册PDF放入该目录后点击【刷新】。";
|
||
return;
|
||
}
|
||
|
||
// 保持原选择(若仍存在),否则默认第一个
|
||
var keep = SelectedPdf != null
|
||
? PdfFiles.FirstOrDefault(a => string.Equals(a.FullPath, SelectedPdf.FullPath, StringComparison.OrdinalIgnoreCase))
|
||
: null;
|
||
|
||
SelectedPdf = keep ?? PdfFiles[0];
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_log.Error($"HelpManual: 扫描/加载PDF失败: {ex}");
|
||
StatusText = $"加载PDF失败: {ex.Message}";
|
||
MessageBox.Show($"加载PDF失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
finally
|
||
{
|
||
IsBusy = false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 页面导航进入时自动加载
|
||
/// </summary>
|
||
/// <param name="navigationContext">导航上下文</param>
|
||
public override async void OnNavigatedTo(Prism.Regions.NavigationContext navigationContext)
|
||
{
|
||
await LoadReportPdfsAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// PDF 文件下拉项
|
||
/// </summary>
|
||
public class PdfFileItem
|
||
{
|
||
/// <summary>
|
||
/// 构造
|
||
/// </summary>
|
||
/// <param name="fileName">文件名</param>
|
||
/// <param name="fullPath">完整路径</param>
|
||
public PdfFileItem(string fileName, string fullPath)
|
||
{
|
||
FileName = fileName;
|
||
FullPath = fullPath;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 文件名
|
||
/// </summary>
|
||
public string FileName { get; }
|
||
|
||
/// <summary>
|
||
/// 完整路径
|
||
/// </summary>
|
||
public string FullPath { get; }
|
||
|
||
/// <summary>
|
||
/// 用于下拉显示
|
||
/// </summary>
|
||
/// <returns>文件名</returns>
|
||
public override string ToString() => FileName;
|
||
}
|
||
}
|
||
}
|