From 0d43cda5d7b7448f4de66a085becbbde9a7270e0 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Thu, 6 Aug 2026 11:22:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20AutomationModeContext=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E8=87=AA=E5=8A=A8=E6=A8=A1=E5=BC=8F=EF=BC=88=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E8=87=AA=E5=8A=A8=E9=80=89=E6=8B=A9=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C=E5=B9=B6=E7=AB=8B=E5=8D=B3=E5=85=B3=E9=97=AD?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 src/Utils/AutomationModeContext.cs: - 自动模式统一入口(运行时计数 EnterAutomaticMode + 环境变量 TRANSPORTPLUGIN_TEST_AUTOMATION 兼容,可嵌套) - 自动模式下窗口自动选默认动作/跳过弹窗,保证自动测试与批处理流畅 接入点: - BatchQueueManager.ProcessQueueAsync 全程自动模式: 排除列表确认框 → 默认继续;完成汇总弹窗 → 跳过(日志保留) - ClashDetectiveIntegration.ShowCancellationMessage → 跳过 - CollisionAnalysisDialog.Loaded 自动关闭(并入统一机制) - AnimationControlViewModel:重复配置对话框默认创建新记录、 预计算分析跳过、重复检查跳过(3 处统一) - DialogHelper.ShowAutoClosingMessageBox → 统一判断 验证:集成测试 25/25、F1 批处理 2 分钟跑完 NW 零残留窗口 (EnumWindows 确认仅主窗口) --- TransportPlugin.csproj | 1 + src/Core/BatchQueueManager.cs | 23 +++++++- .../Collision/ClashDetectiveIntegration.cs | 7 +++ .../ViewModels/AnimationControlViewModel.cs | 7 ++- .../WPF/Views/CollisionAnalysisDialog.xaml.cs | 3 +- src/Utils/AutomationModeContext.cs | 59 +++++++++++++++++++ src/Utils/DialogHelper.cs | 2 +- 7 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 src/Utils/AutomationModeContext.cs diff --git a/TransportPlugin.csproj b/TransportPlugin.csproj index a899d66..8244912 100644 --- a/TransportPlugin.csproj +++ b/TransportPlugin.csproj @@ -339,6 +339,7 @@ + diff --git a/src/Core/BatchQueueManager.cs b/src/Core/BatchQueueManager.cs index 7fa8935..002ec97 100644 --- a/src/Core/BatchQueueManager.cs +++ b/src/Core/BatchQueueManager.cs @@ -11,6 +11,7 @@ using NavisworksTransport.Core.Collision; using NavisworksTransport.Core.Config; using NavisworksTransport.Core.Models; using NavisworksTransport.Core.Services; +using NavisworksTransport.Utils; namespace NavisworksTransport.Core { @@ -204,6 +205,9 @@ namespace NavisworksTransport.Core /// public async Task ProcessQueueAsync() { + // 自动模式:批处理全程窗口自动选择默认动作并立即关闭(排除列表确认/完成汇总/错误提示等) + using (AutomationModeContext.EnterAutomaticMode()) + { Autodesk.Navisworks.Api.Progress progress = null; // 统计信息 @@ -406,6 +410,7 @@ namespace NavisworksTransport.Core TimeSpan duration = endTime - startTime; ShowBatchSummary(startTime, endTime, duration, totalCount, successCount, failedCount, skippedCount); } + } } /// @@ -463,7 +468,14 @@ namespace NavisworksTransport.Core } LogManager.Info($"[批处理队列] 执行汇总 - 总计:{totalCount}, 成功:{successCount}, 失败:{failedCount}, 跳过:{skippedCount}, 耗时:{durationText}"); - + + // 自动模式下跳过完成弹窗(汇总已写入日志) + if (AutomationModeContext.IsAutomaticMode) + { + LogManager.Info("[批处理队列] 自动模式下跳过完成汇总弹窗"); + return; + } + // 在UI线程显示消息框 System.Windows.Application.Current?.Dispatcher.Invoke(() => { @@ -1043,7 +1055,14 @@ namespace NavisworksTransport.Core // 排除列表为空,提示用户 LogManager.Warning("[批处理队列] 排除列表为空,需要用户确认"); - + + // 自动模式下跳过确认框,默认继续(不使用排除列表) + if (AutomationModeContext.IsAutomaticMode) + { + LogManager.Info("[批处理队列] 自动模式下跳过排除列表确认,默认继续"); + return new List(); + } + bool shouldContinue = false; System.Windows.Application.Current?.Dispatcher.Invoke(() => { diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index 1df4de3..9935ac0 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -1305,6 +1305,13 @@ namespace NavisworksTransport /// private void ShowCancellationMessage() { + // 自动模式下跳过取消提示(日志已记录,避免残留弹窗阻塞自动化) + if (AutomationModeContext.IsAutomaticMode) + { + LogManager.Info("[ClashDetective] 自动模式下跳过检测取消提示框"); + return; + } + try { // 获取 Navisworks 主窗口句柄作为父窗口 diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 1d7858c..402c448 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -3623,7 +3623,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { try { - if (DialogHelper.IsTestAutomationModeEnabled) + if (AutomationModeContext.IsAutomaticMode) { LogManager.Info("[碰撞分析] 自动测试模式下跳过预计算碰撞分析"); SaveCollisionDetectionRecord(); @@ -3861,7 +3861,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels string routeId = CurrentPathRoute?.Id ?? ""; - if (!DialogHelper.IsTestAutomationModeEnabled) + if (!AutomationModeContext.IsAutomaticMode) { // 🔥 检查是否已有相同配置的检测记录 var existingRecordResult = CheckExistingDetectionRecord(); @@ -4154,7 +4154,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// private (int id, UserChoice userChoice)? ShowDuplicateConfigDialog(CollisionDetectionRecord record) { - if (TestAutomationHttpService.ShouldAutoChooseCreateNewDetectionRecord) + if (TestAutomationHttpService.ShouldAutoChooseCreateNewDetectionRecord || + AutomationModeContext.IsAutomaticMode) { _lastReusedRecordId = null; LogManager.Info($"[检测记录] 测试自动化已接管重复配置对话框,自动选择重新生成新记录 (ExistingId={record.Id})"); diff --git a/src/UI/WPF/Views/CollisionAnalysisDialog.xaml.cs b/src/UI/WPF/Views/CollisionAnalysisDialog.xaml.cs index 2096cba..54b6784 100644 --- a/src/UI/WPF/Views/CollisionAnalysisDialog.xaml.cs +++ b/src/UI/WPF/Views/CollisionAnalysisDialog.xaml.cs @@ -67,7 +67,8 @@ namespace NavisworksTransport.UI.WPF.Views private void CollisionAnalysisDialog_Loaded(object sender, RoutedEventArgs e) { - if (!TestAutomationHttpService.ShouldAutoConfirmCollisionAnalysisDialogs) + if (!TestAutomationHttpService.ShouldAutoConfirmCollisionAnalysisDialogs && + !AutomationModeContext.IsAutomaticMode) { return; } diff --git a/src/Utils/AutomationModeContext.cs b/src/Utils/AutomationModeContext.cs new file mode 100644 index 0000000..e71d81f --- /dev/null +++ b/src/Utils/AutomationModeContext.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading; + +namespace NavisworksTransport.Utils +{ + /// + /// 自动模式上下文(自动测试 / 批处理执行期间)。 + /// + /// 自动模式下: + /// - 窗口(对话框/提示框)自动选择默认动作并立即关闭(或直接跳过弹窗) + /// - 保证自动测试与批处理流畅进行,无需人工干预 + /// + /// 进入方式: + /// - 批处理执行(BatchQueueManager.ProcessQueueAsync)全程 + /// - 测试 HTTP 端点(TestAutomationHttpService 计数器,兼容保留) + /// - 环境变量 TRANSPORTPLUGIN_TEST_AUTOMATION=1(副实例/测试进程) + /// + public static class AutomationModeContext + { + private static int _requestCount; + + /// + /// 当前是否处于自动模式(任一来源生效:运行时计数 / 环境变量)。 + /// + public static bool IsAutomaticMode => + Interlocked.CompareExchange(ref _requestCount, 0, 0) > 0 || + DialogHelper.IsTestAutomationModeEnabled; + + /// + /// 进入自动模式(可嵌套),Dispose 时退出。 + /// + public static IDisposable EnterAutomaticMode() + { + Interlocked.Increment(ref _requestCount); + return new ActionOnDispose(() => + { + if (Interlocked.Decrement(ref _requestCount) < 0) + { + Interlocked.Exchange(ref _requestCount, 0); + } + }); + } + + private sealed class ActionOnDispose : IDisposable + { + private readonly Action _action; + + public ActionOnDispose(Action action) + { + _action = action; + } + + public void Dispose() + { + _action?.Invoke(); + } + } + } +} diff --git a/src/Utils/DialogHelper.cs b/src/Utils/DialogHelper.cs index ae9044d..b779edc 100644 --- a/src/Utils/DialogHelper.cs +++ b/src/Utils/DialogHelper.cs @@ -180,7 +180,7 @@ namespace NavisworksTransport.Utils MessageBoxImage icon = MessageBoxImage.Information, int autoCloseMilliseconds = 4000) { - if (IsTestAutomationModeEnabled) + if (AutomationModeContext.IsAutomaticMode) { LogManager.Info($"[DialogHelper] 自动测试模式下跳过自动关闭提示框: {caption}"); return;