Browse Source

refactor(ui): 移除网络配置手动确认弹窗改为自动确认

简化 netplan 应用流程,连接恢复后自动确认保留配置,移除倒计时 UI。
yangkaixiang 1 tháng trước cách đây
mục cha
commit
de4f13af00

+ 1 - 0
AGENTS.md

@@ -6,3 +6,4 @@
 - 每次编译 server 端前,需要先修改版本号。
 - 编译win端前,需要修改主界面标题栏的版本号。
 - 版本号格式统一使用 `yyyy.MM.dd.HHmm`,例如 `2026.05.13.1446`。
+- 如果修改后的代码和docs里文档描述不一致,需要你来修改docs里的文档。

+ 4 - 5
docs/06-netplan修改策略.md

@@ -142,17 +142,16 @@
 
 1. 备份完成后写回修改后的文件
 2. 执行 `netplan apply`
-3. 客户端仍可连接时,在限定时间内由用户确认保留配置
-4. 未确认、取消或执行失败时恢复本次备份并再次执行 `netplan apply`
+3. 客户端仍可连接时,在限定时间内自动确认保留配置
+4. 未自动确认或执行失败时恢复本次备份并再次执行 `netplan apply`
 
 ### 7.3 回滚规则
 
 出现以下情况时执行回滚:
 
 1. `netplan apply` 执行失败
-2. 用户未在超时时间内确认保留配置
-3. 用户主动取消保留配置
-4. 其他明确判定为配置失败的情况
+2. 客户端未能在超时时间内自动确认保留配置
+3. 其他明确判定为配置失败的情况
 
 回滚步骤:
 

+ 5 - 213
windows/NetworkTool.Client/DeviceDetailsWindow.xaml.cs

@@ -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),
             }

+ 1 - 1
windows/NetworkTool.Client/NetworkTool.Client.csproj

@@ -6,7 +6,7 @@
     <Nullable>enable</Nullable>
     <ImplicitUsings>enable</ImplicitUsings>
     <UseWPF>true</UseWPF>
-    <InformationalVersion>2026.05.13.1605</InformationalVersion>
+    <InformationalVersion>2026.05.13.1623</InformationalVersion>
   </PropertyGroup>
 
 </Project>