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

155 lines
5.0 KiB
C#

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);
}
}