From ee80792fcca952d794a577ede6313112d428daec Mon Sep 17 00:00:00 2001 From: denglihong2007 <98096191+denglihong2007@users.noreply.github.com> Date: Sun, 20 Jul 2025 16:13:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20#203=20=E6=B7=BB=E5=8A=A0=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=B8=82=E5=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRSim/App.xaml.cs | 6 +- CRSim/CRSim.csproj | 5 + CRSim/Converters/NullToVisibilityConverter.cs | 4 +- .../PluginLoadStatusToVisibilityConverter.cs | 34 +++++ CRSim/MainWindow.xaml | 5 + .../PluginManagementPageViewModel.cs | 92 +++++++++++ CRSim/ViewModels/SettingsPageViewModel.cs | 14 +- .../StationManagementPageViewModel.cs | 21 +-- CRSim/Views/PluginManagementPage.xaml | 144 ++++++++++++++++++ CRSim/Views/PluginManagementPage.xaml.cs | 14 ++ CRSim/Views/SettingsPage.xaml | 4 + 11 files changed, 323 insertions(+), 20 deletions(-) create mode 100644 CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs create mode 100644 CRSim/ViewModels/PluginManagementPageViewModel.cs create mode 100644 CRSim/Views/PluginManagementPage.xaml create mode 100644 CRSim/Views/PluginManagementPage.xaml.cs diff --git a/CRSim/App.xaml.cs b/CRSim/App.xaml.cs index a3397b2..a8ba0f1 100644 --- a/CRSim/App.xaml.cs +++ b/CRSim/App.xaml.cs @@ -14,9 +14,9 @@ { LaunchDebugConsole(); } - if (!Directory.Exists(AppPaths.AppDataFolder)) + if (!Directory.Exists(AppPaths.AppDataPath)) { - Directory.CreateDirectory(AppPaths.AppDataFolder); + Directory.CreateDirectory(AppPaths.AppDataPath); } AppHost = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => @@ -34,6 +34,7 @@ services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); PluginService.InitializePlugins(context, services, parsedOptions.ExternalPluginPath); }) .Build(); @@ -45,7 +46,6 @@ AppHost.Services.GetRequiredService().Start(); MainWindow = AppHost.Services.GetService(); MainWindow?.Activate(); - var win = AppHost.Services.GetService(); } [System.Runtime.InteropServices.DllImport("kernel32.dll")] diff --git a/CRSim/CRSim.csproj b/CRSim/CRSim.csproj index f8253ba..9248cfd 100644 --- a/CRSim/CRSim.csproj +++ b/CRSim/CRSim.csproj @@ -13,6 +13,8 @@ enable None preview + partial + true 2.3.101.1 @@ -82,6 +84,9 @@ Designer + + Designer + Designer diff --git a/CRSim/Converters/NullToVisibilityConverter.cs b/CRSim/Converters/NullToVisibilityConverter.cs index 1aae4d4..5c264a2 100644 --- a/CRSim/Converters/NullToVisibilityConverter.cs +++ b/CRSim/Converters/NullToVisibilityConverter.cs @@ -6,7 +6,9 @@ namespace CRSim.Converters { public object Convert(object value, Type targetType, object parameter, string language) { - return value == null ? Visibility.Collapsed : Visibility.Visible; + bool invert = (parameter as string)?.ToLower() == "invert"; + bool isNull = value == null; + return invert ? isNull ? Visibility.Visible : Visibility.Collapsed : isNull ? Visibility.Collapsed : Visibility.Visible; } public object ConvertBack(object value, Type targetType, object parameter, string language) diff --git a/CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs b/CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs new file mode 100644 index 0000000..070e9d0 --- /dev/null +++ b/CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs @@ -0,0 +1,34 @@ +using CRSim.Core.Enums; +using CRSim.Core.Models.Plugin; +using Microsoft.UI.Xaml.Data; + +namespace CRSim.Converters +{ + public partial class PluginLoadStatusToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + if(value is PluginInfo plugin && parameter is string target) + { + PluginLoadStatus status = plugin.LoadStatus; + if ((plugin.IsUninstalling && target== "Loaded") || (plugin.RestartRequired && target == "NotLoaded")) + { + return Visibility.Collapsed; + } + if ((status == PluginLoadStatus.Loaded && target == "Loaded") || + (status == PluginLoadStatus.Error && target == "Error") || + (status == PluginLoadStatus.NotLoaded && target == "NotLoaded") || + (status == PluginLoadStatus.Disabled && target == "Disabled")) + { + return Visibility.Visible; + } + } + return Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/CRSim/MainWindow.xaml b/CRSim/MainWindow.xaml index 1052d23..64f11a4 100644 --- a/CRSim/MainWindow.xaml +++ b/CRSim/MainWindow.xaml @@ -27,6 +27,11 @@ IsBackButtonVisible="Collapsed" IsBackEnabled="False"> + + + + + diff --git a/CRSim/ViewModels/PluginManagementPageViewModel.cs b/CRSim/ViewModels/PluginManagementPageViewModel.cs new file mode 100644 index 0000000..6365747 --- /dev/null +++ b/CRSim/ViewModels/PluginManagementPageViewModel.cs @@ -0,0 +1,92 @@ +using CRSim.Core.Abstractions; +using CRSim.Core.Models; +using CRSim.Core.Models.Plugin; +using CRSim.Core.Services; +using System.Diagnostics; + +namespace CRSim.ViewModels; + +public partial class PluginManagementPageViewModel : ObservableObject +{ + + [ObservableProperty] + public partial string PageTitle { get; set; } = "插件管理"; + + [ObservableProperty] + public partial PluginInfo? SelectedPlugin { get; set; } + + public ObservableCollection Plugins = []; + + private IPluginService _pluginService; + + public PluginManagementPageViewModel(IPluginService pluginService) + { + _pluginService = pluginService; + } + + [RelayCommand] + public void PluginSelected(object args) + { + if(args is SelectionChangedEventArgs selectionChangedEventArgs && selectionChangedEventArgs.AddedItems.Count == 1) + { + SelectedPlugin = (PluginInfo)selectionChangedEventArgs.AddedItems.FirstOrDefault(); + } + } + + [RelayCommand] + public async Task InstallPlugin() + { + await _pluginService.InstallPluginAsync(SelectedPlugin); + OnPropertyChanged(nameof(SelectedPlugin)); + } + + [RelayCommand] + public void UninstallPlugin() + { + SelectedPlugin.IsUninstalling = true; + OnPropertyChanged(nameof(SelectedPlugin)); + } + + [RelayCommand] + public void CancelUninstallPlugin() + { + SelectedPlugin.IsUninstalling = false; + OnPropertyChanged(nameof(SelectedPlugin)); + } + + [RelayCommand] + public static void Restart() + { + string exePath = Process.GetCurrentProcess().MainModule.FileName; + Process.Start(new ProcessStartInfo(exePath) + { + UseShellExecute = true + }); + Application.Current.Exit(); + } + + [RelayCommand] + public void SourceSelected(SelectorBarItem selectorBarItem) + { + SelectedPlugin = null; + Plugins = (selectorBarItem?.Text == "本地" || selectorBarItem is null) + ? IPluginService.OnlinePlugins : IPluginService.LoadedPlugins; + OnPropertyChanged(nameof(Plugins)); + } + + [RelayCommand] + public static void OpenPluginFolder() + { + Process.Start(new ProcessStartInfo + { + FileName = AppPaths.PluginsRootPath, + UseShellExecute = true + }); + } + + [RelayCommand] + public void Refresh() + { + _pluginService.LoadOnlinePlugins(); + } +} \ No newline at end of file diff --git a/CRSim/ViewModels/SettingsPageViewModel.cs b/CRSim/ViewModels/SettingsPageViewModel.cs index caf9f56..3618d87 100644 --- a/CRSim/ViewModels/SettingsPageViewModel.cs +++ b/CRSim/ViewModels/SettingsPageViewModel.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Diagnostics.Metrics; +using System.Reflection; namespace CRSim.ViewModels { @@ -9,7 +10,11 @@ namespace CRSim.ViewModels [ObservableProperty] public partial string AppVersion { get; set; } = ""; - + public ObservableCollection Apis { get; } = + [ + new InfoItem { Title = "官方插件源", Detail = "http://47.122.74.193:25565" }, + new InfoItem { Title = "镜像站插件源", Detail = "https://crsim.com.cn/api" }, + ]; private Settings _settings; private readonly ISettingsService _settingsService; private readonly IDatabaseService _databaseService; @@ -39,6 +44,9 @@ namespace CRSim.ViewModels [ObservableProperty] public partial string SwitchPageSeconds { get; set; } + [ObservableProperty] + public partial InfoItem ApiUri { get; set; } + [ObservableProperty] public partial string UserKey { get; set; } @@ -67,6 +75,7 @@ namespace CRSim.ViewModels StopDisplayUntilDepartureDuration = _settings.StopDisplayUntilDepartureDuration.TotalMinutes.ToString(); StopDisplayFromArrivalDuration = _settings.StopDisplayFromArrivalDuration.TotalMinutes.ToString(); StopCheckInAdvanceDuration = _settings.StopCheckInAdvanceDuration.TotalMinutes.ToString(); + ApiUri = Apis.Where(x => x.Detail == _settings.ApiUri).FirstOrDefault(); MaxPages = _settings.MaxPages.ToString(); SwitchPageSeconds = _settings.SwitchPageSeconds.ToString(); UserKey = _settings.UserKey; @@ -88,6 +97,7 @@ namespace CRSim.ViewModels _settings.UserKey = UserKey; _settings.LoadTodayOnly = LoadTodayOnly; _settings.ReopenUnclosedScreensOnLoad = ReopenUnclosedScreensOnLoad; + _settings.ApiUri = ApiUri.Detail; _settingsService.SaveSettings(); } private void UpdateSettings(string input, bool allowNegative, Action updateAction) diff --git a/CRSim/ViewModels/StationManagementPageViewModel.cs b/CRSim/ViewModels/StationManagementPageViewModel.cs index 657c208..e0f48da 100644 --- a/CRSim/ViewModels/StationManagementPageViewModel.cs +++ b/CRSim/ViewModels/StationManagementPageViewModel.cs @@ -573,24 +573,17 @@ public partial class StationManagementPageViewModel : ObservableObject [RelayCommand] public async Task ImportFromInternet() { - try + if (!await CheckCanImport()) return; + var stops = await _networkService.GetTrainNumbersAsync(SelectedStation.Name); + if (stops is not null && stops.Count != 0) { - if (!await CheckCanImport()) return; - var stops = await _networkService.GetTrainNumbersAsync(SelectedStation.Name); - if (stops.Count != 0) + TrainStops.Clear(); + foreach (TrainStop t in stops) { - TrainStops.Clear(); - foreach (TrainStop t in stops) - { - TrainStops.Add(RandomTrainStopProperties(t)); - } - } - else - { - throw new Exception(); + TrainStops.Add(RandomTrainStopProperties(t)); } } - catch + else { await _dialogService.ShowMessageAsync("获取失败", "服务器繁忙或车站不存在。"); } diff --git a/CRSim/Views/PluginManagementPage.xaml b/CRSim/Views/PluginManagementPage.xaml new file mode 100644 index 0000000..03a8379 --- /dev/null +++ b/CRSim/Views/PluginManagementPage.xaml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CRSim/Views/PluginManagementPage.xaml.cs b/CRSim/Views/PluginManagementPage.xaml.cs new file mode 100644 index 0000000..43a2f0f --- /dev/null +++ b/CRSim/Views/PluginManagementPage.xaml.cs @@ -0,0 +1,14 @@ +using System.Diagnostics; + +namespace CRSim.Views; + +public sealed partial class PluginManagementPage : Page +{ + public PluginManagementPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + + public PluginManagementPage() + { + InitializeComponent(); + DataContext = ViewModel; + } +} diff --git a/CRSim/Views/SettingsPage.xaml b/CRSim/Views/SettingsPage.xaml index b5a1717..c668619 100644 --- a/CRSim/Views/SettingsPage.xaml +++ b/CRSim/Views/SettingsPage.xaml @@ -41,6 +41,10 @@ + + +