diff --git a/.gitattributes b/.gitattributes index 1ff0c42..74f0865 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,7 @@ # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto +*.cs text eol=lf working-tree-encoding=UTF-8 ############################################################################### # Set default behavior for command prompt diff. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e837a0..affb177 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,11 +21,6 @@ jobs: with: fetch-depth: 0 # 获取全部提交历史以便比较标签 - - name: Setup .NET 9.0 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: '9.0.x' - - name: Extract version from csproj id: get_version shell: pwsh @@ -73,6 +68,12 @@ jobs: with: dotnet-version: '9.0.x' + - name: Set Encoding + run: | + echo "DOTNET_CLI_UI_LANGUAGE=zh-CN" >> $GITHUB_ENV + chcp 65001 + + - name: Restore and Build run: | dotnet restore diff --git a/CRSim/App.xaml.cs b/CRSim/App.xaml.cs index 1bfa9b4..5e635c9 100644 --- a/CRSim/App.xaml.cs +++ b/CRSim/App.xaml.cs @@ -59,6 +59,8 @@ services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); }).Build(); [STAThread] diff --git a/CRSim/Assets/StyleImages/Tianjin/PlatformScreen.png b/CRSim/Assets/StyleImages/Tianjin/PlatformScreen.png new file mode 100644 index 0000000..3d59501 Binary files /dev/null and b/CRSim/Assets/StyleImages/Tianjin/PlatformScreen.png differ diff --git a/CRSim/Assets/StyleImages/Tianjin/image.png b/CRSim/Assets/StyleImages/Tianjin/image.png new file mode 100644 index 0000000..a7bf60e Binary files /dev/null and b/CRSim/Assets/StyleImages/Tianjin/image.png differ diff --git a/CRSim/CRSim.csproj b/CRSim/CRSim.csproj index 9b905ea..bd4e5de 100644 --- a/CRSim/CRSim.csproj +++ b/CRSim/CRSim.csproj @@ -9,11 +9,13 @@ 13.0 CRSim.App Assets\CRSimIcon.ico - 1.2.5.0 + 1.2.6.0 + + PreserveNewest @@ -42,6 +44,8 @@ + + @@ -78,6 +82,9 @@ Code + + Code + Code diff --git a/CRSim/Converters/LocationToStringConverter.cs b/CRSim/Converters/LocationToStringConverter.cs new file mode 100644 index 0000000..25d6adf --- /dev/null +++ b/CRSim/Converters/LocationToStringConverter.cs @@ -0,0 +1,32 @@ +namespace CRSim.Converters +{ + public class LocationToStringConverter : IMultiValueConverter + { + object IMultiValueConverter.Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (values[0] is int Length&& values[1] is int Location) + { + if (Location > Length) + { + return $"当前无车,1-{Length}车向后。"; + } + if (Location == Length) + { + return $"当前{Length}车,1-{Length-1}车向后。"; + } + if (Location == 1) + { + return $"当前1车,2-{Length}车向前。"; + } + return $"当前{Location}车,1-{Location - 1}车向前,{Location + 1}-{Length}车向后。"; + } + return string.Empty; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + // 通常不需要实现 ConvertBack + return null; + } + } +} diff --git a/CRSim/Models/StylesInfoData.json b/CRSim/Models/StylesInfoData.json index e1364e2..3a7f133 100644 --- a/CRSim/Models/StylesInfoData.json +++ b/CRSim/Models/StylesInfoData.json @@ -87,6 +87,18 @@ "Text" ] }, + { + "UniqueId": "Tianjin PlatformScreen", + "Title": "天津站站台看板", + "Station": "Tianjin", + "StyleName": "PlatformScreenView", + "ImagePath": "Assets/StyleImages/Tianjin/PlatformScreen.png", + "Parameters": [ + "Station", + "Platform", + "Location" + ] + }, { "UniqueId": "Zibo PrimaryScreen", "Title": "淄博站主要看板", diff --git a/CRSim/ViewModels/Pages/Simulation/ScreenSimulationPageViewModel.cs b/CRSim/ViewModels/Pages/Simulation/ScreenSimulationPageViewModel.cs index ac9e62f..666e9d0 100644 --- a/CRSim/ViewModels/Pages/Simulation/ScreenSimulationPageViewModel.cs +++ b/CRSim/ViewModels/Pages/Simulation/ScreenSimulationPageViewModel.cs @@ -28,6 +28,9 @@ public partial class ScreenSimulationPageViewModel : ObservableObject [ObservableProperty] private bool _textNeeded; + [ObservableProperty] + private bool _locationNeeded; + [ObservableProperty] private string _text = ""; @@ -37,9 +40,12 @@ public partial class ScreenSimulationPageViewModel : ObservableObject public string SelectedPlatformName = ""; + public int SelectedLoaction = 0; + public ObservableCollection StationNames { get; private set; } = []; public ObservableCollection TicketChecks { get; private set; } = []; public ObservableCollection Platforms { get; private set; } = []; + public ObservableCollection Locations { get; private set; } = []; [ObservableProperty] private bool _isStartSimulationAvailable = false; @@ -62,9 +68,10 @@ public partial class ScreenSimulationPageViewModel : ObservableObject private void CheckCanStart() { - IsStartSimulationAvailable = selectedStyle!=null && - (!StationNeeded || !string.IsNullOrWhiteSpace(SelectedStationName))&& + IsStartSimulationAvailable = selectedStyle != null && + (!StationNeeded || !string.IsNullOrWhiteSpace(SelectedStationName)) && (!TicketCheckNeeded || !string.IsNullOrWhiteSpace(SelectedTicketCheck)) && + (!LocationNeeded || SelectedLoaction != 0) && (!PlatformNeeded || !string.IsNullOrWhiteSpace(SelectedPlatformName)); } @@ -80,27 +87,31 @@ public partial class ScreenSimulationPageViewModel : ObservableObject TicketCheckNeeded = neededParameters.Contains("TicketCheck"); PlatformNeeded = neededParameters.Contains("Platform"); TextNeeded = neededParameters.Contains("Text"); + LocationNeeded = neededParameters.Contains("Location"); } CheckCanStart(); } [RelayCommand] public void SelectStation(object s) { - if(s is string station) + if(s is string v) { - SelectedStationName = station; + var station = _databaseService.GetStationByName(v); + SelectedStationName = station.Name; SelectedPlatformName = ""; SelectedTicketCheck = ""; + SelectedLoaction = 0; TicketChecks.Clear(); - foreach(string ticketCheck in _databaseService.GetStationByName(SelectedStationName).TicketChecks) + foreach(string ticketCheck in station.TicketChecks) { TicketChecks.Add(ticketCheck); } Platforms.Clear(); - foreach (var platform in _databaseService.GetStationByName(SelectedStationName).Platforms) + foreach (var platform in station.Platforms) { Platforms.Add(platform); } + Locations.Clear(); } CheckCanStart(); } @@ -114,11 +125,26 @@ public partial class ScreenSimulationPageViewModel : ObservableObject CheckCanStart(); } [RelayCommand] + public void SelectLocation(object s) + { + if (s is int location) + { + SelectedLoaction = location; + } + CheckCanStart(); + } + [RelayCommand] public void SelectPlatform(object s) { if (s is Platform platform) { SelectedPlatformName = platform.Name; + SelectedLoaction = 0; + Locations.Clear(); + for (int i = 1; i <= platform.Length; i++) + { + Locations.Add(i); + } } CheckCanStart(); } @@ -131,6 +157,10 @@ public partial class ScreenSimulationPageViewModel : ObservableObject { Window.ViewModel.Text = Text; } + if (LocationNeeded && SelectedLoaction != 0) + { + Window.ViewModel.Location = SelectedLoaction; + } Window.ViewModel.LoadData(_databaseService.GetStationByName(SelectedStationName), TicketCheckNeeded ? SelectedTicketCheck : string.Empty, diff --git a/CRSim/ViewModels/Windows/ScreenViewModel.cs b/CRSim/ViewModels/Windows/ScreenViewModel.cs index 0598b3c..26a1ae3 100644 --- a/CRSim/ViewModels/Windows/ScreenViewModel.cs +++ b/CRSim/ViewModels/Windows/ScreenViewModel.cs @@ -14,7 +14,11 @@ namespace CRSim.ViewModels [ObservableProperty] private string _text = ""; [ObservableProperty] + public int _location; + [ObservableProperty] private Station _thisStation; + [ObservableProperty] + private string _thisPlatform; public event PropertyChangedEventHandler PropertyChanged; public List TrainInfo { get; set; } = []; @@ -55,6 +59,7 @@ namespace CRSim.ViewModels public void LoadData(Station station,string ticketCheck,string platform) { ThisStation = station; + ThisPlatform = platform; var trains = station.StationStops; foreach (var trainNumber in trains) { diff --git a/CRSim/ViewModels/Windows/Stations/Tianjin/PlatformScreenViewModel.cs b/CRSim/ViewModels/Windows/Stations/Tianjin/PlatformScreenViewModel.cs new file mode 100644 index 0000000..19958ca --- /dev/null +++ b/CRSim/ViewModels/Windows/Stations/Tianjin/PlatformScreenViewModel.cs @@ -0,0 +1,41 @@ +namespace CRSim.ViewModels.Tianjin +{ + public class PlatformScreenViewModel : ScreenViewModel + { + private ITimeService _timeService; + public ObservableCollection Screen { get; set; } = []; + public PlatformScreenViewModel(ITimeService timeService, ISettingsService settingsService) + : base(timeService, settingsService) + { + _timeService = timeService; + timeService.RefreshSecondsElapsed += RefreshDisplay; + Initialize(); + } + private async void Initialize() + { + await WaitForDataLoadAsync(); + Text = ThisPlatform; + RefreshDisplay(null,null); + } + private void RefreshDisplay(object? sender, EventArgs e) + { + Application.Current.Dispatcher.Invoke(() => + { + Screen.Add(TrainInfo.Count > 0 ? TrainInfo[0] : new()); + if (Screen.Count == 1) return; + Screen.RemoveAt(0); + }); + } + public override void RefreshData(object? sender, EventArgs e) + { + if (CurrentPageIndex == 0) + { + List itemsToRemove = [.. TrainInfo.Where(info => info.DepartureTime < _timeService.GetDateTimeNow())]; + foreach (var item in itemsToRemove) + { + TrainInfo.Remove(item); + } + } + } + } +} diff --git a/CRSim/Views/Pages/Simulation/ScreenSimulationPage.xaml b/CRSim/Views/Pages/Simulation/ScreenSimulationPage.xaml index 089f0b2..2184a32 100644 --- a/CRSim/Views/Pages/Simulation/ScreenSimulationPage.xaml +++ b/CRSim/Views/Pages/Simulation/ScreenSimulationPage.xaml @@ -125,7 +125,6 @@ - @@ -144,6 +143,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml b/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml new file mode 100644 index 0000000..b49c1de --- /dev/null +++ b/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml.cs b/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml.cs new file mode 100644 index 0000000..7c1c9ab --- /dev/null +++ b/CRSim/Views/Windows/Stations/Tianjin/PlatformScreenView.xaml.cs @@ -0,0 +1,33 @@ +using CRSim.ViewModels.Tianjin; + +namespace CRSim.Views.Tianjin +{ + /// + /// SecondaryScreen.xaml 的交互逻辑 + /// + public partial class PlatformScreenView : Window + { + public PlatformScreenViewModel ViewModel { get; } + public PlatformScreenView(PlatformScreenViewModel viewModel) + { + InitializeComponent(); + ViewModel = viewModel; + DataContext = viewModel; + } + private void Window_MouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left) + { + DragMove(); + } + } + + private void Window_KeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + Close(); + } + } + } +}