Files
client/ViewModels/LibraryViewModel.cs
2026-05-23 18:16:50 +08:00

154 lines
5.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 CloudPrint.Client.Infrastructure;
using CloudPrint.Client.Models;
using CloudPrint.Client.Services;
using CloudPrint.Client.Services.Abstractions;
using Microsoft.Win32;
namespace CloudPrint.Client.ViewModels;
public sealed class LibraryViewModel : ObservableObject
{
private readonly IFileService _fileService;
private readonly IPrintBackendClient _backendClient;
private readonly ClientSettings _settings;
private LibraryCategory? _selectedCategory;
private CloudPrintDocument? _selectedDocument;
private string _statusMessage = "文库就绪";
public LibraryViewModel()
: this(new FileService(), new GrpcService(), new ClientSettings())
{
}
public LibraryViewModel(IFileService fileService, IPrintBackendClient backendClient, ClientSettings settings)
{
_fileService = fileService;
_backendClient = backendClient;
_settings = settings;
Categories.Add(new LibraryCategory { Id = 1, Name = "教材资料", Icon = "📘", SortOrder = 1 });
Categories.Add(new LibraryCategory { Id = 2, Name = "考试真题", Icon = "📝", SortOrder = 2 });
Categories.Add(new LibraryCategory { Id = 3, Name = "证件照片", Icon = "🖼️", SortOrder = 3 });
Categories.Add(new LibraryCategory { Id = 4, Name = "其他文件", Icon = "📁", SortOrder = 99 });
SelectedCategory = Categories.FirstOrDefault();
AddDocumentCommand = new RelayCommand(AddDocument);
RemoveDocumentCommand = new RelayCommand(RemoveSelectedDocument, () => SelectedDocument is not null);
SyncSelectedCommand = new AsyncRelayCommand(SyncSelectedAsync, () => SelectedDocument is not null && _backendClient.IsConnected);
SyncAllCommand = new AsyncRelayCommand(SyncAllAsync, () => Documents.Any(document => !document.IsUploaded) && _backendClient.IsConnected);
}
public ObservableCollection<LibraryCategory> Categories { get; } = new();
public ObservableCollection<CloudPrintDocument> Documents { get; } = new();
public LibraryCategory? SelectedCategory
{
get => _selectedCategory;
set => SetProperty(ref _selectedCategory, value);
}
public CloudPrintDocument? SelectedDocument
{
get => _selectedDocument;
set
{
if (SetProperty(ref _selectedDocument, value))
{
RemoveDocumentCommand.RaiseCanExecuteChanged();
SyncSelectedCommand.RaiseCanExecuteChanged();
}
}
}
public string StatusMessage
{
get => _statusMessage;
private set => SetProperty(ref _statusMessage, value);
}
public RelayCommand AddDocumentCommand { get; }
public RelayCommand RemoveDocumentCommand { get; }
public AsyncRelayCommand SyncSelectedCommand { get; }
public AsyncRelayCommand SyncAllCommand { get; }
public void RefreshCommandState()
{
SyncSelectedCommand.RaiseCanExecuteChanged();
SyncAllCommand.RaiseCanExecuteChanged();
}
private void AddDocument()
{
var dialog = new Microsoft.Win32.OpenFileDialog
{
Title = "选择要加入文库的文件",
Multiselect = true,
Filter = "支持的文件|*.pdf;*.doc;*.docx;*.txt;*.xls;*.xlsx;*.ppt;*.pptx;*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.zip;*.rar|所有文件|*.*"
};
if (dialog.ShowDialog() != true)
{
return;
}
var addedCount = 0;
var categoryName = SelectedCategory?.Name ?? "未分类";
var limit = Math.Max(1, _settings.MaxUploadSizeMb) * 1024L * 1024L;
foreach (var fileName in dialog.FileNames)
{
var validation = _fileService.ValidateFile(fileName, limit);
if (!validation.IsValid)
{
StatusMessage = $"跳过 {System.IO.Path.GetFileName(fileName)}{validation.Message}";
continue;
}
var document = _fileService.CopyToLibrary(fileName, _settings.LibraryRoot, categoryName, SelectedCategory?.Id ?? 0);
Documents.Insert(0, document);
addedCount++;
}
StatusMessage = addedCount > 0 ? $"已加入 {addedCount} 个文件到文库" : "没有文件被加入文库";
RefreshCommandState();
}
private void RemoveSelectedDocument()
{
if (SelectedDocument is null)
{
return;
}
var document = SelectedDocument;
Documents.Remove(document);
SelectedDocument = null;
StatusMessage = $"已从列表移除:{document.Title}";
RefreshCommandState();
}
private async Task SyncSelectedAsync()
{
if (SelectedDocument is null)
{
return;
}
await _backendClient.UploadLibraryDocumentAsync(SelectedDocument).ConfigureAwait(true);
StatusMessage = $"已同步:{SelectedDocument.Title}";
RefreshCommandState();
}
private async Task SyncAllAsync()
{
var pendingDocuments = Documents.Where(document => !document.IsUploaded).ToList();
foreach (var document in pendingDocuments)
{
await _backendClient.UploadLibraryDocumentAsync(document).ConfigureAwait(true);
}
StatusMessage = $"已同步 {pendingDocuments.Count} 个文库文件";
RefreshCommandState();
}
}