diff --git a/CRSim/MainWindow.xaml.cs b/CRSim/MainWindow.xaml.cs index 89ee9a8..22f8aa4 100644 --- a/CRSim/MainWindow.xaml.cs +++ b/CRSim/MainWindow.xaml.cs @@ -90,8 +90,8 @@ namespace CRSim private void UpdateWindowBackground() { - if ((!Utility.IsBackdropDisabled() && - !Utility.IsBackdropSupported())) + if ((!Utilities.IsBackdropDisabled() && + !Utilities.IsBackdropSupported())) { this.SetResourceReference(BackgroundProperty, "WindowBackground"); } @@ -110,7 +110,7 @@ namespace CRSim } private void UpdateTitleBarButtonsVisibility() { - if (Utility.IsBackdropDisabled() || !Utility.IsBackdropSupported() || + if (Utilities.IsBackdropDisabled() || !Utilities.IsBackdropSupported() || SystemParameters.HighContrast == true) { MinimizeButton.Visibility = Visibility.Visible; diff --git a/CRSim/Utility.cs b/CRSim/Utilities.cs similarity index 72% rename from CRSim/Utility.cs rename to CRSim/Utilities.cs index 16f6ce2..e769288 100644 --- a/CRSim/Utility.cs +++ b/CRSim/Utilities.cs @@ -1,6 +1,6 @@ namespace CRSim { - internal static class Utility + internal static class Utilities { public static bool IsBackdropSupported() { @@ -22,6 +22,12 @@ namespace CRSim return disableFluentThemeWindowBackdrop; } + public static TimeSpan RoundToMinute(string timeString) + { + if (TimeSpan.TryParse(timeString, out var time)) + return TimeSpan.FromMinutes(Math.Round(time.TotalMinutes)); + return default; + } } } diff --git a/CRSim/ViewModels/Pages/DataManagement/StationManagementPageViewModel.cs b/CRSim/ViewModels/Pages/DataManagement/StationManagementPageViewModel.cs index 47cab79..279d124 100644 --- a/CRSim/ViewModels/Pages/DataManagement/StationManagementPageViewModel.cs +++ b/CRSim/ViewModels/Pages/DataManagement/StationManagementPageViewModel.cs @@ -1,5 +1,6 @@ using CRSim.Core.Models; using OfficeOpenXml; +using System.Diagnostics.Eventing.Reader; namespace CRSim.ViewModels; @@ -333,6 +334,82 @@ public partial class StationManagementPageViewModel : ObservableObject _dialogService.ShowMessage("导入失败", "文件格式错误或被占用。"); } } + [RelayCommand] + public async Task ImportFrompyETRC() + { + if (!CheckCanImport()) return; + + var path = _dialogService.GetFile("pyETRC 运行图文件 (*.pyetgr;*.json)|*.pyetgr;*.json|pyETRC 车次数据库文件 (*.pyetdb;*.json)|*.pyetdb;*.json|所有文件 (*.*)|*.*"); + if (path == null) return; + try + { + using var fs = File.OpenRead(path); + var doc = await JsonDocument.ParseAsync(fs); + + var root = doc.RootElement; + if (!root.TryGetProperty("trains", out var trains)) return; + + foreach (var train in trains.EnumerateArray()) + { + if (!train.TryGetProperty("timetable", out var timetable)) continue; + var stops = timetable.EnumerateArray().ToArray(); + if (stops.Length == 0) continue; + + string origin = stops[0].GetProperty("zhanming").GetString(); + string terminal = stops[^1].GetProperty("zhanming").GetString(); + + TimeSpan? arrivalTime = null; + TimeSpan? departureTime = null; + + foreach (var stop in stops) + { + string name = stop.GetProperty("zhanming").GetString(); + if (name != SelectedStation.Name) continue; + + string cfsj = stop.GetProperty("cfsj").GetString(); + string ddsj = stop.GetProperty("ddsj").GetString(); + + if (cfsj == ddsj) + { + if (name == origin) + { + departureTime = Utilities.RoundToMinute(cfsj); + arrivalTime = null; + } + else if (name == terminal) + { + departureTime = null; + arrivalTime = Utilities.RoundToMinute(ddsj); + } + } + else + { + departureTime = Utilities.RoundToMinute(cfsj); + arrivalTime = Utilities.RoundToMinute(ddsj); + } + break; + } + if (arrivalTime == null && departureTime == null) continue; + string number = train.GetProperty("checi").EnumerateArray().FirstOrDefault().GetString()?.Split('/')?.FirstOrDefault() ?? string.Empty; + + var trainStop = new TrainStop + { + Number = number, + Origin = origin, + Terminal = terminal, + ArrivalTime = arrivalTime, + DepartureTime = departureTime, + }; + + TrainStops.Add(RandomTrainStopProperties(trainStop)); + } + } + catch + { + _dialogService.ShowMessage("导入失败", "文件格式错误或被占用。"); + } + } + [RelayCommand] public void ImportFromExcel() { diff --git a/CRSim/ViewModels/Pages/DataManagement/TrainNumberManagementPageViewModel.cs b/CRSim/ViewModels/Pages/DataManagement/TrainNumberManagementPageViewModel.cs index cea4498..3fe659f 100644 --- a/CRSim/ViewModels/Pages/DataManagement/TrainNumberManagementPageViewModel.cs +++ b/CRSim/ViewModels/Pages/DataManagement/TrainNumberManagementPageViewModel.cs @@ -3,6 +3,7 @@ using OfficeOpenXml; using System; using System.Collections.Specialized; using System.IO; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CRSim.ViewModels; @@ -191,30 +192,7 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject await Task.Delay(100); timeTable ??= []; _databaseService.AddTrainNumber(number); - var sections = new List
(); - var isEmu = number.StartsWith('G') || number.StartsWith('D') || number.StartsWith('C'); - for (int i = 1; i < timeTable.Count; i++) - { - sections.Add(new Section - { - From = timeTable[i - 1].Station, - To = timeTable[i].Station, - Tickets = new Tickets - { - SW = isEmu ? new() : null, - ZYY = isEmu ? new() : null, - ZY = isEmu ? new() : null, - ZE = isEmu ? new() : null, - RZ = !isEmu ? new() : null, - GRW = !isEmu ? new() : null, - RW = !isEmu ? new() : null, - WZ = new(), - YW = !isEmu ? new() : null, - YZ = !isEmu ? new() : null - } - }); - } - _databaseService.UpdateTrainNumber(_databaseService.GetTrainNumberByNumber(number), timeTable, sections); + _databaseService.UpdateTrainNumber(_databaseService.GetTrainNumberByNumber(number), timeTable, GenerateSections(number,timeTable)); } ProgressValue = 0; await _databaseService.SaveData(); @@ -226,6 +204,62 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject ProgressValue = 0; } } + [RelayCommand] + public async Task ImportFrompyETRC() + { + if (TrainNumbers.Count != 0) + { + if (!_dialogService.GetConfirm("当前操作可能覆盖现有车次配置,是否继续?")) return; + } + var path = _dialogService.GetFile("pyETRC 运行图文件 (*.pyetgr;*.json)|*.pyetgr;*.json|pyETRC 车次数据库文件 (*.pyetdb;*.json)|*.pyetdb;*.json|所有文件 (*.*)|*.*"); + if (path == null) return; + try + { + using var fs = File.OpenRead(path); + var doc = await JsonDocument.ParseAsync(fs); + + var root = doc.RootElement; + if (!root.TryGetProperty("trains", out var trains)) return; + + foreach (var train in trains.EnumerateArray()) + { + if (!train.TryGetProperty("timetable", out var timetable)) continue; + var stops = timetable.EnumerateArray().ToArray(); + if (stops.Length == 0) continue; + List? timeTable = []; + string number = train.GetProperty("checi").EnumerateArray().FirstOrDefault().GetString()?.Split('/')?.FirstOrDefault(); + for (int i = 0; i < stops.Length; i++) + { + TimeSpan? arrivalTime = null; + TimeSpan? departureTime = null; + var stop = stops[i]; + string name = stop.GetProperty("zhanming").GetString(); + string cfsj = stop.GetProperty("cfsj").GetString(); + string ddsj = stop.GetProperty("ddsj").GetString(); + if (i != 0) arrivalTime = Utilities.RoundToMinute(ddsj); + if (i != stops.Length-1) departureTime = Utilities.RoundToMinute(cfsj); + if (arrivalTime == departureTime) continue; + timeTable.Add(new TrainStop + { + Station = name, + ArrivalTime = arrivalTime, + DepartureTime = departureTime, + }); + } + if (!TrainNumbers.Select(x => x.Number).Contains(number)) + { + _databaseService.AddTrainNumber(number); + } + _databaseService.UpdateTrainNumber(_databaseService.GetTrainNumberByNumber(number), timeTable, GenerateSections(number, timeTable)); + } + await _databaseService.SaveData(); + RefreshTrainNumbers(); + } + catch + { + _dialogService.ShowMessage("导入失败", "文件格式错误或被占用。"); + } + } #endregion #region TimeTable @@ -418,6 +452,34 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject #endregion #region Sections + private static List
GenerateSections(string number,List timeTable) + { + var sections = new List
(); + var isEmu = number.StartsWith('G') || number.StartsWith('D') || number.StartsWith('C'); + for (int i = 1; i < timeTable.Count; i++) + { + sections.Add(new Section + { + From = timeTable[i - 1].Station, + To = timeTable[i].Station, + Tickets = new Tickets + { + SW = isEmu ? new() : null, + ZYY = isEmu ? new() : null, + ZY = isEmu ? new() : null, + ZE = isEmu ? new() : null, + RZ = !isEmu ? new() : null, + GRW = !isEmu ? new() : null, + RW = !isEmu ? new() : null, + WZ = new(), + YW = !isEmu ? new() : null, + YZ = !isEmu ? new() : null + } + }); + } + return sections; + } + [RelayCommand] public void SeatChecked(object? parameter) { diff --git a/CRSim/Views/Pages/DataManagement/StationManagementPage.xaml b/CRSim/Views/Pages/DataManagement/StationManagementPage.xaml index 3d0f7fd..e1115ce 100644 --- a/CRSim/Views/Pages/DataManagement/StationManagementPage.xaml +++ b/CRSim/Views/Pages/DataManagement/StationManagementPage.xaml @@ -568,6 +568,13 @@ + + + + + + + diff --git a/CRSim/Views/Pages/DataManagement/TrainNumberManagementPage.xaml b/CRSim/Views/Pages/DataManagement/TrainNumberManagementPage.xaml index 9156159..a55bf22 100644 --- a/CRSim/Views/Pages/DataManagement/TrainNumberManagementPage.xaml +++ b/CRSim/Views/Pages/DataManagement/TrainNumberManagementPage.xaml @@ -184,6 +184,13 @@ + + + + + + +