|
|
@@ -4,7 +4,6 @@ using System.ComponentModel;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
-using System.Windows.Documents;
|
|
|
using System.Windows.Input;
|
|
|
using System.Windows.Media;
|
|
|
using System.Windows.Media.Animation;
|
|
|
@@ -15,7 +14,6 @@ namespace NetworkTool.Client;
|
|
|
|
|
|
public partial class DeviceDetailsWindow : Window
|
|
|
{
|
|
|
- private const int ApplyConfirmationTimeoutSeconds = 20;
|
|
|
private readonly ServerApiService _serverApiService = new();
|
|
|
private readonly ObservableCollection<InterfaceEditor> _interfaces = [];
|
|
|
private readonly string _baseAddress;
|
|
|
@@ -316,21 +314,10 @@ public partial class DeviceDetailsWindow : Window
|
|
|
if (task.Status == "running" && task.Step == "confirming" && !confirmationRequested)
|
|
|
{
|
|
|
confirmationRequested = true;
|
|
|
- var confirm = ShowApplyConfirmationDialog(ApplyConfirmationTimeoutSeconds);
|
|
|
- if (confirm)
|
|
|
- {
|
|
|
- var confirmResult = await _serverApiService.ConfirmApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
|
|
|
- ShowStatusMessage(
|
|
|
- confirmResult.Success ? "已发送保留配置确认。" : $"发送确认失败:{confirmResult.Message}",
|
|
|
- confirmResult.Success ? StatusMessageType.Success : StatusMessageType.Error);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- var cancelResult = await _serverApiService.CancelApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
|
|
|
- ShowStatusMessage(
|
|
|
- cancelResult.Success ? "已取消保留配置,正在回滚。" : $"发送取消失败:{cancelResult.Message}",
|
|
|
- cancelResult.Success ? StatusMessageType.Warning : StatusMessageType.Error);
|
|
|
- }
|
|
|
+ var confirmResult = await _serverApiService.ConfirmApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
|
|
|
+ ShowStatusMessage(
|
|
|
+ confirmResult.Success ? "设备连接已恢复,已自动确认保留配置。" : $"自动确认保留配置失败:{confirmResult.Message}",
|
|
|
+ confirmResult.Success ? StatusMessageType.Success : StatusMessageType.Error);
|
|
|
}
|
|
|
|
|
|
if (task.Status is "success" or "failed" or "rolled_back")
|
|
|
@@ -355,201 +342,6 @@ public partial class DeviceDetailsWindow : Window
|
|
|
ShowStatusMessage($"任务 {taskId} 轮询超时,请稍后手动刷新。", StatusMessageType.Warning);
|
|
|
}
|
|
|
|
|
|
- private bool ShowApplyConfirmationDialog(int timeoutSeconds)
|
|
|
- {
|
|
|
- var remaining = timeoutSeconds;
|
|
|
- var result = false;
|
|
|
- var deadline = DateTime.UtcNow.AddSeconds(timeoutSeconds);
|
|
|
- var remainingTextBlock = new TextBlock
|
|
|
- {
|
|
|
- VerticalAlignment = VerticalAlignment.Center,
|
|
|
- FontSize = 14,
|
|
|
- FontWeight = FontWeights.SemiBold,
|
|
|
- };
|
|
|
- var progressBar = new ProgressBar
|
|
|
- {
|
|
|
- Height = 8,
|
|
|
- Minimum = 0,
|
|
|
- Maximum = timeoutSeconds,
|
|
|
- Value = timeoutSeconds,
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(24, 119, 242)),
|
|
|
- Background = new SolidColorBrush(Color.FromRgb(229, 231, 235)),
|
|
|
- BorderBrush = Brushes.Transparent,
|
|
|
- BorderThickness = new Thickness(0),
|
|
|
- };
|
|
|
- var confirmButton = new Button
|
|
|
- {
|
|
|
- Width = 100,
|
|
|
- Height = 34,
|
|
|
- Margin = new Thickness(0, 0, 12, 0),
|
|
|
- Content = "保留配置",
|
|
|
- FontSize = 13,
|
|
|
- IsDefault = true,
|
|
|
- };
|
|
|
- confirmButton.Style = (Style)FindResource("PrimaryButtonStyle");
|
|
|
- var cancelButton = new Button
|
|
|
- {
|
|
|
- Width = 100,
|
|
|
- Height = 34,
|
|
|
- Content = "撤销修改",
|
|
|
- FontSize = 13,
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(31, 41, 55)),
|
|
|
- IsCancel = true,
|
|
|
- };
|
|
|
- var dialog = new Window
|
|
|
- {
|
|
|
- Title = "确认保留网络配置",
|
|
|
- Owner = this,
|
|
|
- WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
|
|
- ResizeMode = ResizeMode.NoResize,
|
|
|
- SizeToContent = SizeToContent.WidthAndHeight,
|
|
|
- Content = new Border
|
|
|
- {
|
|
|
- Width = 460,
|
|
|
- Padding = new Thickness(16),
|
|
|
- Background = Brushes.White,
|
|
|
- Child = new Grid
|
|
|
- {
|
|
|
- RowDefinitions =
|
|
|
- {
|
|
|
- new RowDefinition { Height = GridLength.Auto },
|
|
|
- new RowDefinition { Height = GridLength.Auto },
|
|
|
- new RowDefinition { Height = GridLength.Auto },
|
|
|
- },
|
|
|
- Children =
|
|
|
- {
|
|
|
- CreateApplyConfirmNoticeCard(),
|
|
|
- CreateApplyConfirmCountdownCard(remainingTextBlock, progressBar),
|
|
|
- new StackPanel
|
|
|
- {
|
|
|
- Margin = new Thickness(0, 24, 0, 0),
|
|
|
- HorizontalAlignment = HorizontalAlignment.Right,
|
|
|
- Orientation = Orientation.Horizontal,
|
|
|
- Children = { confirmButton, cancelButton },
|
|
|
- }.SetGridRow(2),
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- void UpdateMessage(double secondsLeft)
|
|
|
- {
|
|
|
- remaining = Math.Max(0, (int)Math.Ceiling(secondsLeft));
|
|
|
- remainingTextBlock.Inlines.Clear();
|
|
|
- remainingTextBlock.Inlines.Add(new Run($"{remaining} 秒后")
|
|
|
- {
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(24, 119, 242)),
|
|
|
- });
|
|
|
- remainingTextBlock.Inlines.Add(new Run("撤销修改")
|
|
|
- {
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(31, 41, 55)),
|
|
|
- });
|
|
|
- progressBar.Value = Math.Max(0, secondsLeft);
|
|
|
- }
|
|
|
-
|
|
|
- var timer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
|
|
|
- timer.Tick += (_, _) =>
|
|
|
- {
|
|
|
- var secondsLeft = (deadline - DateTime.UtcNow).TotalSeconds;
|
|
|
- if (secondsLeft <= 0)
|
|
|
- {
|
|
|
- timer.Stop();
|
|
|
- dialog.DialogResult = false;
|
|
|
- dialog.Close();
|
|
|
- return;
|
|
|
- }
|
|
|
- UpdateMessage(secondsLeft);
|
|
|
- };
|
|
|
- confirmButton.Click += (_, _) =>
|
|
|
- {
|
|
|
- result = true;
|
|
|
- dialog.DialogResult = true;
|
|
|
- dialog.Close();
|
|
|
- };
|
|
|
- cancelButton.Click += (_, _) =>
|
|
|
- {
|
|
|
- dialog.DialogResult = false;
|
|
|
- dialog.Close();
|
|
|
- };
|
|
|
- dialog.Closed += (_, _) => timer.Stop();
|
|
|
-
|
|
|
- UpdateMessage(timeoutSeconds);
|
|
|
- timer.Start();
|
|
|
- dialog.ShowDialog();
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- private static Border CreateApplyConfirmNoticeCard()
|
|
|
- {
|
|
|
- return new Border
|
|
|
- {
|
|
|
- Height = 36,
|
|
|
- Padding = new Thickness(14, 0, 14, 0),
|
|
|
- Background = new SolidColorBrush(Color.FromRgb(255, 251, 235)),
|
|
|
- BorderBrush = new SolidColorBrush(Color.FromRgb(253, 230, 138)),
|
|
|
- BorderThickness = new Thickness(1),
|
|
|
- CornerRadius = new CornerRadius(8),
|
|
|
- Child = new StackPanel
|
|
|
- {
|
|
|
- VerticalAlignment = VerticalAlignment.Center,
|
|
|
- Orientation = Orientation.Horizontal,
|
|
|
- Children =
|
|
|
- {
|
|
|
- new TextBlock
|
|
|
- {
|
|
|
- Text = "⏳",
|
|
|
- Margin = new Thickness(0, 0, 12, 0),
|
|
|
- VerticalAlignment = VerticalAlignment.Center,
|
|
|
- FontSize = 16,
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(245, 158, 11)),
|
|
|
- },
|
|
|
- new TextBlock
|
|
|
- {
|
|
|
- Text = "请在倒计时结束前点击“保留配置”。",
|
|
|
- VerticalAlignment = VerticalAlignment.Center,
|
|
|
- FontSize = 13,
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(31, 41, 55)),
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }.SetGridRow(0);
|
|
|
- }
|
|
|
-
|
|
|
- private static Border CreateApplyConfirmCountdownCard(TextBlock remainingTextBlock, ProgressBar progressBar)
|
|
|
- {
|
|
|
- return new Border
|
|
|
- {
|
|
|
- Margin = new Thickness(0, 16, 0, 0),
|
|
|
- Padding = new Thickness(18, 12, 18, 12),
|
|
|
- BorderBrush = new SolidColorBrush(Color.FromRgb(229, 231, 235)),
|
|
|
- BorderThickness = new Thickness(1),
|
|
|
- CornerRadius = new CornerRadius(8),
|
|
|
- Child = new StackPanel
|
|
|
- {
|
|
|
- Children =
|
|
|
- {
|
|
|
- new StackPanel
|
|
|
- {
|
|
|
- Orientation = Orientation.Horizontal,
|
|
|
- Children =
|
|
|
- {
|
|
|
- new TextBlock
|
|
|
- {
|
|
|
- Text = "◷",
|
|
|
- Margin = new Thickness(0, 0, 12, 0),
|
|
|
- VerticalAlignment = VerticalAlignment.Center,
|
|
|
- FontSize = 18,
|
|
|
- Foreground = new SolidColorBrush(Color.FromRgb(24, 119, 242)),
|
|
|
- },
|
|
|
- remainingTextBlock,
|
|
|
- },
|
|
|
- },
|
|
|
- progressBar.SetMargin(new Thickness(0, 12, 0, 0)),
|
|
|
- },
|
|
|
- },
|
|
|
- }.SetGridRow(1);
|
|
|
- }
|
|
|
-
|
|
|
private async void RebootButton_OnClick(object sender, RoutedEventArgs e)
|
|
|
{
|
|
|
await ExecuteSystemActionAsync(
|
|
|
@@ -1249,7 +1041,7 @@ public partial class DeviceDetailsWindow : Window
|
|
|
"validating" => ("正在校验配置...", StatusMessageType.Info),
|
|
|
"writing_netplan" => ("正在写入 Linux 网络配置...", StatusMessageType.Info),
|
|
|
"applying" => ("正在保存 Linux 网络配置...", StatusMessageType.Info),
|
|
|
- "confirming" => (string.IsNullOrWhiteSpace(task.Detail) ? "等待确认保留配置..." : task.Detail, StatusMessageType.Warning),
|
|
|
+ "confirming" => ("设备连接已恢复,正在自动确认保留配置...", StatusMessageType.Info),
|
|
|
"rolling_back" => ("配置保存失败,正在自动回滚...", StatusMessageType.Warning),
|
|
|
_ => (string.IsNullOrWhiteSpace(task.Detail) ? "正在处理,请稍候..." : task.Detail, StatusMessageType.Info),
|
|
|
}
|