154 lines
5.3 KiB
C#
154 lines
5.3 KiB
C#
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();
|
||
}
|
||
} |