Files
client/ViewModels/LibraryViewModel.cs

140 lines
4.8 KiB
C#
Raw Normal View History

2026-05-23 18:16:50 +08:00
using System.Collections.ObjectModel;
using CloudPrint.Client.Models;
using CloudPrint.Client.Services;
using CloudPrint.Client.Services.Abstractions;
2026-05-28 23:26:37 +08:00
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
2026-05-23 18:16:50 +08:00
using Microsoft.Win32;
namespace CloudPrint.Client.ViewModels;
2026-05-28 23:26:37 +08:00
public sealed partial class LibraryViewModel : ObservableObject
2026-05-23 18:16:50 +08:00
{
private readonly IFileService _fileService;
private readonly IPrintBackendClient _backendClient;
private readonly ClientSettings _settings;
2026-05-28 23:26:37 +08:00
[ObservableProperty]
private LibraryCategory? selectedCategory;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RemoveDocumentCommand))]
[NotifyCanExecuteChangedFor(nameof(SyncSelectedCommand))]
private CloudPrintDocument? selectedDocument;
[ObservableProperty]
private string statusMessage = "文库就绪";
2026-05-23 18:16:50 +08:00
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();
}
public ObservableCollection<LibraryCategory> Categories { get; } = new();
public ObservableCollection<CloudPrintDocument> Documents { get; } = new();
public void RefreshCommandState()
{
2026-05-28 23:26:37 +08:00
SyncSelectedCommand.NotifyCanExecuteChanged();
SyncAllCommand.NotifyCanExecuteChanged();
2026-05-23 18:16:50 +08:00
}
2026-05-28 23:26:37 +08:00
[RelayCommand]
2026-05-23 18:16:50 +08:00
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();
}
2026-05-28 23:26:37 +08:00
private bool CanRemoveDocument() => SelectedDocument is not null;
[RelayCommand(CanExecute = nameof(CanRemoveDocument))]
private void RemoveDocument()
2026-05-23 18:16:50 +08:00
{
if (SelectedDocument is null)
{
return;
}
var document = SelectedDocument;
Documents.Remove(document);
SelectedDocument = null;
StatusMessage = $"已从列表移除:{document.Title}";
RefreshCommandState();
}
2026-05-28 23:26:37 +08:00
private bool CanSyncSelected() => SelectedDocument is not null && _backendClient.IsConnected;
[RelayCommand(CanExecute = nameof(CanSyncSelected))]
2026-05-23 18:16:50 +08:00
private async Task SyncSelectedAsync()
{
if (SelectedDocument is null)
{
return;
}
await _backendClient.UploadLibraryDocumentAsync(SelectedDocument).ConfigureAwait(true);
StatusMessage = $"已同步:{SelectedDocument.Title}";
RefreshCommandState();
}
2026-05-28 23:26:37 +08:00
private bool CanSyncAll() => Documents.Any(document => !document.IsUploaded) && _backendClient.IsConnected;
[RelayCommand(CanExecute = nameof(CanSyncAll))]
2026-05-23 18:16:50 +08:00
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();
}
2026-05-28 23:26:37 +08:00
}