using CloudPrint.Client.Models; using CloudPrint.Client.Infrastructure; using CloudPrint.Client.Services; using CloudPrint.Client.Services.Abstractions; using System.IO; namespace CloudPrint.Client.ViewModels; public sealed class SettingsViewModel : ObservableObject { private readonly ISettingsService _settingsService; private readonly IPrintBackendClient _backendClient; private readonly IAppLogger _appLogger; private string _statusMessage = "设置就绪"; private string _adminPassword = string.Empty; public SettingsViewModel() : this(new JsonSettingsService().Load(), new JsonSettingsService(), new GrpcService(), new FileAppLogger()) { } public SettingsViewModel(ClientSettings settings, ISettingsService settingsService, IPrintBackendClient backendClient, IAppLogger appLogger) { Settings = settings; _settingsService = settingsService; _backendClient = backendClient; _appLogger = appLogger; SaveCommand = new RelayCommand(Save); SelectLibraryRootCommand = new RelayCommand(SelectLibraryRoot); LoginAdminCommand = new AsyncRelayCommand(LoginAdminAsync); LogoutAdminCommand = new RelayCommand(LogoutAdmin, () => IsAdminLoggedIn); OpenLogDirectoryCommand = new RelayCommand(OpenLogDirectory); if (!string.IsNullOrWhiteSpace(Settings.AdminAccessToken)) { _backendClient.SetAdminToken(Settings.AdminUsername, Settings.AdminAccessToken); IsAdminLoggedIn = true; } } public ClientSettings Settings { get; } public string StatusMessage { get => _statusMessage; private set => SetProperty(ref _statusMessage, value); } public RelayCommand SaveCommand { get; } public RelayCommand SelectLibraryRootCommand { get; } public AsyncRelayCommand LoginAdminCommand { get; } public RelayCommand LogoutAdminCommand { get; } public RelayCommand OpenLogDirectoryCommand { get; } public string LogDirectory => _appLogger.LogDirectory; private bool _isAdminLoggedIn; public bool IsAdminLoggedIn { get => _isAdminLoggedIn; private set { if (SetProperty(ref _isAdminLoggedIn, value)) { OnPropertyChanged(nameof(AdminLoginStatus)); LogoutAdminCommand.RaiseCanExecuteChanged(); } } } public string AdminLoginStatus => IsAdminLoggedIn ? $"已登录:{Settings.AdminUsername}" : "未登录"; public string AdminPassword { get => _adminPassword; set => SetProperty(ref _adminPassword, value); } private void Save() { _settingsService.Save(Settings); StatusMessage = "设置已保存"; } private async Task LoginAdminAsync() { try { ConfigureBackendMode(); if (!_backendClient.IsConnected) { await _backendClient.ConnectAsync(Settings.ServerAddress, Settings.ApiKey).ConfigureAwait(true); } var session = await _backendClient.LoginAdminAsync(Settings.AdminUsername, AdminPassword).ConfigureAwait(true); Settings.AdminUsername = session.Username; Settings.AdminAccessToken = session.AccessToken; AdminPassword = string.Empty; IsAdminLoggedIn = true; _settingsService.Save(Settings); StatusMessage = $"管理员登录成功:{session.DisplayName}"; } catch (Exception ex) { IsAdminLoggedIn = false; StatusMessage = $"管理员登录失败:{ex.Message}"; } } private void LogoutAdmin() { _backendClient.LogoutAdmin(); Settings.AdminAccessToken = string.Empty; AdminPassword = string.Empty; IsAdminLoggedIn = false; _settingsService.Save(Settings); StatusMessage = "管理员已退出登录"; } private void ConfigureBackendMode() { if (_backendClient is GrpcService grpcService) { grpcService.AllowInsecureGrpc = Settings.AllowInsecureGrpc; } } private void SelectLibraryRoot() { using var dialog = new System.Windows.Forms.FolderBrowserDialog { Description = "选择本地文库目录", UseDescriptionForTitle = true, SelectedPath = string.IsNullOrWhiteSpace(Settings.LibraryRoot) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) : Settings.LibraryRoot }; if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Settings.LibraryRoot = dialog.SelectedPath; StatusMessage = "已选择文库目录"; } } private void OpenLogDirectory() { Directory.CreateDirectory(_appLogger.LogDirectory); var startInfo = new System.Diagnostics.ProcessStartInfo { FileName = _appLogger.LogDirectory, UseShellExecute = true }; System.Diagnostics.Process.Start(startInfo); } }