diff --git a/.serena/cache/csharp/document_symbols_cache_v23-06-25.pkl b/.serena/cache/csharp/document_symbols_cache_v23-06-25.pkl
index 8eff30b..9e66a01 100644
Binary files a/.serena/cache/csharp/document_symbols_cache_v23-06-25.pkl and b/.serena/cache/csharp/document_symbols_cache_v23-06-25.pkl differ
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index 4e4f3c9..644afd5 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -193,6 +193,7 @@
+
diff --git a/SystemManagementViewModel_Design.cs b/SystemManagementViewModel_Design.cs
new file mode 100644
index 0000000..82d7ddf
--- /dev/null
+++ b/SystemManagementViewModel_Design.cs
@@ -0,0 +1,897 @@
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using System.Windows.Threading;
+
+namespace NavisworksTransport.UI.WPF.ViewModels
+{
+ ///
+ /// 系统管理ViewModel - 参照PathEditingViewModel的设计模式
+ /// 专门负责系统管理相关功能,包括:日志管理、设置管理、性能监控、版本控制、配置管理等
+ ///
+ public class SystemManagementViewModel : ViewModelBase
+ {
+ #region 私有字段
+
+ // 依赖注入的核心服务
+ private readonly UIStateManager _uiStateManager;
+
+ // 系统管理相关的管理器实例(通过依赖注入)
+ private ISystemLogManager _logManager;
+ private ISystemConfigManager _configManager;
+ private IPerformanceMonitor _performanceMonitor;
+ private IModelSplitterManager _modelSplitterManager;
+
+ // 日志管理相关字段
+ private ObservableCollection _logLevels;
+ private string _selectedLogLevel = "Info";
+ private string _logStatus = "日志系统正常";
+ private int _logEntryCount = 0;
+ private string _logFilePath = "未设置";
+
+ // 系统设置相关字段
+ private bool _isAutoSaveEnabled = true;
+ private bool _isDebugModeEnabled = false;
+ private string _settingsStatus = "设置已加载";
+ private int _autoSaveInterval = 300; // 秒
+ private string _workingDirectory = "";
+
+ // 版本和系统信息相关字段
+ private string _pluginVersion = "v1.0";
+ private string _navisworksVersion = "2026";
+ private string _systemStatus = "正常";
+ private string _systemStatusColor = "Green";
+ private string _lastUpdateCheck = "未检查";
+
+ // 性能监控相关字段
+ private string _memoryUsage = "0 MB";
+ private string _runningTime = "00:00:00";
+ private string _performanceInfo = "性能监控就绪";
+ private double _cpuUsage = 0.0;
+ private int _threadsCount = 0;
+ private DispatcherTimer _performanceTimer;
+
+ // 模型分割器相关字段
+ private string _modelSplitterStatus = "就绪";
+ private bool _canRunModelSplitter = true;
+ private string _lastSplitResult = "未执行";
+
+ // 配置管理相关字段
+ private string _currentConfigProfile = "默认配置";
+ private ObservableCollection _availableProfiles;
+ private bool _hasUnsavedChanges = false;
+
+ #endregion
+
+ #region 公共属性
+
+ #region 日志管理属性
+
+ ///
+ /// 可用日志级别集合
+ ///
+ public ObservableCollection LogLevels
+ {
+ get => _logLevels;
+ set => SetProperty(ref _logLevels, value);
+ }
+
+ ///
+ /// 选中的日志级别
+ ///
+ public string SelectedLogLevel
+ {
+ get => _selectedLogLevel;
+ set
+ {
+ if (SetProperty(ref _selectedLogLevel, value))
+ {
+ OnLogLevelChanged();
+ }
+ }
+ }
+
+ ///
+ /// 日志系统状态
+ ///
+ public string LogStatus
+ {
+ get => _logStatus;
+ set => SetProperty(ref _logStatus, value);
+ }
+
+ ///
+ /// 日志条目数量
+ ///
+ public int LogEntryCount
+ {
+ get => _logEntryCount;
+ set => SetProperty(ref _logEntryCount, value);
+ }
+
+ ///
+ /// 日志文件路径
+ ///
+ public string LogFilePath
+ {
+ get => _logFilePath;
+ set => SetProperty(ref _logFilePath, value);
+ }
+
+ #endregion
+
+ #region 系统设置属性
+
+ ///
+ /// 是否启用自动保存
+ ///
+ public bool IsAutoSaveEnabled
+ {
+ get => _isAutoSaveEnabled;
+ set
+ {
+ if (SetProperty(ref _isAutoSaveEnabled, value))
+ {
+ OnAutoSaveSettingChanged();
+ }
+ }
+ }
+
+ ///
+ /// 是否启用调试模式
+ ///
+ public bool IsDebugModeEnabled
+ {
+ get => _isDebugModeEnabled;
+ set
+ {
+ if (SetProperty(ref _isDebugModeEnabled, value))
+ {
+ OnDebugModeChanged();
+ }
+ }
+ }
+
+ ///
+ /// 设置状态
+ ///
+ public string SettingsStatus
+ {
+ get => _settingsStatus;
+ set => SetProperty(ref _settingsStatus, value);
+ }
+
+ ///
+ /// 自动保存间隔(秒)
+ ///
+ public int AutoSaveInterval
+ {
+ get => _autoSaveInterval;
+ set
+ {
+ if (SetProperty(ref _autoSaveInterval, value))
+ {
+ OnAutoSaveIntervalChanged();
+ }
+ }
+ }
+
+ ///
+ /// 工作目录
+ ///
+ public string WorkingDirectory
+ {
+ get => _workingDirectory;
+ set => SetProperty(ref _workingDirectory, value);
+ }
+
+ #endregion
+
+ #region 版本和系统信息属性
+
+ ///
+ /// 插件版本
+ ///
+ public string PluginVersion
+ {
+ get => _pluginVersion;
+ set => SetProperty(ref _pluginVersion, value);
+ }
+
+ ///
+ /// Navisworks版本
+ ///
+ public string NavisworksVersion
+ {
+ get => _navisworksVersion;
+ set => SetProperty(ref _navisworksVersion, value);
+ }
+
+ ///
+ /// 系统状态
+ ///
+ public string SystemStatus
+ {
+ get => _systemStatus;
+ set => SetProperty(ref _systemStatus, value);
+ }
+
+ ///
+ /// 系统状态颜色
+ ///
+ public string SystemStatusColor
+ {
+ get => _systemStatusColor;
+ set => SetProperty(ref _systemStatusColor, value);
+ }
+
+ ///
+ /// 最后更新检查时间
+ ///
+ public string LastUpdateCheck
+ {
+ get => _lastUpdateCheck;
+ set => SetProperty(ref _lastUpdateCheck, value);
+ }
+
+ #endregion
+
+ #region 性能监控属性
+
+ ///
+ /// 内存使用情况
+ ///
+ public string MemoryUsage
+ {
+ get => _memoryUsage;
+ set => SetProperty(ref _memoryUsage, value);
+ }
+
+ ///
+ /// 运行时间
+ ///
+ public string RunningTime
+ {
+ get => _runningTime;
+ set => SetProperty(ref _runningTime, value);
+ }
+
+ ///
+ /// 性能信息
+ ///
+ public string PerformanceInfo
+ {
+ get => _performanceInfo;
+ set => SetProperty(ref _performanceInfo, value);
+ }
+
+ ///
+ /// CPU使用率
+ ///
+ public double CpuUsage
+ {
+ get => _cpuUsage;
+ set => SetProperty(ref _cpuUsage, value);
+ }
+
+ ///
+ /// 线程数量
+ ///
+ public int ThreadsCount
+ {
+ get => _threadsCount;
+ set => SetProperty(ref _threadsCount, value);
+ }
+
+ #endregion
+
+ #region 模型分割器属性
+
+ ///
+ /// 模型分层拆分状态
+ ///
+ public string ModelSplitterStatus
+ {
+ get => _modelSplitterStatus;
+ set => SetProperty(ref _modelSplitterStatus, value);
+ }
+
+ ///
+ /// 是否可以运行模型分割器
+ ///
+ public bool CanRunModelSplitter
+ {
+ get => _canRunModelSplitter;
+ set => SetProperty(ref _canRunModelSplitter, value);
+ }
+
+ ///
+ /// 最后分割结果
+ ///
+ public string LastSplitResult
+ {
+ get => _lastSplitResult;
+ set => SetProperty(ref _lastSplitResult, value);
+ }
+
+ #endregion
+
+ #region 配置管理属性
+
+ ///
+ /// 当前配置档案
+ ///
+ public string CurrentConfigProfile
+ {
+ get => _currentConfigProfile;
+ set => SetProperty(ref _currentConfigProfile, value);
+ }
+
+ ///
+ /// 可用配置档案
+ ///
+ public ObservableCollection AvailableProfiles
+ {
+ get => _availableProfiles;
+ set => SetProperty(ref _availableProfiles, value);
+ }
+
+ ///
+ /// 是否有未保存的更改
+ ///
+ public bool HasUnsavedChanges
+ {
+ get => _hasUnsavedChanges;
+ set => SetProperty(ref _hasUnsavedChanges, value);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region 命令定义
+
+ // 日志管理命令
+ public ICommand ViewLogCommand { get; private set; }
+ public ICommand ClearLogCommand { get; private set; }
+ public ICommand ExportLogCommand { get; private set; }
+ public ICommand RefreshLogStatusCommand { get; private set; }
+
+ // 设置管理命令
+ public ICommand OpenSettingsCommand { get; private set; }
+ public ICommand ResetSettingsCommand { get; private set; }
+ public ICommand SaveSettingsCommand { get; private set; }
+ public ICommand LoadSettingsCommand { get; private set; }
+
+ // 配置管理命令
+ public ICommand ImportConfigCommand { get; private set; }
+ public ICommand ExportConfigCommand { get; private set; }
+ public ICommand CreateProfileCommand { get; private set; }
+ public ICommand DeleteProfileCommand { get; private set; }
+ public ICommand SwitchProfileCommand { get; private set; }
+
+ // 系统管理命令
+ public ICommand CheckUpdateCommand { get; private set; }
+ public ICommand RestartSystemCommand { get; private set; }
+ public ICommand SystemDiagnosticsCommand { get; private set; }
+
+ // 性能管理命令
+ public ICommand GeneratePerformanceReportCommand { get; private set; }
+ public ICommand StartPerformanceMonitoringCommand { get; private set; }
+ public ICommand StopPerformanceMonitoringCommand { get; private set; }
+ public ICommand ClearPerformanceDataCommand { get; private set; }
+
+ // 模型分割器命令
+ public ICommand RunModelSplitterCommand { get; private set; }
+ public ICommand ConfigureModelSplitterCommand { get; private set; }
+
+ #endregion
+
+ #region 构造函数
+
+ ///
+ /// 构造函数 - 参照PathEditingViewModel的设计模式
+ ///
+ /// 日志管理器(可选,用于依赖注入)
+ /// 配置管理器(可选,用于依赖注入)
+ /// 性能监控器(可选,用于依赖注入)
+ /// 模型分割器管理器(可选,用于依赖注入)
+ public SystemManagementViewModel(
+ ISystemLogManager logManager = null,
+ ISystemConfigManager configManager = null,
+ IPerformanceMonitor performanceMonitor = null,
+ IModelSplitterManager modelSplitterManager = null) : base()
+ {
+ try
+ {
+ // 获取UI状态管理器
+ _uiStateManager = UIStateManager.Instance;
+ if (_uiStateManager == null)
+ {
+ throw new InvalidOperationException("UIStateManager初始化失败");
+ }
+
+ // 设置依赖(如果为null则使用默认实现)
+ _logManager = logManager ?? CreateDefaultLogManager();
+ _configManager = configManager ?? CreateDefaultConfigManager();
+ _performanceMonitor = performanceMonitor ?? CreateDefaultPerformanceMonitor();
+ _modelSplitterManager = modelSplitterManager ?? CreateDefaultModelSplitterManager();
+
+ // 初始化集合
+ LogLevels = new ThreadSafeObservableCollection();
+ AvailableProfiles = new ThreadSafeObservableCollection();
+
+ // 初始化命令
+ InitializeCommands();
+
+ // 初始化系统管理设置(异步)
+ InitializeSystemManagementAsync();
+
+ LogManager.Info("SystemManagementViewModel构造函数执行完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex);
+ SystemStatus = "初始化失败,请检查日志";
+ SystemStatusColor = "Red";
+ throw;
+ }
+ }
+
+ #endregion
+
+ #region 初始化方法
+
+ ///
+ /// 初始化命令
+ ///
+ private void InitializeCommands()
+ {
+ // 日志管理命令
+ ViewLogCommand = new RelayCommand(async () => await ExecuteViewLogAsync());
+ ClearLogCommand = new RelayCommand(async () => await ExecuteClearLogAsync());
+ ExportLogCommand = new RelayCommand(async () => await ExecuteExportLogAsync());
+ RefreshLogStatusCommand = new RelayCommand(async () => await ExecuteRefreshLogStatusAsync());
+
+ // 设置管理命令
+ OpenSettingsCommand = new RelayCommand(async () => await ExecuteOpenSettingsAsync());
+ ResetSettingsCommand = new RelayCommand(async () => await ExecuteResetSettingsAsync());
+ SaveSettingsCommand = new RelayCommand(async () => await ExecuteSaveSettingsAsync());
+ LoadSettingsCommand = new RelayCommand(async () => await ExecuteLoadSettingsAsync());
+
+ // 配置管理命令
+ ImportConfigCommand = new RelayCommand(async () => await ExecuteImportConfigAsync());
+ ExportConfigCommand = new RelayCommand(async () => await ExecuteExportConfigAsync());
+ CreateProfileCommand = new RelayCommand(async () => await ExecuteCreateProfileAsync());
+ DeleteProfileCommand = new RelayCommand(async () => await ExecuteDeleteProfileAsync());
+ SwitchProfileCommand = new RelayCommand(async (profile) => await ExecuteSwitchProfileAsync(profile));
+
+ // 系统管理命令
+ CheckUpdateCommand = new RelayCommand(async () => await ExecuteCheckUpdateAsync());
+ RestartSystemCommand = new RelayCommand(async () => await ExecuteRestartSystemAsync());
+ SystemDiagnosticsCommand = new RelayCommand(async () => await ExecuteSystemDiagnosticsAsync());
+
+ // 性能管理命令
+ GeneratePerformanceReportCommand = new RelayCommand(async () => await ExecuteGeneratePerformanceReportAsync());
+ StartPerformanceMonitoringCommand = new RelayCommand(async () => await ExecuteStartPerformanceMonitoringAsync());
+ StopPerformanceMonitoringCommand = new RelayCommand(async () => await ExecuteStopPerformanceMonitoringAsync());
+ ClearPerformanceDataCommand = new RelayCommand(async () => await ExecuteClearPerformanceDataAsync());
+
+ // 模型分割器命令
+ RunModelSplitterCommand = new RelayCommand(async () => await ExecuteRunModelSplitterAsync(), () => CanRunModelSplitter);
+ ConfigureModelSplitterCommand = new RelayCommand(async () => await ExecuteConfigureModelSplitterAsync());
+ }
+
+ ///
+ /// 异步初始化系统管理设置
+ ///
+ private async void InitializeSystemManagementAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ await _uiStateManager.ExecuteUIUpdateAsync(() =>
+ {
+ // 初始化日志级别
+ LogLevels.Clear();
+ var logLevels = new[] { "Debug", "Info", "Warning", "Error" };
+ foreach (var level in logLevels)
+ {
+ LogLevels.Add(level);
+ }
+ SelectedLogLevel = "Info";
+
+ // 初始化配置档案
+ AvailableProfiles.Clear();
+ var profiles = new[] { "默认配置", "开发配置", "生产配置", "测试配置" };
+ foreach (var profile in profiles)
+ {
+ AvailableProfiles.Add(profile);
+ }
+ CurrentConfigProfile = "默认配置";
+
+ // 初始化系统信息
+ PluginVersion = GetPluginVersion();
+ NavisworksVersion = GetNavisworksVersion();
+ SystemStatus = "正常";
+ SystemStatusColor = "Green";
+ WorkingDirectory = GetWorkingDirectory();
+ LogFilePath = GetLogFilePath();
+ });
+
+ // 启动性能监控
+ await StartPerformanceMonitoring();
+
+ LogManager.Info("系统管理设置初始化完成");
+ }, "初始化系统管理设置");
+ }
+
+ #endregion
+
+ #region 命令实现
+
+ // 这里只展示架构框架,具体实现方法将在后续详细说明
+
+ #region 日志管理命令实现
+
+ private async Task ExecuteViewLogAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // TODO: 实现日志查看功能
+ await _logManager.OpenLogViewerAsync();
+ LogStatus = "日志查看器已打开";
+ }, "查看日志");
+ }
+
+ private async Task ExecuteClearLogAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // TODO: 实现日志清空功能
+ await _logManager.ClearLogsAsync();
+ LogEntryCount = 0;
+ LogStatus = "日志已清空";
+ }, "清空日志");
+ }
+
+ private async Task ExecuteExportLogAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // TODO: 实现日志导出功能
+ var exportPath = await _logManager.ExportLogsAsync();
+ LogStatus = $"日志已导出到: {exportPath}";
+ }, "导出日志");
+ }
+
+ private async Task ExecuteRefreshLogStatusAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // TODO: 实现日志状态刷新功能
+ var status = await _logManager.GetLogStatusAsync();
+ LogStatus = status.Message;
+ LogEntryCount = status.EntryCount;
+ LogFilePath = status.FilePath;
+ }, "刷新日志状态");
+ }
+
+ #endregion
+
+ // 其他命令实现方法...
+ // (这里省略具体实现,在实际代码中会完整实现)
+
+ #endregion
+
+ #region 事件处理
+
+ ///
+ /// 处理日志级别改变事件
+ ///
+ private void OnLogLevelChanged()
+ {
+ SafeExecute(() =>
+ {
+ _logManager?.SetLogLevel(SelectedLogLevel);
+ LogStatus = $"日志级别已设置为: {SelectedLogLevel}";
+ }, "设置日志级别");
+ }
+
+ ///
+ /// 处理自动保存设置改变事件
+ ///
+ private void OnAutoSaveSettingChanged()
+ {
+ SafeExecute(() =>
+ {
+ _configManager?.SetAutoSaveEnabled(IsAutoSaveEnabled);
+ SettingsStatus = $"自动保存: {(IsAutoSaveEnabled ? "已启用" : "已禁用")}";
+ HasUnsavedChanges = true;
+ }, "设置自动保存");
+ }
+
+ ///
+ /// 处理调试模式改变事件
+ ///
+ private void OnDebugModeChanged()
+ {
+ SafeExecute(() =>
+ {
+ _configManager?.SetDebugMode(IsDebugModeEnabled);
+ SettingsStatus = $"调试模式: {(IsDebugModeEnabled ? "已启用" : "已禁用")}";
+ HasUnsavedChanges = true;
+ }, "设置调试模式");
+ }
+
+ ///
+ /// 处理自动保存间隔改变事件
+ ///
+ private void OnAutoSaveIntervalChanged()
+ {
+ SafeExecute(() =>
+ {
+ _configManager?.SetAutoSaveInterval(AutoSaveInterval);
+ SettingsStatus = $"自动保存间隔: {AutoSaveInterval}秒";
+ HasUnsavedChanges = true;
+ }, "设置自动保存间隔");
+ }
+
+ #endregion
+
+ #region 辅助方法
+
+ ///
+ /// 安全执行异步操作
+ ///
+ private async Task SafeExecuteAsync(Func action, string operationName = "未知操作")
+ {
+ try
+ {
+ await action();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
+ SystemStatus = $"{operationName}失败: {ex.Message}";
+ SystemStatusColor = "Red";
+ }
+ }
+
+ ///
+ /// 安全执行同步操作
+ ///
+ private void SafeExecute(Action action, string operationName = "未知操作")
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
+ SystemStatus = $"{operationName}失败: {ex.Message}";
+ SystemStatusColor = "Red";
+ }
+ }
+
+ #endregion
+
+ #region 性能监控
+
+ ///
+ /// 启动性能监控
+ ///
+ private async Task StartPerformanceMonitoring()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ var startTime = DateTime.Now;
+
+ // 使用定时器更新性能信息
+ _performanceTimer = new DispatcherTimer();
+ _performanceTimer.Interval = TimeSpan.FromSeconds(5);
+ _performanceTimer.Tick += async (s, e) =>
+ {
+ try
+ {
+ await UpdatePerformanceInfo(startTime);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"性能监控更新失败: {ex.Message}");
+ }
+ };
+ _performanceTimer.Start();
+
+ PerformanceInfo = "性能监控已启动";
+ }, "启动性能监控");
+ }
+
+ ///
+ /// 更新性能信息
+ ///
+ private async Task UpdatePerformanceInfo(DateTime startTime)
+ {
+ await _uiStateManager.ExecuteUIUpdateAsync(() =>
+ {
+ // 更新内存使用
+ var process = Process.GetCurrentProcess();
+ var memoryMB = process.WorkingSet64 / (1024 * 1024);
+ MemoryUsage = $"{memoryMB} MB";
+
+ // 更新运行时间
+ var runTime = DateTime.Now - startTime;
+ RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}";
+
+ // 更新线程数
+ ThreadsCount = process.Threads.Count;
+
+ // 更新性能信息
+ PerformanceInfo = $"CPU: 正常, 内存: {memoryMB}MB, 线程: {ThreadsCount}, 运行时间: {RunningTime}";
+ });
+ }
+
+ #endregion
+
+ #region 默认实现创建方法
+
+ private ISystemLogManager CreateDefaultLogManager()
+ {
+ // TODO: 创建默认日志管理器实现
+ return new DefaultSystemLogManager();
+ }
+
+ private ISystemConfigManager CreateDefaultConfigManager()
+ {
+ // TODO: 创建默认配置管理器实现
+ return new DefaultSystemConfigManager();
+ }
+
+ private IPerformanceMonitor CreateDefaultPerformanceMonitor()
+ {
+ // TODO: 创建默认性能监控器实现
+ return new DefaultPerformanceMonitor();
+ }
+
+ private IModelSplitterManager CreateDefaultModelSplitterManager()
+ {
+ // TODO: 创建默认模型分割器管理器实现
+ return new DefaultModelSplitterManager();
+ }
+
+ #endregion
+
+ #region 系统信息获取方法
+
+ private string GetPluginVersion()
+ {
+ // TODO: 从程序集获取插件版本
+ return "v1.0";
+ }
+
+ private string GetNavisworksVersion()
+ {
+ // TODO: 从Navisworks API获取版本信息
+ return "2026";
+ }
+
+ private string GetWorkingDirectory()
+ {
+ // TODO: 获取当前工作目录
+ return Environment.CurrentDirectory;
+ }
+
+ private string GetLogFilePath()
+ {
+ // TODO: 获取日志文件路径
+ return Path.Combine(GetWorkingDirectory(), "Logs", "NavisworksTransport.log");
+ }
+
+ #endregion
+
+ #region 资源清理
+
+ ///
+ /// 清理资源
+ ///
+ public void Cleanup()
+ {
+ try
+ {
+ LogManager.Info("开始清理SystemManagementViewModel资源");
+
+ // 停止性能监控定时器
+ if (_performanceTimer != null)
+ {
+ _performanceTimer.Stop();
+ _performanceTimer = null;
+ }
+
+ // 清理管理器资源
+ _logManager?.Dispose();
+ _configManager?.Dispose();
+ _performanceMonitor?.Dispose();
+ _modelSplitterManager?.Dispose();
+
+ LogManager.Info("SystemManagementViewModel资源清理完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"SystemManagementViewModel清理失败: {ex.Message}");
+ }
+ }
+
+ #endregion
+ }
+}
+
+// 接口定义(这些接口将在单独的文件中定义)
+
+///
+/// 系统日志管理器接口
+///
+public interface ISystemLogManager : IDisposable
+{
+ Task OpenLogViewerAsync();
+ Task ClearLogsAsync();
+ Task ExportLogsAsync();
+ Task GetLogStatusAsync();
+ void SetLogLevel(string level);
+}
+
+///
+/// 系统配置管理器接口
+///
+public interface ISystemConfigManager : IDisposable
+{
+ void SetAutoSaveEnabled(bool enabled);
+ void SetDebugMode(bool enabled);
+ void SetAutoSaveInterval(int seconds);
+ Task SaveConfigAsync();
+ Task LoadConfigAsync();
+}
+
+///
+/// 性能监控器接口
+///
+public interface IPerformanceMonitor : IDisposable
+{
+ Task GetCurrentPerformanceAsync();
+ Task StartMonitoringAsync();
+ Task StopMonitoringAsync();
+}
+
+///
+/// 模型分割器管理器接口
+///
+public interface IModelSplitterManager : IDisposable
+{
+ Task RunModelSplitterAsync();
+ Task ConfigureAsync();
+ bool CanRun { get; }
+}
+
+///
+/// 日志状态数据结构
+///
+public class LogStatus
+{
+ public string Message { get; set; }
+ public int EntryCount { get; set; }
+ public string FilePath { get; set; }
+}
+
+///
+/// 性能数据结构
+///
+public class PerformanceData
+{
+ public double CpuUsage { get; set; }
+ public long MemoryUsage { get; set; }
+ public int ThreadCount { get; set; }
+ public TimeSpan RunningTime { get; set; }
+}
\ No newline at end of file
diff --git a/SystemManagement_Integration_Plan.md b/SystemManagement_Integration_Plan.md
new file mode 100644
index 0000000..d19a630
--- /dev/null
+++ b/SystemManagement_Integration_Plan.md
@@ -0,0 +1,457 @@
+# SystemManagementViewModel 集成方案
+
+## 1. 与LogisticsControlViewModel的解耦策略
+
+### 1.1 依赖关系处理
+
+**原始依赖关系问题:**
+- LogisticsControlViewModel 直接包含所有系统管理代码
+- UI更新、状态管理、业务逻辑混合在一起
+- 违反单一职责原则
+
+**解耦方案:**
+
+```csharp
+// 在LogisticsControlViewModel中
+public class LogisticsControlViewModel : ViewModelBase
+{
+ // 移除所有系统管理相关的字段和属性
+ // private string _modelSplitterStatus; // 删除
+ // private ObservableCollection _logLevels; // 删除
+ // ... 其他系统管理相关代码
+
+ // 添加SystemManagementViewModel的引用
+ private SystemManagementViewModel _systemManagementViewModel;
+
+ public SystemManagementViewModel SystemManagement
+ {
+ get => _systemManagementViewModel;
+ private set => SetProperty(ref _systemManagementViewModel, value);
+ }
+
+ public LogisticsControlViewModel() : base()
+ {
+ try
+ {
+ // 原有初始化代码...
+
+ // 初始化系统管理ViewModel
+ SystemManagement = new SystemManagementViewModel();
+
+ // 订阅系统管理事件(如果需要)
+ SubscribeToSystemManagementEvents();
+ }
+ catch (Exception ex)
+ {
+ // 错误处理
+ }
+ }
+
+ // 移除所有系统管理相关的方法
+ // private async Task InitializeSystemManagementSettingsAsync() // 删除
+ // private void ExecuteClearLog() // 删除
+ // private void ExecuteExportLog() // 删除
+ // ... 其他系统管理方法
+}
+```
+
+### 1.2 事件通信机制
+
+```csharp
+// 定义系统管理事件接口
+public interface ISystemManagementEvents
+{
+ event EventHandler SystemStatusChanged;
+ event EventHandler PerformanceAlert;
+ event EventHandler ConfigurationChanged;
+}
+
+// 在SystemManagementViewModel中实现事件发布
+public class SystemManagementViewModel : ViewModelBase, ISystemManagementEvents
+{
+ public event EventHandler SystemStatusChanged;
+ public event EventHandler PerformanceAlert;
+ public event EventHandler ConfigurationChanged;
+
+ // 触发系统状态变更事件
+ private void OnSystemStatusChanged(string newStatus, string color)
+ {
+ SystemStatusChanged?.Invoke(this, new SystemStatusChangedEventArgs
+ {
+ Status = newStatus,
+ StatusColor = color,
+ Timestamp = DateTime.Now
+ });
+ }
+
+ // 触发性能警告事件
+ private void OnPerformanceAlert(PerformanceAlertType alertType, string message)
+ {
+ PerformanceAlert?.Invoke(this, new PerformanceAlertEventArgs
+ {
+ AlertType = alertType,
+ Message = message,
+ Timestamp = DateTime.Now
+ });
+ }
+}
+
+// 在LogisticsControlViewModel中订阅事件
+private void SubscribeToSystemManagementEvents()
+{
+ if (SystemManagement != null)
+ {
+ SystemManagement.SystemStatusChanged += OnSystemStatusChanged;
+ SystemManagement.PerformanceAlert += OnPerformanceAlert;
+ SystemManagement.ConfigurationChanged += OnConfigurationChanged;
+ }
+}
+
+private void OnSystemStatusChanged(object sender, SystemStatusChangedEventArgs e)
+{
+ // 处理系统状态变更(如果主ViewModel需要知道)
+ // 例如:更新主界面的状态指示器
+ StatusText = $"系统状态: {e.Status}";
+}
+```
+
+## 2. UI集成策略
+
+### 2.1 XAML绑定方案
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 2.2 ViewModelLocator调整
+
+```csharp
+// 在ViewModelLocator中注册SystemManagementViewModel
+public class ViewModelLocator
+{
+ public LogisticsControlViewModel LogisticsControl => ServiceLocator.Current.GetInstance();
+
+ // 可以选择直接注册SystemManagementViewModel
+ public SystemManagementViewModel SystemManagement => ServiceLocator.Current.GetInstance();
+
+ static ViewModelLocator()
+ {
+ // 注册服务
+ ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
+
+ // 注册SystemManagementViewModel及其依赖
+ SimpleIoc.Default.Register();
+ SimpleIoc.Default.Register();
+ SimpleIoc.Default.Register();
+ SimpleIoc.Default.Register();
+
+ SimpleIoc.Default.Register();
+ SimpleIoc.Default.Register();
+ }
+}
+```
+
+## 3. 初始化和生命周期管理
+
+### 3.1 初始化顺序
+
+```csharp
+public class LogisticsControlViewModel : ViewModelBase
+{
+ private async void InitializeViewModelAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // 1. 先初始化核心组件
+ await UpdateInstructionTextAsync();
+ await UpdateSelectionDisplayAsync();
+ await InitializeCategoriesAsync();
+
+ // 2. 初始化系统管理ViewModel
+ await InitializeSystemManagementAsync();
+
+ // 3. 最后更新UI状态
+ await _uiStateManager.ExecuteUIUpdateAsync(() =>
+ {
+ StatusText = "插件已就绪";
+ AnimationStatus = "动画状态: 就绪";
+ AnimationProgress = 0;
+ WidthLimit = 3.0;
+ });
+
+ // 4. 初始化动画设置
+ await InitializeAnimationSettingsAsync();
+
+ LogManager.Info("LogisticsControlViewModel 初始化完成");
+ }, "初始化ViewModel");
+ }
+
+ private async Task InitializeSystemManagementAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ // 创建SystemManagementViewModel实例
+ SystemManagement = new SystemManagementViewModel(
+ logManager: ServiceProvider.GetService(),
+ configManager: ServiceProvider.GetService(),
+ performanceMonitor: ServiceProvider.GetService(),
+ modelSplitterManager: ServiceProvider.GetService()
+ );
+
+ // 订阅系统管理事件
+ SubscribeToSystemManagementEvents();
+
+ LogManager.Info("系统管理ViewModel初始化完成");
+ }, "初始化系统管理");
+ }
+}
+```
+
+### 3.2 清理机制
+
+```csharp
+public class LogisticsControlViewModel : ViewModelBase
+{
+ // 添加清理方法
+ public void Cleanup()
+ {
+ try
+ {
+ LogManager.Info("开始清理LogisticsControlViewModel资源");
+
+ // 清理系统管理ViewModel
+ if (SystemManagement != null)
+ {
+ UnsubscribeFromSystemManagementEvents();
+ SystemManagement.Cleanup();
+ SystemManagement = null;
+ }
+
+ // 原有的清理代码...
+
+ LogManager.Info("LogisticsControlViewModel资源清理完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"LogisticsControlViewModel清理失败: {ex.Message}");
+ }
+ }
+
+ private void UnsubscribeFromSystemManagementEvents()
+ {
+ if (SystemManagement != null)
+ {
+ SystemManagement.SystemStatusChanged -= OnSystemStatusChanged;
+ SystemManagement.PerformanceAlert -= OnPerformanceAlert;
+ SystemManagement.ConfigurationChanged -= OnConfigurationChanged;
+ }
+ }
+}
+```
+
+## 4. 命令重定向机制
+
+### 4.1 保持向后兼容性
+
+```csharp
+public class LogisticsControlViewModel : ViewModelBase
+{
+ // 保持原有命令接口,但重定向到SystemManagementViewModel
+ public ICommand ViewLogCommand => SystemManagement?.ViewLogCommand;
+ public ICommand ClearLogCommand => SystemManagement?.ClearLogCommand;
+ public ICommand ExportLogCommand => SystemManagement?.ExportLogCommand;
+ public ICommand OpenSettingsCommand => SystemManagement?.OpenSettingsCommand;
+ public ICommand ResetSettingsCommand => SystemManagement?.ResetSettingsCommand;
+ public ICommand ImportConfigCommand => SystemManagement?.ImportConfigCommand;
+ public ICommand CheckUpdateCommand => SystemManagement?.CheckUpdateCommand;
+ public ICommand GeneratePerformanceReportCommand => SystemManagement?.GeneratePerformanceReportCommand;
+
+ // 或者使用代理模式
+ private void InitializeCommandProxies()
+ {
+ ViewLogCommand = new RelayCommand(async () =>
+ {
+ if (SystemManagement != null)
+ await SystemManagement.ViewLogCommand.ExecuteAsync(null);
+ });
+
+ ClearLogCommand = new RelayCommand(async () =>
+ {
+ if (SystemManagement != null)
+ await SystemManagement.ClearLogCommand.ExecuteAsync(null);
+ });
+
+ // ... 其他命令代理
+ }
+}
+```
+
+## 5. 测试策略
+
+### 5.1 单元测试
+
+```csharp
+[TestFixture]
+public class SystemManagementViewModelTests
+{
+ private SystemManagementViewModel _viewModel;
+ private Mock _mockLogManager;
+ private Mock _mockConfigManager;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mockLogManager = new Mock();
+ _mockConfigManager = new Mock();
+
+ _viewModel = new SystemManagementViewModel(
+ _mockLogManager.Object,
+ _mockConfigManager.Object
+ );
+ }
+
+ [Test]
+ public async Task ExecuteViewLogAsync_ShouldCallLogManager()
+ {
+ // Arrange
+ _mockLogManager.Setup(x => x.OpenLogViewerAsync()).Returns(Task.CompletedTask);
+
+ // Act
+ await _viewModel.ViewLogCommand.ExecuteAsync(null);
+
+ // Assert
+ _mockLogManager.Verify(x => x.OpenLogViewerAsync(), Times.Once);
+ Assert.AreEqual("日志查看器已打开", _viewModel.LogStatus);
+ }
+}
+```
+
+### 5.2 集成测试
+
+```csharp
+[TestFixture]
+public class SystemManagementIntegrationTests
+{
+ [Test]
+ public void LogisticsControlViewModel_ShouldInitializeSystemManagement()
+ {
+ // Arrange & Act
+ var logisticsVM = new LogisticsControlViewModel();
+
+ // Assert
+ Assert.IsNotNull(logisticsVM.SystemManagement);
+ Assert.IsInstanceOf(logisticsVM.SystemManagement);
+ }
+
+ [Test]
+ public void SystemManagementEvents_ShouldPropagateToMainViewModel()
+ {
+ // Arrange
+ var logisticsVM = new LogisticsControlViewModel();
+ var systemManagementVM = logisticsVM.SystemManagement;
+ string receivedStatus = null;
+
+ logisticsVM.PropertyChanged += (s, e) =>
+ {
+ if (e.PropertyName == nameof(LogisticsControlViewModel.StatusText))
+ receivedStatus = logisticsVM.StatusText;
+ };
+
+ // Act
+ systemManagementVM.SystemStatus = "测试状态";
+ // 触发SystemStatusChanged事件
+
+ // Assert
+ Assert.IsTrue(receivedStatus?.Contains("测试状态"));
+ }
+}
+```
+
+## 6. 迁移计划
+
+### 6.1 分阶段迁移
+
+**阶段1:创建基础架构**
+1. 创建SystemManagementViewModel类
+2. 定义所需接口
+3. 创建默认实现类
+4. 设置依赖注入
+
+**阶段2:迁移核心功能**
+1. 迁移日志管理功能
+2. 迁移设置管理功能
+3. 迁移性能监控功能
+4. 测试基本功能
+
+**阶段3:集成和优化**
+1. 集成到LogisticsControlViewModel
+2. 调整UI绑定
+3. 实现事件通信
+4. 性能优化
+
+**阶段4:测试和部署**
+1. 全面测试
+2. 修复问题
+3. 文档更新
+4. 部署验证
+
+### 6.2 兼容性保证
+
+```csharp
+// 在迁移期间,保持旧接口可用
+public class LogisticsControlViewModel : ViewModelBase
+{
+ // 新的系统管理ViewModel
+ private SystemManagementViewModel _systemManagement;
+
+ // 保持旧属性兼容性(标记为过时)
+ [Obsolete("请使用SystemManagement.LogLevels", false)]
+ public ObservableCollection LogLevels => SystemManagement?.LogLevels;
+
+ [Obsolete("请使用SystemManagement.SelectedLogLevel", false)]
+ public string SelectedLogLevel
+ {
+ get => SystemManagement?.SelectedLogLevel;
+ set { if (SystemManagement != null) SystemManagement.SelectedLogLevel = value; }
+ }
+
+ // 保持旧命令兼容性
+ [Obsolete("请使用SystemManagement.ViewLogCommand", false)]
+ public ICommand ViewLogCommand => SystemManagement?.ViewLogCommand;
+}
+```
+
+这个解耦方案确保了:
+1. **清晰的职责分离**:系统管理功能完全独立
+2. **向后兼容性**:现有UI和代码不会立即失效
+3. **渐进式迁移**:可以分步骤进行迁移
+4. **良好的测试性**:每个组件都可以独立测试
+5. **事件驱动通信**:组件间通过事件解耦
\ No newline at end of file
diff --git a/SystemManagement_Services.cs b/SystemManagement_Services.cs
new file mode 100644
index 0000000..0381e1a
--- /dev/null
+++ b/SystemManagement_Services.cs
@@ -0,0 +1,744 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace NavisworksTransport.Core.SystemManagement
+{
+ #region 事件参数定义
+
+ ///
+ /// 系统状态变更事件参数
+ ///
+ public class SystemStatusChangedEventArgs : EventArgs
+ {
+ public string Status { get; set; }
+ public string StatusColor { get; set; }
+ public DateTime Timestamp { get; set; }
+ public string Details { get; set; }
+ }
+
+ ///
+ /// 性能警告事件参数
+ ///
+ public class PerformanceAlertEventArgs : EventArgs
+ {
+ public PerformanceAlertType AlertType { get; set; }
+ public string Message { get; set; }
+ public DateTime Timestamp { get; set; }
+ public double Value { get; set; }
+ public double Threshold { get; set; }
+ }
+
+ ///
+ /// 配置变更事件参数
+ ///
+ public class ConfigurationChangedEventArgs : EventArgs
+ {
+ public string ConfigKey { get; set; }
+ public object OldValue { get; set; }
+ public object NewValue { get; set; }
+ public string ProfileName { get; set; }
+ public DateTime Timestamp { get; set; }
+ }
+
+ ///
+ /// 性能警告类型枚举
+ ///
+ public enum PerformanceAlertType
+ {
+ MemoryHigh,
+ CpuHigh,
+ ThreadCountHigh,
+ ResponseTimeLow
+ }
+
+ #endregion
+
+ #region 数据模型
+
+ ///
+ /// 日志状态数据模型
+ ///
+ public class LogStatus
+ {
+ public string Message { get; set; }
+ public int EntryCount { get; set; }
+ public string FilePath { get; set; }
+ public DateTime LastUpdate { get; set; }
+ public long FileSizeBytes { get; set; }
+ public string CurrentLevel { get; set; }
+ }
+
+ ///
+ /// 性能数据模型
+ ///
+ public class PerformanceData
+ {
+ public double CpuUsage { get; set; }
+ public long MemoryUsageMB { get; set; }
+ public int ThreadCount { get; set; }
+ public TimeSpan RunningTime { get; set; }
+ public int HandleCount { get; set; }
+ public double ResponseTimeMs { get; set; }
+ public DateTime Timestamp { get; set; }
+ }
+
+ ///
+ /// 配置档案数据模型
+ ///
+ public class ConfigProfile
+ {
+ public string Name { get; set; }
+ public Dictionary Settings { get; set; }
+ public DateTime CreatedAt { get; set; }
+ public DateTime LastModified { get; set; }
+ public bool IsDefault { get; set; }
+ public string Description { get; set; }
+ }
+
+ #endregion
+
+ #region 系统日志管理器实现
+
+ ///
+ /// 默认系统日志管理器实现
+ ///
+ public class DefaultSystemLogManager : ISystemLogManager
+ {
+ private readonly string _logDirectory;
+ private readonly string _logFilePath;
+ private string _currentLogLevel = "Info";
+
+ public DefaultSystemLogManager()
+ {
+ _logDirectory = Path.Combine(Environment.CurrentDirectory, "Logs");
+ _logFilePath = Path.Combine(_logDirectory, "NavisworksTransport.log");
+
+ // 确保日志目录存在
+ if (!Directory.Exists(_logDirectory))
+ {
+ Directory.CreateDirectory(_logDirectory);
+ }
+ }
+
+ public async Task OpenLogViewerAsync()
+ {
+ await Task.Run(() =>
+ {
+ try
+ {
+ // 检查是否存在自定义日志查看器
+ var logViewerPath = Path.Combine(Environment.CurrentDirectory, "tools", "LogViewer.exe");
+
+ if (File.Exists(logViewerPath))
+ {
+ // 使用自定义日志查看器
+ Process.Start(logViewerPath, $"\"{_logFilePath}\"");
+ }
+ else if (File.Exists(_logFilePath))
+ {
+ // 使用默认文本编辑器打开
+ Process.Start("notepad.exe", _logFilePath);
+ }
+ else
+ {
+ MessageBox.Show("日志文件不存在", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"打开日志查看器失败: {ex.Message}", ex);
+ MessageBox.Show($"打开日志查看器失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ });
+ }
+
+ public async Task ClearLogsAsync()
+ {
+ await Task.Run(() =>
+ {
+ try
+ {
+ if (File.Exists(_logFilePath))
+ {
+ // 备份当前日志文件
+ var backupPath = Path.Combine(_logDirectory, $"backup_{DateTime.Now:yyyyMMdd_HHmmss}.log");
+ File.Move(_logFilePath, backupPath);
+
+ LogManager.Info("日志已清空,备份文件已创建");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"清空日志失败: {ex.Message}", ex);
+ throw;
+ }
+ });
+ }
+
+ public async Task ExportLogsAsync()
+ {
+ return await Task.Run(() =>
+ {
+ try
+ {
+ var exportDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "NavisworksTransport_Logs");
+ if (!Directory.Exists(exportDirectory))
+ {
+ Directory.CreateDirectory(exportDirectory);
+ }
+
+ var exportFileName = $"NavisworksTransport_Log_{DateTime.Now:yyyyMMdd_HHmmss}.zip";
+ var exportPath = Path.Combine(exportDirectory, exportFileName);
+
+ // 这里可以使用System.IO.Compression.ZipFile来创建压缩包
+ // 包含主日志文件和任何相关的日志文件
+ if (File.Exists(_logFilePath))
+ {
+ var singleLogExportPath = Path.Combine(exportDirectory, $"NavisworksTransport_Log_{DateTime.Now:yyyyMMdd_HHmmss}.log");
+ File.Copy(_logFilePath, singleLogExportPath);
+ return singleLogExportPath;
+ }
+
+ return exportPath;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"导出日志失败: {ex.Message}", ex);
+ throw;
+ }
+ });
+ }
+
+ public async Task GetLogStatusAsync()
+ {
+ return await Task.Run(() =>
+ {
+ try
+ {
+ var status = new LogStatus
+ {
+ FilePath = _logFilePath,
+ CurrentLevel = _currentLogLevel,
+ LastUpdate = DateTime.Now
+ };
+
+ if (File.Exists(_logFilePath))
+ {
+ var fileInfo = new FileInfo(_logFilePath);
+ status.FileSizeBytes = fileInfo.Length;
+ status.LastUpdate = fileInfo.LastWriteTime;
+
+ // 估算日志条目数量(简单实现)
+ var lines = File.ReadAllLines(_logFilePath);
+ status.EntryCount = lines.Length;
+ status.Message = $"日志文件正常,共 {status.EntryCount} 条记录";
+ }
+ else
+ {
+ status.EntryCount = 0;
+ status.FileSizeBytes = 0;
+ status.Message = "日志文件不存在";
+ }
+
+ return status;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"获取日志状态失败: {ex.Message}", ex);
+ return new LogStatus
+ {
+ Message = $"获取日志状态失败: {ex.Message}",
+ EntryCount = 0,
+ FilePath = _logFilePath,
+ CurrentLevel = _currentLogLevel
+ };
+ }
+ });
+ }
+
+ public void SetLogLevel(string level)
+ {
+ try
+ {
+ _currentLogLevel = level;
+ // 这里需要与实际的日志系统集成
+ LogManager.SetLogLevel(level);
+ LogManager.Info($"日志级别已设置为: {level}");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"设置日志级别失败: {ex.Message}", ex);
+ throw;
+ }
+ }
+
+ public void Dispose()
+ {
+ // 清理资源
+ LogManager.Info("SystemLogManager已清理");
+ }
+ }
+
+ #endregion
+
+ #region 系统配置管理器实现
+
+ ///
+ /// 默认系统配置管理器实现
+ ///
+ public class DefaultSystemConfigManager : ISystemConfigManager
+ {
+ private readonly string _configDirectory;
+ private readonly string _configFilePath;
+ private Dictionary _currentSettings;
+ private ConfigProfile _currentProfile;
+
+ public event EventHandler ConfigurationChanged;
+
+ public DefaultSystemConfigManager()
+ {
+ _configDirectory = Path.Combine(Environment.CurrentDirectory, "Config");
+ _configFilePath = Path.Combine(_configDirectory, "settings.json");
+ _currentSettings = new Dictionary();
+
+ // 确保配置目录存在
+ if (!Directory.Exists(_configDirectory))
+ {
+ Directory.CreateDirectory(_configDirectory);
+ }
+
+ // 加载默认配置
+ LoadDefaultSettings();
+ }
+
+ private void LoadDefaultSettings()
+ {
+ _currentSettings = new Dictionary
+ {
+ { "AutoSaveEnabled", true },
+ { "AutoSaveInterval", 300 },
+ { "DebugModeEnabled", false },
+ { "LogLevel", "Info" },
+ { "WorkingDirectory", Environment.CurrentDirectory },
+ { "MaxMemoryUsageMB", 1024 },
+ { "PerformanceMonitoringEnabled", true }
+ };
+
+ _currentProfile = new ConfigProfile
+ {
+ Name = "默认配置",
+ Settings = new Dictionary(_currentSettings),
+ CreatedAt = DateTime.Now,
+ LastModified = DateTime.Now,
+ IsDefault = true,
+ Description = "系统默认配置档案"
+ };
+ }
+
+ public void SetAutoSaveEnabled(bool enabled)
+ {
+ SetSetting("AutoSaveEnabled", enabled);
+ }
+
+ public void SetDebugMode(bool enabled)
+ {
+ SetSetting("DebugModeEnabled", enabled);
+ }
+
+ public void SetAutoSaveInterval(int seconds)
+ {
+ SetSetting("AutoSaveInterval", seconds);
+ }
+
+ private void SetSetting(string key, object value)
+ {
+ try
+ {
+ var oldValue = _currentSettings.ContainsKey(key) ? _currentSettings[key] : null;
+ _currentSettings[key] = value;
+
+ // 触发配置变更事件
+ ConfigurationChanged?.Invoke(this, new ConfigurationChangedEventArgs
+ {
+ ConfigKey = key,
+ OldValue = oldValue,
+ NewValue = value,
+ ProfileName = _currentProfile?.Name,
+ Timestamp = DateTime.Now
+ });
+
+ LogManager.Info($"配置项已更新: {key} = {value}");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"设置配置项失败 {key}: {ex.Message}", ex);
+ throw;
+ }
+ }
+
+ public async Task SaveConfigAsync()
+ {
+ await Task.Run(() =>
+ {
+ try
+ {
+ // 这里应该实现JSON序列化保存
+ // var json = JsonConvert.SerializeObject(_currentSettings, Formatting.Indented);
+ // File.WriteAllText(_configFilePath, json);
+
+ LogManager.Info("配置已保存到文件");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"保存配置失败: {ex.Message}", ex);
+ throw;
+ }
+ });
+ }
+
+ public async Task LoadConfigAsync()
+ {
+ await Task.Run(() =>
+ {
+ try
+ {
+ if (File.Exists(_configFilePath))
+ {
+ // var json = File.ReadAllText(_configFilePath);
+ // _currentSettings = JsonConvert.DeserializeObject>(json);
+ LogManager.Info("配置已从文件加载");
+ }
+ else
+ {
+ LoadDefaultSettings();
+ LogManager.Info("使用默认配置");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"加载配置失败: {ex.Message}", ex);
+ LoadDefaultSettings();
+ }
+ });
+ }
+
+ public T GetSetting(string key, T defaultValue = default(T))
+ {
+ try
+ {
+ if (_currentSettings.ContainsKey(key))
+ {
+ return (T)Convert.ChangeType(_currentSettings[key], typeof(T));
+ }
+ return defaultValue;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"获取配置项失败 {key}: {ex.Message}", ex);
+ return defaultValue;
+ }
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ // 自动保存配置
+ SaveConfigAsync().Wait(5000); // 等待最多5秒
+ LogManager.Info("SystemConfigManager已清理");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"SystemConfigManager清理失败: {ex.Message}", ex);
+ }
+ }
+ }
+
+ #endregion
+
+ #region 性能监控器实现
+
+ ///
+ /// 默认性能监控器实现
+ ///
+ public class DefaultPerformanceMonitor : IPerformanceMonitor
+ {
+ private readonly Process _currentProcess;
+ private bool _isMonitoring;
+ private readonly List _performanceHistory;
+ private readonly object _lockObject = new object();
+
+ public event EventHandler PerformanceAlert;
+
+ public DefaultPerformanceMonitor()
+ {
+ _currentProcess = Process.GetCurrentProcess();
+ _performanceHistory = new List();
+ _isMonitoring = false;
+ }
+
+ public async Task GetCurrentPerformanceAsync()
+ {
+ return await Task.Run(() =>
+ {
+ try
+ {
+ _currentProcess.Refresh();
+
+ var performanceData = new PerformanceData
+ {
+ MemoryUsageMB = _currentProcess.WorkingSet64 / (1024 * 1024),
+ ThreadCount = _currentProcess.Threads.Count,
+ HandleCount = _currentProcess.HandleCount,
+ RunningTime = DateTime.Now - _currentProcess.StartTime,
+ Timestamp = DateTime.Now,
+ CpuUsage = GetCpuUsage(), // 需要实现CPU使用率获取
+ ResponseTimeMs = GetResponseTime() // 需要实现响应时间测量
+ };
+
+ // 检查性能阈值
+ CheckPerformanceThresholds(performanceData);
+
+ lock (_lockObject)
+ {
+ _performanceHistory.Add(performanceData);
+
+ // 保持历史记录在合理范围内(最多保留1000条记录)
+ if (_performanceHistory.Count > 1000)
+ {
+ _performanceHistory.RemoveAt(0);
+ }
+ }
+
+ return performanceData;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"获取性能数据失败: {ex.Message}", ex);
+ throw;
+ }
+ });
+ }
+
+ private double GetCpuUsage()
+ {
+ // 简单实现,实际应该使用PerformanceCounter或更准确的方法
+ try
+ {
+ return _currentProcess.TotalProcessorTime.TotalMilliseconds / Environment.TickCount * 100;
+ }
+ catch
+ {
+ return 0.0;
+ }
+ }
+
+ private double GetResponseTime()
+ {
+ // 这里应该实现响应时间测量逻辑
+ // 可以通过测试关键操作的执行时间来获得
+ return 50.0; // 模拟值
+ }
+
+ private void CheckPerformanceThresholds(PerformanceData data)
+ {
+ // 内存使用率检查(超过512MB警告)
+ if (data.MemoryUsageMB > 512)
+ {
+ PerformanceAlert?.Invoke(this, new PerformanceAlertEventArgs
+ {
+ AlertType = PerformanceAlertType.MemoryHigh,
+ Message = $"内存使用量较高: {data.MemoryUsageMB}MB",
+ Value = data.MemoryUsageMB,
+ Threshold = 512,
+ Timestamp = DateTime.Now
+ });
+ }
+
+ // 线程数量检查(超过50个线程警告)
+ if (data.ThreadCount > 50)
+ {
+ PerformanceAlert?.Invoke(this, new PerformanceAlertEventArgs
+ {
+ AlertType = PerformanceAlertType.ThreadCountHigh,
+ Message = $"线程数量较多: {data.ThreadCount}个",
+ Value = data.ThreadCount,
+ Threshold = 50,
+ Timestamp = DateTime.Now
+ });
+ }
+
+ // CPU使用率检查(超过80%警告)
+ if (data.CpuUsage > 80)
+ {
+ PerformanceAlert?.Invoke(this, new PerformanceAlertEventArgs
+ {
+ AlertType = PerformanceAlertType.CpuHigh,
+ Message = $"CPU使用率较高: {data.CpuUsage:F1}%",
+ Value = data.CpuUsage,
+ Threshold = 80,
+ Timestamp = DateTime.Now
+ });
+ }
+ }
+
+ public async Task StartMonitoringAsync()
+ {
+ await Task.Run(() =>
+ {
+ _isMonitoring = true;
+ LogManager.Info("性能监控已启动");
+ });
+ }
+
+ public async Task StopMonitoringAsync()
+ {
+ await Task.Run(() =>
+ {
+ _isMonitoring = false;
+ LogManager.Info("性能监控已停止");
+ });
+ }
+
+ public List GetPerformanceHistory(TimeSpan? timeRange = null)
+ {
+ lock (_lockObject)
+ {
+ if (timeRange.HasValue)
+ {
+ var cutoffTime = DateTime.Now - timeRange.Value;
+ return _performanceHistory.Where(p => p.Timestamp >= cutoffTime).ToList();
+ }
+ return new List(_performanceHistory);
+ }
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ _isMonitoring = false;
+ _currentProcess?.Dispose();
+ LogManager.Info("PerformanceMonitor已清理");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"PerformanceMonitor清理失败: {ex.Message}", ex);
+ }
+ }
+ }
+
+ #endregion
+
+ #region 模型分割器管理器实现
+
+ ///
+ /// 默认模型分割器管理器实现
+ ///
+ public class DefaultModelSplitterManager : IModelSplitterManager
+ {
+ private bool _isRunning;
+ private string _outputDirectory;
+
+ public bool CanRun => !_isRunning && HasValidModel();
+
+ public DefaultModelSplitterManager()
+ {
+ _outputDirectory = Path.Combine(Environment.CurrentDirectory, "ModelSplitter", "Output");
+ if (!Directory.Exists(_outputDirectory))
+ {
+ Directory.CreateDirectory(_outputDirectory);
+ }
+ }
+
+ private bool HasValidModel()
+ {
+ try
+ {
+ // 检查Navisworks中是否有已加载的模型
+ var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
+ return document != null && document.Models != null && document.Models.Count > 0;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public async Task RunModelSplitterAsync()
+ {
+ if (!CanRun)
+ {
+ LogManager.Warning("模型分割器无法运行:条件不满足");
+ return false;
+ }
+
+ return await Task.Run(() =>
+ {
+ try
+ {
+ _isRunning = true;
+ LogManager.Info("开始模型分层拆分");
+
+ // 这里应该实现实际的模型分割逻辑
+ // 1. 获取当前Navisworks文档
+ // 2. 按照楼层、区域或其他标准进行分割
+ // 3. 导出各个分割后的模型
+
+ var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
+ if (document?.Models != null)
+ {
+ // 模拟分割过程
+ System.Threading.Thread.Sleep(2000);
+
+ // 实际实现中,这里会调用ModelSplitterManager的分割逻辑
+ // var splitterResult = ModelSplitterManager.SplitByFloors(document);
+
+ LogManager.Info("模型分层拆分完成");
+ return true;
+ }
+
+ return false;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"模型分割器运行失败: {ex.Message}", ex);
+ return false;
+ }
+ finally
+ {
+ _isRunning = false;
+ }
+ });
+ }
+
+ public async Task ConfigureAsync()
+ {
+ await Task.Run(() =>
+ {
+ try
+ {
+ // 这里可以打开模型分割器的配置对话框
+ // 或者加载配置设置
+ LogManager.Info("模型分割器配置界面已打开");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"配置模型分割器失败: {ex.Message}", ex);
+ }
+ });
+ }
+
+ public void Dispose()
+ {
+ _isRunning = false;
+ LogManager.Info("ModelSplitterManager已清理");
+ }
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/doc/design/2026/NavisworksAPI使用方法.md b/doc/design/2026/NavisworksAPI使用方法.md
index 2dafadb..139e041 100644
--- a/doc/design/2026/NavisworksAPI使用方法.md
+++ b/doc/design/2026/NavisworksAPI使用方法.md
@@ -482,7 +482,132 @@ public void BatchNavisworksOperations(List items)
8. **线程状态检查**:在关键操作前验证线程状态(STA)
9. **Dispatcher 模式**:后台线程中需要调用 API 时,始终使用 Dispatcher.Invoke
-## 11. 参考官方示例
+## 11. Transform 变换操作
+
+### 11.1 Transform 相关 API 概念
+
+**核心概念**:
+- `ModelItem.Transform` - 返回设计文件中的原始变换,只读属性
+- `OverridePermanentTransform()` - 应用增量变换(与现有变换叠加)
+- `ResetPermanentTransform()` - 清除所有增量变换,恢复到设计文件原始位置
+
+### 11.2 Transform 操作的正确用法
+
+```csharp
+// ✅ 获取物体的原始Transform(设计文件中的位置)
+Transform3D originalTransform = modelItem.Transform;
+
+// ✅ 应用增量变换(累积变换)
+var doc = Application.ActiveDocument;
+var modelItems = new ModelItemCollection { modelItem };
+doc.Models.OverridePermanentTransform(modelItems, newTransform, false);
+
+// ✅ 重置到原始位置(清除所有增量变换)
+doc.Models.ResetPermanentTransform(modelItems);
+```
+
+### 11.3 Transform 操作的关键区别
+
+| API方法 | 作用 | 使用场景 | 注意事项 |
+|---------|------|---------|---------|
+| `ModelItem.Transform` | 获取原始变换 | 记录物体初始位置 | 只读属性,返回设计文件位置 |
+| `OverridePermanentTransform()` | 应用增量变换 | 动画中移动物体 | 与现有变换累积,不是绝对位置 |
+| `ResetPermanentTransform()` | 重置到原始位置 | 清除所有移动,恢复初始状态 | 忽略所有之前的变换 |
+
+### 11.4 实际应用案例
+
+**案例1:动画系统中的Transform管理**
+```csharp
+// 动画开始时记录原始位置
+private Transform3D _originalTransform;
+
+public void StartAnimation(ModelItem animatedObject)
+{
+ // 记录原始Transform
+ _originalTransform = animatedObject.Transform;
+
+ // 移动到路径起点(增量变换)
+ var startTransform = Transform3D.CreateTranslation(startPosition);
+ var modelItems = new ModelItemCollection { animatedObject };
+ doc.Models.OverridePermanentTransform(modelItems, startTransform, false);
+}
+
+public void ResetAnimation()
+{
+ // 动画结束后,使用原始Transform恢复位置
+ var modelItems = new ModelItemCollection { _animatedObject };
+ doc.Models.OverridePermanentTransform(modelItems, _originalTransform, false);
+}
+```
+
+**案例2:用户手动位置恢复**
+```csharp
+public void RestoreToOriginalPosition(ModelItem selectedObject)
+{
+ // 不需要记录Transform,直接重置到设计文件原始位置
+ var doc = Application.ActiveDocument;
+ var modelItems = new ModelItemCollection { selectedObject };
+
+ // 清除所有增量变换,恢复到设计文件原始位置
+ doc.Models.ResetPermanentTransform(modelItems);
+}
+```
+
+### 11.5 常见Transform问题和解决方案
+
+**问题1:位置恢复有偏移**
+```csharp
+// ❌ 错误:使用增量变换恢复位置
+doc.Models.OverridePermanentTransform(modelItems, originalTransform, false);
+// 问题:如果物体已经被移动过,这会导致累积偏移
+
+// ✅ 正确:重置到原始位置
+doc.Models.ResetPermanentTransform(modelItems);
+// 结果:直接恢复到设计文件中的原始位置,无偏移
+```
+
+**问题2:动画结束后位置不准确**
+```csharp
+// ✅ 动画系统应该记录原始Transform并使用增量恢复
+private Transform3D _originalTransform;
+
+// 动画开始时
+_originalTransform = animatedObject.Transform;
+
+// 动画结束时恢复
+doc.Models.OverridePermanentTransform(modelItems, _originalTransform, false);
+```
+
+**问题3:记录Transform但不使用**
+```csharp
+// ❌ 不必要:记录Transform但使用Reset
+private Transform3D _originalTransform;
+_originalTransform = selectedItem.Transform; // 记录了但不使用
+doc.Models.ResetPermanentTransform(modelItems); // 直接重置
+
+// ✅ 简化:直接重置,无需记录
+doc.Models.ResetPermanentTransform(modelItems);
+```
+
+### 11.6 Transform 最佳实践
+
+1. **选择合适的恢复方式**:
+ - 动画系统:使用 `OverridePermanentTransform` + 原始Transform
+ - 用户操作:使用 `ResetPermanentTransform` 直接重置
+
+2. **避免不必要的Transform记录**:
+ - 如果只需要恢复到设计文件原始位置,使用 `ResetPermanentTransform`
+ - 只有需要恢复到特定中间状态时才记录Transform
+
+3. **理解增量vs绝对变换**:
+ - `OverridePermanentTransform` 是增量的,会与现有变换叠加
+ - `ResetPermanentTransform` 是绝对的,清除所有变换
+
+4. **线程安全**:
+ - 所有Transform操作都必须在主UI线程中执行
+ - 使用 `Dispatcher.Invoke` 确保线程安全
+
+## 12. 参考官方示例
强烈建议查看以下官方示例了解更多用法:
- `SearchComparisonPlugIn.cs` - 搜索性能对比
diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs
index 340c830..aa964f1 100644
--- a/src/Core/PathPlanningManager.cs
+++ b/src/Core/PathPlanningManager.cs
@@ -559,7 +559,7 @@ namespace NavisworksTransport
{
_pathPointMarkers?.Clear();
// 通知渲染插件更新显示
- _renderPlugin?.ClearPathMarkers();
+ _renderPlugin?.ClearAllPaths();
LogManager.Info("3D路径标记已清除");
}
catch (Exception ex)
@@ -591,11 +591,11 @@ namespace NavisworksTransport
}
}
- // 同时尝试通过坐标移除3D标记
- if (_renderPlugin != null)
+ // 重新渲染当前路径以反映更改
+ if (_renderPlugin != null && CurrentRoute != null)
{
- _renderPlugin.RemoveMarkerAt(point.Position, 2.0);
- LogManager.Info($"已从3D中移除路径点: {point.Name}");
+ _renderPlugin.RenderPath(CurrentRoute);
+ LogManager.Info($"已更新路径可视化: {point.Name}");
}
// 触发路径点移除事件
@@ -636,9 +636,49 @@ namespace NavisworksTransport
{
try
{
+ LogManager.WriteLog("[事件清理] ===== 开始执行StopClickTool - 完整事件订阅清理 =====");
+
+ // 1. 停用ToolPlugin并清理事件订阅
DeactivateToolPlugin();
+
+ // 2. 额外的事件订阅清理 - 确保所有可能的重复订阅都被清除
+ LogManager.WriteLog("[事件清理] 执行额外的事件订阅清理");
+ try
+ {
+ // 移除所有可能的OnToolPluginMouseClicked订阅
+ var mouseClickedEvent = typeof(PathClickToolPlugin).GetEvent("MouseClicked");
+ if (mouseClickedEvent != null)
+ {
+ var eventField = typeof(PathClickToolPlugin).GetField("MouseClicked",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
+ if (eventField != null)
+ {
+ var currentDelegate = (MulticastDelegate)eventField.GetValue(null);
+ if (currentDelegate != null)
+ {
+ var invocationList = currentDelegate.GetInvocationList();
+ LogManager.WriteLog($"[事件清理] 发现 {invocationList.Length} 个事件订阅者");
+
+ foreach (var handler in invocationList)
+ {
+ if (handler.Target == this && handler.Method.Name == "OnToolPluginMouseClicked")
+ {
+ PathClickToolPlugin.MouseClicked -= OnToolPluginMouseClicked;
+ LogManager.WriteLog($"[事件清理] 移除了PathPlanningManager.OnToolPluginMouseClicked订阅");
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception cleanupEx)
+ {
+ LogManager.WriteLog($"[事件清理] 额外清理过程异常: {cleanupEx.Message}");
+ }
+
+ // 3. 更新状态
PathEditState = PathEditState.None;
- LogManager.Info("点击工具已停止");
+ LogManager.WriteLog("[事件清理] ===== StopClickTool执行完成,所有事件订阅已清理 =====");
}
catch (Exception ex)
{
@@ -1068,13 +1108,11 @@ namespace NavisworksTransport
lastPoint.Type = PathPointType.EndPoint;
lastPoint.Name = GeneratePointName(PathPointType.EndPoint);
- // 更新3D标记类型
+ // 更新3D路径可视化
if (_renderPlugin != null)
{
- // 移除旧标记
- _renderPlugin.RemoveMarkerAt(lastPoint.Position, 2.0);
- // 添加终点标记
- _renderPlugin.AddCircleMarker(lastPoint.Position, PathPointType.EndPoint, CurrentRoute.Points.Count);
+ // 重新渲染整个路径以反映类型变更
+ _renderPlugin.RenderPath(CurrentRoute);
}
LogManager.Info($"已自动设置最后一个点为终点: {lastPoint.Name}");
@@ -1908,8 +1946,44 @@ namespace NavisworksTransport
private bool DeactivateToolPlugin()
{
- // TODO: 实现ToolPlugin停用逻辑
- return true;
+ if (!_isToolPluginActive)
+ {
+ LogManager.WriteLog("[ToolPlugin] ToolPlugin未激活,无需停用");
+ return true;
+ }
+
+ try
+ {
+ LogManager.WriteLog("[ToolPlugin] ===== 开始停用ToolPlugin =====");
+
+ // 1. 取消事件订阅
+ LogManager.WriteLog("[ToolPlugin] 步骤1: 取消事件订阅");
+ PathClickToolPlugin.MouseClicked -= OnToolPluginMouseClicked;
+ LogManager.WriteLog("[ToolPlugin] ✓ 事件订阅已取消");
+
+ // 2. 重置为无活动工具状态
+ LogManager.WriteLog("[ToolPlugin] 步骤2: 重置为默认工具");
+ try
+ {
+ // 使用Tool.None重置到无活动工具状态,让Navisworks处理默认导航
+ Application.MainDocument.Tool.Value = Tool.None;
+ LogManager.WriteLog("[ToolPlugin] ✓ 已重置工具为None状态");
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[ToolPlugin] 重置工具状态失败: {ex.Message}");
+ }
+
+ _isToolPluginActive = false;
+ LogManager.WriteLog("[ToolPlugin] ===== ToolPlugin停用完成 =====");
+ return true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[ToolPlugin] 停用异常: {ex.Message}");
+ LogManager.WriteLog($"[ToolPlugin] 堆栈: {ex.StackTrace}");
+ return false;
+ }
}
#endregion
@@ -2137,71 +2211,10 @@ namespace NavisworksTransport
return;
}
- if (isAutoPath)
- {
- // 自动路径可视化
- var sortedPoints = route.GetSortedPoints();
-
- // 安全显示自动路径,限制显示数量防止崩溃
- int maxDisplayPoints = Math.Min(10, sortedPoints.Count); // 最多显示10个点
- LogManager.Info($"安全显示自动路径: 原始{sortedPoints.Count}个点,限制显示{maxDisplayPoints}个点");
-
- if (sortedPoints.Count > maxDisplayPoints)
- {
- // 如果点太多,只显示起点、终点和几个中间点
- var displayPoints = new List
- {
- sortedPoints[0] // 起点
- };
-
- // 添加几个等间距的中间点
- for (int i = 1; i < maxDisplayPoints - 1; i++)
- {
- int index = (int)((double)i / (maxDisplayPoints - 1) * (sortedPoints.Count - 1));
- displayPoints.Add(sortedPoints[index]);
- }
-
- displayPoints.Add(sortedPoints[sortedPoints.Count - 1]); // 终点
-
- int displayIndex = 0;
- foreach (var point in displayPoints)
- {
- LogManager.Info($"[路径点{displayIndex}] 坐标: ({point.Position.X:F2}, {point.Position.Y:F2}, {point.Position.Z:F2})");
- renderPlugin.AddCircleMarker(point.Position, point.Type, -1000 - displayIndex);
- displayIndex++;
- }
-
- LogManager.Info($"已可视化自动路径: {route.Name},安全显示 {displayIndex} 个关键点和橙色连线");
- }
- else
- {
- // 点数较少时完整显示
- int displayIndex = 0;
- for (int i = 0; i < sortedPoints.Count; i++)
- {
- var point = sortedPoints[i];
- LogManager.Info($"[路径点{displayIndex}] 坐标: ({point.Position.X:F2}, {point.Position.Y:F2}, {point.Position.Z:F2})");
- renderPlugin.AddCircleMarker(point.Position, point.Type, -1000 - displayIndex);
- displayIndex++;
- }
-
- LogManager.Info($"已可视化自动路径: {route.Name},完整显示 {displayIndex} 个路径点和橙色连线");
- }
- }
- else
- {
- // 手工路径:完整显示,清除所有标记后重绘,使用黑色连线
- renderPlugin.ClearAllMarkers();
-
- var sortedPoints = route.GetSortedPoints();
- for (int i = 0; i < sortedPoints.Count; i++)
- {
- var point = sortedPoints[i];
- renderPlugin.AddCircleMarker(point.Position, point.Type, i + 1);
- }
-
- LogManager.Info($"已绘制路径: {route.Name},包含 {sortedPoints.Count} 个路径点和连线");
- }
+ // 使用新的统一路径渲染API
+ renderPlugin.RenderPath(route);
+
+ LogManager.Info($"已渲染路径: {route.Name},包含 {route.Points.Count} 个路径点");
}
catch (Exception ex)
{
diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs
index 2bce904..557b009 100644
--- a/src/Core/PathPointRenderPlugin.cs
+++ b/src/Core/PathPointRenderPlugin.cs
@@ -3,9 +3,96 @@ using System.Collections.Generic;
using System.Linq;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
+using NavisworksTransport.Core;
namespace NavisworksTransport
{
+ ///
+ /// 连线标记,用于渲染路径点之间的连接线
+ ///
+ public class LineMarker
+ {
+ ///
+ /// 连线起点
+ ///
+ public Point3D StartPoint { get; set; }
+
+ ///
+ /// 连线终点
+ ///
+ public Point3D EndPoint { get; set; }
+
+ ///
+ /// 连线颜色
+ ///
+ public Color Color { get; set; }
+
+ ///
+ /// 连线半径
+ ///
+ public double Radius { get; set; }
+
+ ///
+ /// 起点在路径中的索引
+ ///
+ public int FromIndex { get; set; }
+
+ ///
+ /// 终点在路径中的索引
+ ///
+ public int ToIndex { get; set; }
+
+ public override string ToString()
+ {
+ return $"LineMarker[{FromIndex}->{ToIndex}, 起点=({StartPoint.X:F2},{StartPoint.Y:F2},{StartPoint.Z:F2}), 终点=({EndPoint.X:F2},{EndPoint.Y:F2},{EndPoint.Z:F2})]";
+ }
+ }
+
+ ///
+ /// 路径可视化数据,包含一个完整路径的所有可视化元素
+ ///
+ public class PathVisualization
+ {
+ ///
+ /// 路径唯一标识
+ ///
+ public string PathId { get; set; }
+
+ ///
+ /// 路径数据引用
+ ///
+ public PathRoute PathRoute { get; set; }
+
+ ///
+ /// 点标记集合
+ ///
+ public List PointMarkers { get; set; }
+
+ ///
+ /// 连线标记集合
+ ///
+ public List LineMarkers { get; set; }
+
+ ///
+ /// 最后更新时间
+ ///
+ public DateTime LastUpdated { get; set; }
+
+ ///
+ /// 构造函数
+ ///
+ public PathVisualization()
+ {
+ PointMarkers = new List();
+ LineMarkers = new List();
+ LastUpdated = DateTime.Now;
+ }
+
+ public override string ToString()
+ {
+ return $"PathVisualization[PathId={PathId}, 点数={PointMarkers.Count}, 连线数={LineMarkers.Count}]";
+ }
+ }
///
/// 路径点圆形标记渲染插件
/// 使用Graphics.Circle在3D空间绘制圆形标记
@@ -14,9 +101,11 @@ namespace NavisworksTransport
public class PathPointRenderPlugin : RenderPlugin
{
private readonly object _lockObject = new object();
- private List _circleMarkers = new List();
+ private Dictionary _pathVisualizations = new Dictionary();
private bool _isEnabled = true;
- private int _lastAutoMarkersCount = -1; // 用于检测自动路径标记数量变化
+
+ // 为向后兼容保留的旧字段
+ private List _circleMarkers = new List();
// 静态实例,用于外部访问
private static PathPointRenderPlugin _instance;
@@ -52,7 +141,21 @@ namespace NavisworksTransport
}
///
- /// 当前圆形标记数量
+ /// 当前路径总数
+ ///
+ public int PathCount
+ {
+ get
+ {
+ lock (_lockObject)
+ {
+ return _pathVisualizations.Count;
+ }
+ }
+ }
+
+ ///
+ /// 当前点标记总数
///
public int MarkerCount
{
@@ -60,7 +163,7 @@ namespace NavisworksTransport
{
lock (_lockObject)
{
- return _circleMarkers.Count;
+ return _pathVisualizations.Values.Sum(v => v.PointMarkers.Count);
}
}
}
@@ -83,85 +186,38 @@ namespace NavisworksTransport
return; // 静默返回,避免日志泛滥
}
- // 检查是否有标记需要渲染
- int markerCount;
+ // 检查是否有路径需要渲染
+ int pathCount;
lock (_lockObject)
{
- markerCount = _circleMarkers.Count;
+ pathCount = _pathVisualizations.Count;
}
- if (markerCount == 0) return;
+ if (pathCount == 0) return;
// 使用BeginModelContext确保正确的渲染上下文
graphics.BeginModelContext();
- // 缓存转换系数,避免重复计算
- double lineRadiusInMeters = 0.2;
- double lineRadiusInModelUnits = lineRadiusInMeters * GetMetersToModelUnitsConversionFactor();
-
lock (_lockObject)
{
- // 优化:预过滤和排序,减少重复计算
- var manualMarkers = _circleMarkers.Where(m => m.SequenceNumber >= 0)
- .OrderBy(m => m.SequenceNumber)
- .ToArray(); // 转为数组提高性能
-
- var autoMarkers = _circleMarkers.Where(m => m.SequenceNumber < -999)
- .OrderByDescending(m => m.SequenceNumber)
- .ToArray();
-
- // 绘制连接线段(仅在有多个标记时)
- if (markerCount > 1)
+ foreach (var visualization in _pathVisualizations.Values)
{
- // 1. 绘制手动路径连线(正序号,黑色)
- if (manualMarkers.Length > 1)
+ // 渲染所有点标记
+ foreach (var pointMarker in visualization.PointMarkers)
{
- graphics.Color(Color.FromByteRGB(0, 0, 0), 1.0);
- for (int i = 0; i < manualMarkers.Length - 1; i++)
- {
- var current = manualMarkers[i];
- var next = manualMarkers[i + 1];
-
- // 只为连续序号的点绘制连线
- if (next.SequenceNumber == current.SequenceNumber + 1)
- {
- graphics.Cylinder(current.Center, next.Center, lineRadiusInModelUnits);
- }
- }
+ graphics.Color(pointMarker.Color, pointMarker.Alpha);
+ graphics.Sphere(pointMarker.Center, pointMarker.Radius);
}
-
- // 2. 绘制自动路径连线(负序号-1000系列,橙色)
- if (autoMarkers.Length > 1)
+
+ // 渲染所有连线
+ LogManager.WriteLog($"[渲染连线] 路径 {visualization.PathId} 有 {visualization.LineMarkers.Count} 条连线");
+ foreach (var lineMarker in visualization.LineMarkers)
{
- graphics.Color(Color.FromByteRGB(255, 165, 0), 1.0);
-
- // 只在标记数量变化时输出日志
- if (autoMarkers.Length != _lastAutoMarkersCount)
- {
- LogManager.WriteLog($"[自动路径连线] 找到 {autoMarkers.Length} 个自动路径标记");
- _lastAutoMarkersCount = autoMarkers.Length;
- }
-
- for (int i = 0; i < autoMarkers.Length - 1; i++)
- {
- var current = autoMarkers[i];
- var next = autoMarkers[i + 1];
-
- // 为连续负序号的点绘制连线
- if (current.SequenceNumber - next.SequenceNumber == 1)
- {
- graphics.Cylinder(current.Center, next.Center, lineRadiusInModelUnits);
- }
- }
+ graphics.Color(lineMarker.Color, 1.0);
+ graphics.Cylinder(lineMarker.StartPoint, lineMarker.EndPoint, lineMarker.Radius);
+ LogManager.WriteLog($"[渲染连线] 绘制连线 {lineMarker.FromIndex}->{lineMarker.ToIndex}, 半径={lineMarker.Radius:F3}");
}
}
-
- // 绘制所有球体标记(使用原始集合避免重复过滤)
- foreach (var marker in _circleMarkers)
- {
- graphics.Color(marker.Color, marker.Alpha);
- graphics.Sphere(marker.Center, marker.Radius);
- }
}
graphics.EndModelContext();
@@ -174,42 +230,371 @@ namespace NavisworksTransport
}
}
+ #region 新的统一路径可视化接口
+
///
- /// 添加球体标记
+ /// 渲染完整路径
///
- /// 圆心位置
- /// 路径点类型
- /// 序号
- public void AddCircleMarker(Point3D center, PathPointType pointType, int sequenceNumber)
+ /// 路径数据
+ public void RenderPath(PathRoute pathRoute)
{
+ if (pathRoute == null)
+ {
+ LogManager.WriteLog("[路径渲染] 路径数据为空");
+ return;
+ }
+
try
{
- var marker = new CircleMarker
- {
- Center = center,
- Normal = new Vector3D(0, 0, 1), // 垂直向上
- Radius = GetRadiusForPointType(pointType),
- Color = GetColorForPointType(pointType),
- Alpha = 1.0, // 完全不透明
- Filled = true, // 实心圆
- PointType = pointType,
- SequenceNumber = sequenceNumber,
- CreatedTime = DateTime.Now
+ var visualization = new PathVisualization
+ {
+ PathId = pathRoute.Id,
+ PathRoute = pathRoute
};
+ BuildVisualization(visualization);
+
lock (_lockObject)
{
- _circleMarkers.Add(marker);
+ _pathVisualizations[pathRoute.Id] = visualization;
}
- //LogManager.WriteLog($"[圆形标记] 添加圆形标记: 类型={pointType}, 序号={sequenceNumber}, 中心=({center.X:F2}, {center.Y:F2}, {center.Z:F2})");
-
- // 触发视图刷新
+ LogManager.WriteLog($"[路径渲染] 渲染路径: {pathRoute.Name}, 点数: {pathRoute.Points.Count}");
RequestViewRefresh();
}
catch (Exception ex)
{
- LogManager.WriteLog($"[圆形标记] 添加标记失败: {ex.Message}");
+ LogManager.WriteLog($"[路径渲染] 渲染路径失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 刷新路径可视化
+ ///
+ /// 路径ID
+ public void RefreshPath(string pathId)
+ {
+ lock (_lockObject)
+ {
+ if (_pathVisualizations.TryGetValue(pathId, out var visualization))
+ {
+ BuildVisualization(visualization);
+ LogManager.WriteLog($"[路径刷新] 刷新路径: {pathId}");
+ RequestViewRefresh();
+ }
+ }
+ }
+
+ ///
+ /// 移除路径
+ ///
+ /// 路径ID
+ public void RemovePath(string pathId)
+ {
+ lock (_lockObject)
+ {
+ if (_pathVisualizations.Remove(pathId))
+ {
+ LogManager.WriteLog($"[路径移除] 移除路径: {pathId}");
+ RequestViewRefresh();
+ }
+ }
+ }
+
+ ///
+ /// 清空所有路径
+ ///
+ public void ClearAllPaths()
+ {
+ lock (_lockObject)
+ {
+ var count = _pathVisualizations.Count;
+ _pathVisualizations.Clear();
+ LogManager.WriteLog($"[路径清空] 清空所有路径,共{count}个");
+ RequestViewRefresh();
+ }
+ }
+
+ ///
+ /// 构建路径可视化
+ ///
+ /// 路径可视化对象
+ private void BuildVisualization(PathVisualization visualization)
+ {
+ // 清空现有标记
+ visualization.PointMarkers.Clear();
+ visualization.LineMarkers.Clear();
+
+ var points = visualization.PathRoute.Points;
+ if (points.Count == 0) return;
+
+ // 按索引排序点
+ var sortedPoints = points.OrderBy(p => p.Index).ToList();
+
+ // 构建点标记
+ foreach (var point in sortedPoints)
+ {
+ var pointMarker = CreatePointMarker(point);
+ visualization.PointMarkers.Add(pointMarker);
+ }
+
+ // 构建连线标记(按排序后的顺序连接)
+ for (int i = 0; i < sortedPoints.Count - 1; i++)
+ {
+ var currentPoint = sortedPoints[i];
+ var nextPoint = sortedPoints[i + 1];
+
+ var lineMarker = new LineMarker
+ {
+ StartPoint = currentPoint.Position,
+ EndPoint = nextPoint.Position,
+ Color = GetLineColor(),
+ Radius = GetLineRadius(),
+ FromIndex = currentPoint.Index,
+ ToIndex = nextPoint.Index
+ };
+ visualization.LineMarkers.Add(lineMarker);
+
+ LogManager.WriteLog($"[连线构建] 创建连线: {currentPoint.Index} -> {nextPoint.Index}, " +
+ $"起点({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2}) -> " +
+ $"终点({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
+ }
+
+ visualization.LastUpdated = DateTime.Now;
+ }
+
+ ///
+ /// 创建点标记
+ ///
+ /// 路径点
+ /// 圆形标记
+ private CircleMarker CreatePointMarker(PathPoint point)
+ {
+ return new CircleMarker
+ {
+ Center = point.Position,
+ Normal = new Vector3D(0, 0, 1),
+ Radius = GetRadiusForPointType(point.Type),
+ Color = GetColorForPointType(point.Type),
+ Alpha = 1.0,
+ Filled = true,
+ PointType = point.Type,
+ SequenceNumber = point.Index, // 使用Index而不是任意序号
+ CreatedTime = DateTime.Now
+ };
+ }
+
+ ///
+ /// 获取连线颜色(统一使用橙色)
+ ///
+ /// 连线颜色
+ private Color GetLineColor()
+ {
+ return Color.FromByteRGB(255, 165, 0); // 统一使用橙色连线
+ }
+
+ ///
+ /// 获取连线半径
+ ///
+ /// 连线半径
+ private double GetLineRadius()
+ {
+ double lineRadiusInMeters = 0.2;
+ return lineRadiusInMeters * GetMetersToModelUnitsConversionFactor();
+ }
+
+ ///
+ /// 添加路径点到指定路径
+ ///
+ /// 路径ID
+ /// 新的路径点
+ /// 插入位置索引,-1表示添加到末尾
+ public void AddPointToPath(string pathId, PathPoint newPoint, int insertIndex = -1)
+ {
+ var visualization = GetPathVisualization(pathId);
+ if (visualization == null)
+ {
+ LogManager.WriteLog($"[路径编辑] 未找到路径: {pathId}");
+ return;
+ }
+
+ try
+ {
+ var pathRoute = visualization.PathRoute;
+
+ if (insertIndex == -1)
+ {
+ // 添加到末尾
+ newPoint.Index = pathRoute.Points.Count;
+ pathRoute.Points.Add(newPoint);
+ }
+ else
+ {
+ // 插入到指定位置
+ pathRoute.Points.Insert(insertIndex, newPoint);
+ // 重新分配所有点的索引
+ ReindexPoints(pathRoute);
+ }
+
+ // 重建可视化
+ BuildVisualization(visualization);
+ LogManager.WriteLog($"[路径编辑] 添加路径点: {newPoint.Name} 到路径 {pathId}");
+ RequestViewRefresh();
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[路径编辑] 添加路径点失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 从指定路径移除路径点
+ ///
+ /// 路径ID
+ /// 要移除的点索引
+ public void RemovePointFromPath(string pathId, int pointIndex)
+ {
+ var visualization = GetPathVisualization(pathId);
+ if (visualization == null)
+ {
+ LogManager.WriteLog($"[路径编辑] 未找到路径: {pathId}");
+ return;
+ }
+
+ try
+ {
+ var pathRoute = visualization.PathRoute;
+ var pointToRemove = pathRoute.Points.FirstOrDefault(p => p.Index == pointIndex);
+
+ if (pointToRemove != null)
+ {
+ pathRoute.Points.Remove(pointToRemove);
+ // 重新分配索引
+ ReindexPoints(pathRoute);
+
+ // 重建可视化
+ BuildVisualization(visualization);
+ LogManager.WriteLog($"[路径编辑] 移除路径点: 索引 {pointIndex} 从路径 {pathId}");
+ RequestViewRefresh();
+ }
+ else
+ {
+ LogManager.WriteLog($"[路径编辑] 未找到索引为 {pointIndex} 的路径点");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[路径编辑] 移除路径点失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 更新指定路径中的路径点
+ ///
+ /// 路径ID
+ /// 要更新的点索引
+ /// 更新后的路径点
+ public void UpdatePointInPath(string pathId, int pointIndex, PathPoint updatedPoint)
+ {
+ var visualization = GetPathVisualization(pathId);
+ if (visualization == null)
+ {
+ LogManager.WriteLog($"[路径编辑] 未找到路径: {pathId}");
+ return;
+ }
+
+ try
+ {
+ var pathRoute = visualization.PathRoute;
+ var existingPoint = pathRoute.Points.FirstOrDefault(p => p.Index == pointIndex);
+
+ if (existingPoint != null)
+ {
+ // 保持索引不变
+ updatedPoint.Index = pointIndex;
+
+ // 替换点
+ var index = pathRoute.Points.IndexOf(existingPoint);
+ pathRoute.Points[index] = updatedPoint;
+
+ // 重建可视化
+ BuildVisualization(visualization);
+ LogManager.WriteLog($"[路径编辑] 更新路径点: 索引 {pointIndex} 在路径 {pathId}");
+ RequestViewRefresh();
+ }
+ else
+ {
+ LogManager.WriteLog($"[路径编辑] 未找到索引为 {pointIndex} 的路径点");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[路径编辑] 更新路径点失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 重新分配路径点索引
+ ///
+ /// 路径对象
+ private void ReindexPoints(PathRoute pathRoute)
+ {
+ // 按照当前在List中的位置重新分配连续索引
+ for (int i = 0; i < pathRoute.Points.Count; i++)
+ {
+ pathRoute.Points[i].Index = i;
+ }
+ }
+
+ ///
+ /// 获取路径可视化对象
+ ///
+ /// 路径ID
+ /// 路径可视化对象,如果不存在返回null
+ private PathVisualization GetPathVisualization(string pathId)
+ {
+ lock (_lockObject)
+ {
+ _pathVisualizations.TryGetValue(pathId, out var visualization);
+ return visualization;
+ }
+ }
+
+ #endregion
+
+ #region 向后兼容的旧接口(保留以避免编译错误)
+
+ ///
+ /// [已过时] 添加球体标记 - 请使用RenderPath方法代替
+ ///
+ /// 圆心位置
+ /// 路径点类型
+ /// 序号
+ [Obsolete("此方法已过时,请使用RenderPath方法进行统一的路径可视化", false)]
+ public void AddCircleMarker(Point3D center, PathPointType pointType, int sequenceNumber)
+ {
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的AddCircleMarker方法,建议使用RenderPath方法");
+
+ try
+ {
+ // 为了兼容性,创建一个临时路径
+ var tempPath = new PathRoute($"TempPath_{Guid.NewGuid().ToString("N").Substring(0, 8)}")
+ {
+ Id = $"temp_{sequenceNumber}_{DateTime.Now.Ticks}"
+ };
+
+ var pathPoint = new PathPoint(center, $"Point_{sequenceNumber}", pointType)
+ {
+ Index = 0
+ };
+ tempPath.Points.Add(pathPoint);
+
+ // 使用新的渲染方法
+ RenderPath(tempPath);
+ }
+ catch (Exception ex)
+ {
+ LogManager.WriteLog($"[兼容性标记] 添加标记失败: {ex.Message}");
}
}
@@ -255,145 +640,58 @@ namespace NavisworksTransport
}
///
- /// 清除所有球体标记
+ /// [已过时] 清除所有球体标记 - 请使用ClearAllPaths方法代替
///
+ [Obsolete("此方法已过时,请使用ClearAllPaths方法", false)]
public void ClearAllMarkers()
{
- try
- {
- int removedCount = 0;
-
- lock (_lockObject)
- {
- removedCount = _circleMarkers.Count;
- _circleMarkers.Clear();
- }
-
- LogManager.WriteLog($"[球体标记] 清除所有标记,共移除 {removedCount} 个球体标记");
-
- if (removedCount > 0)
- {
- RequestViewRefresh();
- }
- }
- catch (Exception ex)
- {
- LogManager.WriteLog($"[球体标记] 清除标记失败: {ex.Message}");
- }
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的ClearAllMarkers方法,建议使用ClearAllPaths方法");
+ ClearAllPaths();
}
///
- /// 清除所有自动路径标记(序列号-1000系列)
+ /// [已过时] 清除所有自动路径标记 - 请使用ClearAllPaths方法代替
///
+ [Obsolete("此方法已过时,请使用ClearAllPaths方法", false)]
public void ClearAutoPathMarkers()
{
- try
- {
- int removedCount = 0;
-
- lock (_lockObject)
- {
- // 移除所有序列号小于-999的标记(自动路径标记)
- for (int i = _circleMarkers.Count - 1; i >= 0; i--)
- {
- var marker = _circleMarkers[i];
- if (marker.SequenceNumber < -999)
- {
- _circleMarkers.RemoveAt(i);
- removedCount++;
- }
- }
-
- // 重置自动路径标记计数
- _lastAutoMarkersCount = -1;
- }
-
- LogManager.WriteLog($"[球体标记] 清除自动路径标记,共移除 {removedCount} 个自动路径点");
-
- if (removedCount > 0)
- {
- RequestViewRefresh();
- }
- }
- catch (Exception ex)
- {
- LogManager.WriteLog($"[球体标记] 清除自动路径标记失败: {ex.Message}");
- }
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的ClearAutoPathMarkers方法,建议使用ClearAllPaths方法");
+ ClearAllPaths();
}
///
- /// 清除手动路径标记(序列号>=0)
+ /// [已过时] 清除手动路径标记 - 请使用ClearAllPaths方法代替
///
+ [Obsolete("此方法已过时,请使用ClearAllPaths方法", false)]
public void ClearManualPathMarkers()
{
- try
- {
- int removedCount = 0;
-
- lock (_lockObject)
- {
- // 移除所有序列号>=0的标记(手动路径标记)
- for (int i = _circleMarkers.Count - 1; i >= 0; i--)
- {
- var marker = _circleMarkers[i];
- if (marker.SequenceNumber >= 0)
- {
- _circleMarkers.RemoveAt(i);
- removedCount++;
- }
- }
- }
-
- LogManager.WriteLog($"[球体标记] 清除手动路径标记,共移除 {removedCount} 个手动路径点");
-
- if (removedCount > 0)
- {
- RequestViewRefresh();
- }
- }
- catch (Exception ex)
- {
- LogManager.WriteLog($"[球体标记] 清除手动路径标记失败: {ex.Message}");
- }
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的ClearManualPathMarkers方法,建议使用ClearAllPaths方法");
+ ClearAllPaths();
}
///
- /// 获取所有球体标记的副本
+ /// [已过时] 获取所有球体标记的副本 - 此方法不再适用于新的路径系统
///
- /// 标记列表
+ /// 空列表
+ [Obsolete("此方法已过时,新的路径系统不使用独立的标记概念", false)]
public List GetAllMarkers()
{
- lock (_lockObject)
- {
- return new List(_circleMarkers);
- }
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的GetAllMarkers方法,新系统不再支持独立标记");
+ return new List();
}
///
- /// 根据序号更新一个已存在的球体标记
+ /// [已过时] 根据序号更新一个已存在的球体标记 - 请使用UpdatePointInPath方法代替
///
+ [Obsolete("此方法已过时,请使用UpdatePointInPath方法更新路径中的点", false)]
public void UpdateMarker(int sequenceNumber, Color newColor, double newRadius)
{
- try
- {
- lock (_lockObject)
- {
- var markerToUpdate = _circleMarkers.FirstOrDefault(m => m.SequenceNumber == sequenceNumber);
- if (markerToUpdate != null)
- {
- markerToUpdate.Color = newColor;
- markerToUpdate.Radius = newRadius;
- LogManager.WriteLog($"[球体标记] 更新标记: 序号={sequenceNumber}, 新颜色={newColor}, 新半径={newRadius:F2}");
- RequestViewRefresh();
- }
- }
- }
- catch (Exception ex)
- {
- LogManager.WriteLog($"[球体标记] 更新标记失败: {ex.Message}");
- }
+ LogManager.WriteLog($"[兼容性警告] 使用了已过时的UpdateMarker方法,请使用UpdatePointInPath方法");
+ // 由于新系统没有直接的序号对应关系,这个方法不再有效
}
+ #endregion
+
#region 私有辅助方法
///
diff --git a/src/UI/WPF/LogisticsControlPanel.xaml b/src/UI/WPF/LogisticsControlPanel.xaml
index 939cca8..0dd91b6 100644
--- a/src/UI/WPF/LogisticsControlPanel.xaml
+++ b/src/UI/WPF/LogisticsControlPanel.xaml
@@ -31,34 +31,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/UI/WPF/LogisticsControlPanel.xaml.cs b/src/UI/WPF/LogisticsControlPanel.xaml.cs
index 422750b..0ea2dc6 100644
--- a/src/UI/WPF/LogisticsControlPanel.xaml.cs
+++ b/src/UI/WPF/LogisticsControlPanel.xaml.cs
@@ -15,6 +15,7 @@ namespace NavisworksTransport.UI.WPF
{
// ViewModel实例
public LogisticsControlViewModel ViewModel { get; private set; }
+ public SystemManagementViewModel SystemManagementViewModel { get; private set; }
// 分层管理视图
private LayerManagementView _layerManagementView;
@@ -32,7 +33,11 @@ namespace NavisworksTransport.UI.WPF
// 创建并设置ViewModel
ViewModel = new LogisticsControlViewModel();
+ SystemManagementViewModel = new SystemManagementViewModel();
DataContext = ViewModel;
+
+ // 为SystemManagementView设置独立的DataContext
+ SystemManagementView.DataContext = SystemManagementViewModel;
InitializeSession();
InitializeViews();
@@ -68,6 +73,9 @@ namespace NavisworksTransport.UI.WPF
// 初始化PathEditingView
InitializePathEditingView();
+
+ // 初始化SystemManagementView
+ InitializeSystemManagementView();
LogManager.Info("子视图初始化完成");
}
@@ -180,6 +188,24 @@ namespace NavisworksTransport.UI.WPF
LogManager.Error($"初始化PathEditingView失败: {ex.Message}");
}
}
+
+ ///
+ /// 初始化SystemManagementView
+ ///
+ private void InitializeSystemManagementView()
+ {
+ try
+ {
+ if (SystemManagementView?.DataContext != null)
+ {
+ LogManager.Info("SystemManagementView初始化完成");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"初始化SystemManagementView失败: {ex.Message}");
+ }
+ }
///
/// 初始化事件处理器
@@ -282,6 +308,9 @@ namespace NavisworksTransport.UI.WPF
// 清理PathEditingView
PathEditingView?.Cleanup();
+
+ // 清理SystemManagementViewModel
+ SystemManagementViewModel?.Cleanup();
// TODO: 清理路径规划管理器事件订阅
// 暂时注释掉,避免编译错误
diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs
index 692bdd9..78e439d 100644
--- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs
+++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs
@@ -60,6 +60,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private bool _hasSelectedAnimatedObject = false;
private bool _canGenerateAnimation = false;
private string _generationStatus = "就绪";
+
#endregion
@@ -856,6 +857,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
+ ///
+ /// 执行清除移动物体命令
+ ///
///
/// 执行清除移动物体命令
///
@@ -863,13 +867,44 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
try
{
+ LogManager.Info("开始清除移动物体选择并恢复原始位置");
+
+ // 如果有选中的物体,则恢复到原始位置
+ if (SelectedAnimatedObject != null)
+ {
+ try
+ {
+ LogManager.Info($"开始恢复物体 '{SelectedAnimatedObject.DisplayName}' 到原始位置");
+
+ // 使用ResetPermanentTransform清除所有增量变换,恢复到设计文件中的原始位置
+ var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
+ var modelItems = new ModelItemCollection { SelectedAnimatedObject };
+ doc.Models.ResetPermanentTransform(modelItems);
+
+ LogManager.Info($"物体 '{SelectedAnimatedObject.DisplayName}' 已成功恢复到原始位置");
+ GenerationStatus = "已清除移动物体选择并恢复到原始位置";
+ }
+ catch (Exception restoreEx)
+ {
+ LogManager.Error($"恢复物体到原始位置时发生错误: {restoreEx.Message}");
+ GenerationStatus = $"已清除物体选择,但恢复位置失败: {restoreEx.Message}";
+ }
+ }
+ else
+ {
+ LogManager.Info("没有选中的物体需要清除");
+ GenerationStatus = "已清除移动物体选择";
+ }
+
+ // 清理选择状态
SelectedAnimatedObject = null;
- GenerationStatus = "已清除移动物体选择";
- LogManager.Info("移动物体选择已清除");
+
+ LogManager.Info("移动物体选择已完全清除");
}
catch (Exception ex)
{
LogManager.Error($"清除移动物体选择时发生错误: {ex.Message}");
+ GenerationStatus = $"清除失败: {ex.Message}";
}
}
diff --git a/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs b/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
index 84438ae..fb343b2 100644
--- a/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
+++ b/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
@@ -61,21 +61,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private string _collisionStatus = "就绪";
private string _collisionSummary = "尚未运行碰撞检测";
- // 系统管理相关字段
- private string _modelSplitterStatus = "就绪";
- private ObservableCollection _logLevels;
- private string _selectedLogLevel = "Info";
- private string _logStatus = "日志系统正常";
- private bool _isAutoSaveEnabled = true;
- private bool _isDebugModeEnabled = false;
- private string _settingsStatus = "设置已加载";
- private string _pluginVersion = "v1.0";
- private string _navisworksVersion = "2026";
- private string _systemStatus = "正常";
- private string _systemStatusColor = "Green";
- private string _memoryUsage = "0 MB";
- private string _runningTime = "00:00:00";
- private string _performanceInfo = "性能监控就绪";
#endregion
@@ -341,135 +326,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#endregion
- #region 系统管理属性
-
- ///
- /// 模型分层拆分状态
- ///
- public string ModelSplitterStatus
- {
- get => _modelSplitterStatus;
- set => SetProperty(ref _modelSplitterStatus, value);
- }
-
- ///
- /// 日志级别集合
- ///
- public ObservableCollection LogLevels
- {
- get => _logLevels;
- set => SetProperty(ref _logLevels, value);
- }
-
- ///
- /// 选中的日志级别
- ///
- public string SelectedLogLevel
- {
- get => _selectedLogLevel;
- set => SetProperty(ref _selectedLogLevel, value);
- }
-
- ///
- /// 日志状态
- ///
- public string LogStatus
- {
- get => _logStatus;
- set => SetProperty(ref _logStatus, value);
- }
-
- ///
- /// 是否启用自动保存
- ///
- public bool IsAutoSaveEnabled
- {
- get => _isAutoSaveEnabled;
- set => SetProperty(ref _isAutoSaveEnabled, value);
- }
-
- ///
- /// 是否启用调试模式
- ///
- public bool IsDebugModeEnabled
- {
- get => _isDebugModeEnabled;
- set => SetProperty(ref _isDebugModeEnabled, value);
- }
-
- ///
- /// 设置状态
- ///
- public string SettingsStatus
- {
- get => _settingsStatus;
- set => SetProperty(ref _settingsStatus, value);
- }
-
- ///
- /// 插件版本
- ///
- public string PluginVersion
- {
- get => _pluginVersion;
- set => SetProperty(ref _pluginVersion, value);
- }
-
- ///
- /// Navisworks版本
- ///
- public string NavisworksVersion
- {
- get => _navisworksVersion;
- set => SetProperty(ref _navisworksVersion, value);
- }
-
- ///
- /// 系统状态
- ///
- public string SystemStatus
- {
- get => _systemStatus;
- set => SetProperty(ref _systemStatus, value);
- }
-
- ///
- /// 系统状态颜色
- ///
- public string SystemStatusColor
- {
- get => _systemStatusColor;
- set => SetProperty(ref _systemStatusColor, value);
- }
-
- ///
- /// 内存使用情况
- ///
- public string MemoryUsage
- {
- get => _memoryUsage;
- set => SetProperty(ref _memoryUsage, value);
- }
-
- ///
- /// 运行时间
- ///
- public string RunningTime
- {
- get => _runningTime;
- set => SetProperty(ref _runningTime, value);
- }
-
- ///
- /// 性能信息
- ///
- public string PerformanceInfo
- {
- get => _performanceInfo;
- set => SetProperty(ref _performanceInfo, value);
- }
-
- #endregion
#endregion
@@ -480,16 +336,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public ICommand StopAnimationCommand { get; private set; }
public ICommand RunCollisionDetectionCommand { get; private set; }
public ICommand ViewCollisionReportCommand { get; private set; }
- public ICommand ModelSplitterCommand { get; private set; }
public ICommand SetLogisticsAttributeCommand { get; private set; }
- public ICommand ViewLogCommand { get; private set; }
- public ICommand ClearLogCommand { get; private set; }
- public ICommand ExportLogCommand { get; private set; }
- public ICommand OpenSettingsCommand { get; private set; }
- public ICommand ResetSettingsCommand { get; private set; }
- public ICommand ImportConfigCommand { get; private set; }
- public ICommand CheckUpdateCommand { get; private set; }
- public ICommand GeneratePerformanceReportCommand { get; private set; }
#endregion
@@ -520,7 +367,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogisticsModels = new ThreadSafeObservableCollection();
AvailableCategories = new ThreadSafeObservableCollection();
AvailableFrameRates = new ThreadSafeObservableCollection();
- LogLevels = new ThreadSafeObservableCollection();
// 初始化命令(使用新的Command Pattern框架)
InitializeCommandsAsync();
@@ -563,8 +409,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 初始化动画参数
await InitializeAnimationSettingsAsync();
- // 初始化系统管理设置
- await InitializeSystemManagementSettingsAsync();
LogManager.Info("LogisticsControlViewModel 初始化完成");
}, "初始化ViewModel");
@@ -586,17 +430,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
RunCollisionDetectionCommand = new RelayCommand(async () => await ExecuteRunCollisionDetectionAsync(), () => CanRunCollisionDetection);
ViewCollisionReportCommand = new RelayCommand(async () => await ExecuteViewCollisionReportAsync(), () => HasCollisionResults);
- // 系统管理命令
- ModelSplitterCommand = new RelayCommand(async () => await ExecuteModelSplitterAsync());
+ // 物流属性命令
SetLogisticsAttributeCommand = new RelayCommand(async () => await ExecuteSetLogisticsAttributeAsync());
- ViewLogCommand = new RelayCommand(async () => await ExecuteViewLogAsync());
- ClearLogCommand = new RelayCommand(async () => await ExecuteClearLogAsync());
- ExportLogCommand = new RelayCommand(async () => await ExecuteExportLogAsync());
- OpenSettingsCommand = new RelayCommand(async () => await ExecuteOpenSettingsAsync());
- ResetSettingsCommand = new RelayCommand(async () => await ExecuteResetSettingsAsync());
- ImportConfigCommand = new RelayCommand(async () => await ExecuteImportConfigAsync());
- CheckUpdateCommand = new RelayCommand(async () => await ExecuteCheckUpdateAsync());
- GeneratePerformanceReportCommand = new RelayCommand(async () => await ExecuteGeneratePerformanceReportAsync());
LogManager.Info("命令初始化完成 - 使用新的异步Command Pattern框架");
}, "初始化命令");
@@ -644,71 +479,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
///
/// 初始化系统管理设置
///
- private async Task InitializeSystemManagementSettingsAsync()
- {
- await SafeExecuteAsync(async () =>
- {
- await _uiStateManager.ExecuteUIUpdateAsync(() =>
- {
- // 初始化日志级别
- LogLevels.Clear();
- var logLevels = new[] { "Debug", "Info", "Warning", "Error" };
- foreach (var level in logLevels)
- {
- LogLevels.Add(level);
- }
- SelectedLogLevel = "Info";
-
- // 初始化系统信息
- ModelSplitterStatus = "就绪";
- LogStatus = "日志系统正常";
- SettingsStatus = "设置已加载";
- PluginVersion = "v1.0";
- NavisworksVersion = "2026";
- SystemStatus = "正常";
- SystemStatusColor = "Green";
- });
-
- // 启动性能监控
- StartPerformanceMonitoring();
-
- LogManager.Info("系统管理设置初始化完成");
- }, "初始化系统管理设置");
- }
-
- ///
- /// 启动性能监控
- ///
- private void StartPerformanceMonitoring()
- {
- var startTime = DateTime.Now;
-
- // 使用定时器更新性能信息
- var timer = new System.Windows.Threading.DispatcherTimer();
- timer.Interval = TimeSpan.FromSeconds(5);
- timer.Tick += (s, e) =>
- {
- try
- {
- // 更新内存使用
- var process = System.Diagnostics.Process.GetCurrentProcess();
- var memoryMB = process.WorkingSet64 / (1024 * 1024);
- MemoryUsage = $"{memoryMB} MB";
-
- // 更新运行时间
- var runTime = DateTime.Now - startTime;
- RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}";
-
- // 更新性能信息
- PerformanceInfo = $"CPU: 正常, 内存: {memoryMB}MB, 运行时间: {RunningTime}";
- }
- catch (Exception ex)
- {
- LogManager.Error($"性能监控更新失败: {ex.Message}");
- }
- };
- timer.Start();
- }
#endregion
@@ -1057,126 +827,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
- private void ExecuteViewLog()
- {
- SafeExecute(() =>
- {
- // TODO: 实现日志查看功能
- StatusText = "打开日志查看器";
- LogManager.Info("查看日志");
- }, "查看日志");
- }
+
- private void ExecuteClearLog()
- {
- SafeExecute(() =>
- {
- // TODO: 实现日志清空功能
- LogStatus = "日志已清空";
- StatusText = "日志已清空";
- LogManager.Info("清空日志");
- }, "清空日志");
- }
+
- private void ExecuteExportLog()
- {
- SafeExecute(() =>
- {
- // TODO: 实现日志导出功能
- StatusText = "日志导出完成";
- LogManager.Info("导出日志");
- }, "导出日志");
- }
+
- private void ExecuteOpenSettings()
- {
- SafeExecute(() =>
- {
- // TODO: 实现设置对话框
- StatusText = "打开插件设置";
- LogManager.Info("打开设置");
- }, "打开设置");
- }
+
- private void ExecuteResetSettings()
- {
- SafeExecute(() =>
- {
- // TODO: 实现设置重置功能
- SettingsStatus = "设置已重置为默认值";
- IsAutoSaveEnabled = true;
- IsDebugModeEnabled = false;
- StatusText = "设置已重置";
- LogManager.Info("重置设置");
- }, "重置设置");
- }
+
- private void ExecuteImportConfig()
- {
- SafeExecute(() =>
- {
- // TODO: 实现配置导入功能
- StatusText = "配置导入完成";
- LogManager.Info("导入配置");
- }, "导入配置");
- }
+
- private void ExecuteCheckUpdate()
- {
- SafeExecute(() =>
- {
- StatusText = "正在检查更新...";
-
- // 模拟检查更新
- System.Threading.Tasks.Task.Run(() =>
- {
- System.Threading.Thread.Sleep(2000);
-
- System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- try
- {
- StatusText = "当前版本已是最新版本";
- }
- catch (Exception ex)
- {
- LogManager.Error($"更新检查UI更新失败: {ex.Message}");
- }
- }), System.Windows.Threading.DispatcherPriority.Background);
- });
-
- LogManager.Info("检查更新");
- }, "检查更新");
- }
+
- private void ExecuteGeneratePerformanceReport()
- {
- SafeExecute(() =>
- {
- StatusText = "正在生成性能报告...";
-
- // 模拟生成报告
- System.Threading.Tasks.Task.Run(() =>
- {
- System.Threading.Thread.Sleep(1500);
-
- System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- try
- {
- StatusText = "性能报告生成完成";
- PerformanceInfo = $"报告已生成 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
- }
- catch (Exception ex)
- {
- LogManager.Error($"性能报告UI更新失败: {ex.Message}");
- }
- }), System.Windows.Threading.DispatcherPriority.Background);
- });
-
- LogManager.Info("生成性能报告");
- }, "生成性能报告");
- }
+
///
/// 异步设置物流属性命令(使用UIStateManager和Command Pattern)
@@ -1267,18 +932,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
- #region 其他异步命令实现
- private async Task ExecuteModelSplitterAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteViewLogAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteClearLogAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteExportLogAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteOpenSettingsAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteResetSettingsAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteImportConfigAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteCheckUpdateAsync() { await Task.CompletedTask; /* TODO */ }
- private async Task ExecuteGeneratePerformanceReportAsync() { await Task.CompletedTask; /* TODO */ }
-
- #endregion
#region 自动路径规划命令实现
///
diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
index 69d8b1a..0ad1e78 100644
--- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs
+++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
@@ -310,6 +310,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
AutoPathStatus = "正在创建新路径...";
+ // 清除所有现有路径的可视化显示
+ if (PathPointRenderPlugin.Instance != null)
+ {
+ try
+ {
+ PathPointRenderPlugin.Instance.ClearAllPaths();
+ LogManager.Info("新建路径:已清除所有现有路径可视化显示");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"新建路径:清除现有路径可视化失败: {ex.Message}", ex);
+ throw; // 重新抛出异常,让上层处理
+ }
+ }
+
if (_pathPlanningManager != null)
{
var newRoute = _pathPlanningManager.StartCreatingNewRoute();
@@ -372,32 +387,36 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var pathName = SelectedPathRoute.Name;
AutoPathStatus = $"正在删除路径: {pathName}...";
- // 清理对应的3D可视化标记
+ // 清理当前路径的3D可视化显示(使用新的统一API)
if (PathPointRenderPlugin.Instance != null)
{
- if (pathName.StartsWith("自动路径_"))
+ try
{
- // 清除所有自动路径标记
- var allMarkers = PathPointRenderPlugin.Instance.GetAllMarkers();
- var autoPathMarkers = allMarkers.Where(m => m.SequenceNumber < -999).ToList();
-
- foreach (var marker in autoPathMarkers)
+ // 使用路径名找到对应的Core路径,获取其ID进行精确清理
+ string pathIdToRemove = null;
+ if (_pathPlanningManager != null)
{
- PathPointRenderPlugin.Instance.RemoveMarkerAt(marker.Center, 1.0);
- }
- }
- else
- {
- // 对于手动路径,清除对应序号的标记
- if (SelectedPathRoute.Points.Count > 0)
- {
- foreach (var point in SelectedPathRoute.Points)
+ var coreRoute = _pathPlanningManager.Routes.FirstOrDefault(r => r.Name == pathName);
+ if (coreRoute != null)
{
- var pointLocation = new Point3D(point.X, point.Y, point.Z);
- PathPointRenderPlugin.Instance.RemoveMarkerAt(pointLocation, 2.0);
+ pathIdToRemove = coreRoute.Id;
+ LogManager.Info($"删除路径:找到Core路径ID: {pathIdToRemove}");
+
+ // 使用新的API精确删除该路径
+ PathPointRenderPlugin.Instance.RemovePath(pathIdToRemove);
+ LogManager.Info($"删除路径:已清除路径 {pathName} (ID: {pathIdToRemove}) 的可视化显示");
+ }
+ else
+ {
+ LogManager.Warning($"删除路径:未找到路径 {pathName} 对应的Core路径,无法清理可视化");
}
}
}
+ catch (Exception ex)
+ {
+ LogManager.Error($"删除路径:清除路径可视化失败: {ex.Message}", ex);
+ throw; // 重新抛出异常,让上层处理
+ }
}
// 通知PathPlanningManager删除对应的路径
@@ -506,6 +525,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
AutoPathStatus = "正在计算最优路径...";
LogManager.Info("=== 开始执行自动路径规划 ===");
+ // 确保在开始自动路径规划前清理任何残留的事件订阅
+ LogManager.WriteLog("[自动路径规划] 规划前清理事件订阅状态");
+ CleanupAutoPathEventSubscriptions();
+ if (_pathPlanningManager != null)
+ {
+ _pathPlanningManager.StopClickTool();
+ }
+
// 调用PathPlanningManager的自动路径规划功能
var startPathPoint = new PathPoint
{
@@ -533,6 +560,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
LogManager.Info($"路径规划成功,共 {pathRoute.Points.Count} 个点");
+ // 自动路径规划完成后,执行完整的事件订阅清理
+ LogManager.WriteLog("[自动路径规划] 规划完成后清理事件订阅状态");
+ CleanupAutoPathEventSubscriptions();
+ if (_pathPlanningManager != null)
+ {
+ _pathPlanningManager.StopClickTool();
+ }
+
// 不在这里直接操作UI,让RouteGenerated事件处理UI更新
// 这避免了重复的路径添加和UI更新冲突
@@ -543,6 +578,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
AutoPathStatus = "❌ 路径规划失败,未找到可行路径";
LogManager.Warning("自动路径规划失败:未找到可行路径");
+
+ // 失败情况下也要清理事件订阅
+ CleanupAutoPathEventSubscriptions();
+ if (_pathPlanningManager != null)
+ {
+ _pathPlanningManager.StopClickTool();
+ }
}
}, "自动路径规划");
}
@@ -561,35 +603,18 @@ namespace NavisworksTransport.UI.WPF.ViewModels
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
}
- // 清除3D标记
+ // 清除所有路径可视化(使用新的统一API)
if (PathPointRenderPlugin.Instance != null)
{
- if (_hasStartPoint)
- {
- PathPointRenderPlugin.Instance.RemoveMarkerAt(_startPoint3D, 2.0);
- }
- if (_hasEndPoint)
- {
- PathPointRenderPlugin.Instance.RemoveMarkerAt(_endPoint3D, 2.0);
- }
-
- // 清除自动路径规划生成的所有中间路径点标记(序号为-1000及以下)
try
{
- var allMarkers = PathPointRenderPlugin.Instance.GetAllMarkers();
- var autoPathMarkers = allMarkers.Where(m => m.SequenceNumber <= -1000).ToList();
-
- LogManager.Info($"找到 {autoPathMarkers.Count} 个自动路径标记需要清除");
-
- foreach (var marker in autoPathMarkers)
- {
- PathPointRenderPlugin.Instance.RemoveMarkerAt(marker.Center, 1.0);
- LogManager.Info($"已清除自动路径标记: 序号{marker.SequenceNumber}, 位置({marker.Center.X:F2}, {marker.Center.Y:F2}, {marker.Center.Z:F2})");
- }
+ PathPointRenderPlugin.Instance.ClearAllPaths();
+ LogManager.Info("重置参数:已清除所有路径可视化显示");
}
catch (Exception ex)
{
- LogManager.Warning($"清除自动路径标记时出现异常: {ex.Message}");
+ LogManager.Error($"重置参数:清除路径可视化失败: {ex.Message}", ex);
+ throw; // 重新抛出异常,让上层处理
}
}
@@ -777,49 +802,61 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
try
{
- if (pickResult == null) return;
+ LogManager.WriteLog("[自动路径事件] ===== OnAutoPathMouseClicked被调用 =====");
+
+ if (pickResult == null)
+ {
+ LogManager.WriteLog("[自动路径事件] pickResult为null,退出处理");
+ return;
+ }
var point3D = pickResult.Point;
- LogManager.Info($"接收到点击事件: ({point3D.X:F2}, {point3D.Y:F2}, {point3D.Z:F2})");
+ LogManager.WriteLog($"[自动路径事件] 接收到点击事件: ({point3D.X:F2}, {point3D.Y:F2}, {point3D.Z:F2})");
+ LogManager.WriteLog($"[自动路径事件] IsSelectingStartPoint: {IsSelectingStartPoint}, IsSelectingEndPoint: {IsSelectingEndPoint}");
if (IsSelectingStartPoint)
{
+ LogManager.WriteLog("[自动路径事件] 设置起点并停止点击工具");
SetAutoPathStartPoint(point3D);
await SafeExecuteAsync(() =>
{
- _pathPlanningManager.StopClickTool();
- PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
+ CleanupAutoPathEventSubscriptions();
+ _pathPlanningManager?.StopClickTool();
}, "停止起点选择工具");
}
else if (IsSelectingEndPoint)
{
+ LogManager.WriteLog("[自动路径事件] 设置终点并停止点击工具");
SetAutoPathEndPoint(point3D);
await SafeExecuteAsync(() =>
{
- _pathPlanningManager.StopClickTool();
- PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
+ CleanupAutoPathEventSubscriptions();
+ _pathPlanningManager?.StopClickTool();
}, "停止终点选择工具");
}
else
{
- PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
+ LogManager.WriteLog("[自动路径事件] 非选择状态,直接清理事件订阅");
+ CleanupAutoPathEventSubscriptions();
}
}
catch (Exception ex)
{
- LogManager.Error($"处理自动路径规划点击事件时发生错误: {ex.Message}");
+ LogManager.Error($"[自动路径事件] 处理点击事件异常: {ex.Message}");
AutoPathStatus = $"获取点击位置失败: {ex.Message}";
IsSelectingStartPoint = false;
IsSelectingEndPoint = false;
- if (_pathPlanningManager != null)
+ // 异常情况下也要清理事件订阅
+ try
{
- await SafeExecuteAsync(() =>
- {
- _pathPlanningManager.StopClickTool();
- PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
- }, "清理点击工具状态");
+ CleanupAutoPathEventSubscriptions();
+ _pathPlanningManager?.StopClickTool();
+ }
+ catch (Exception cleanupEx)
+ {
+ LogManager.Error($"[自动路径事件] 清理异常: {cleanupEx.Message}");
}
}
}
@@ -920,6 +957,52 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
+ ///
+ /// 清理自动路径相关的事件订阅
+ ///
+ private void CleanupAutoPathEventSubscriptions()
+ {
+ try
+ {
+ LogManager.WriteLog("[事件清理] 开始清理自动路径事件订阅");
+
+ // 移除所有可能的OnAutoPathMouseClicked订阅
+ PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
+
+ // 使用反射检查并清理重复订阅
+ var mouseClickedEvent = typeof(PathClickToolPlugin).GetEvent("MouseClicked");
+ if (mouseClickedEvent != null)
+ {
+ var eventField = typeof(PathClickToolPlugin).GetField("MouseClicked",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
+ if (eventField != null)
+ {
+ var currentDelegate = (MulticastDelegate)eventField.GetValue(null);
+ if (currentDelegate != null)
+ {
+ var invocationList = currentDelegate.GetInvocationList();
+ LogManager.WriteLog($"[事件清理] 发现 {invocationList.Length} 个事件订阅者");
+
+ foreach (var handler in invocationList)
+ {
+ if (handler.Target == this && handler.Method.Name == "OnAutoPathMouseClicked")
+ {
+ PathClickToolPlugin.MouseClicked -= (EventHandler)handler;
+ LogManager.WriteLog($"[事件清理] 移除了PathEditingViewModel.OnAutoPathMouseClicked订阅");
+ }
+ }
+ }
+ }
+ }
+
+ LogManager.WriteLog("[事件清理] 自动路径事件订阅清理完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"[事件清理] 清理自动路径事件订阅失败: {ex.Message}");
+ }
+ }
+
#endregion
#region PathPlanningManager事件处理
@@ -1318,14 +1401,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 取消事件订阅
UnsubscribeFromPathPlanningManager();
- // 清理自动路径规划相关的事件订阅
+ // 完整清理自动路径规划相关的事件订阅
try
{
- PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
+ CleanupAutoPathEventSubscriptions();
}
catch (Exception ex)
{
- LogManager.Warning($"取消PathClickToolPlugin.MouseClicked事件订阅时发生异常: {ex.Message}");
+ LogManager.Warning($"清理自动路径事件订阅时发生异常: {ex.Message}");
+ }
+
+ // 确保停止任何活动的点击工具
+ try
+ {
+ if (_pathPlanningManager != null)
+ {
+ _pathPlanningManager.StopClickTool();
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Warning($"停止点击工具时发生异常: {ex.Message}");
}
LogManager.Info("PathEditingViewModel资源清理完成");
diff --git a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
new file mode 100644
index 0000000..2a7c227
--- /dev/null
+++ b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
@@ -0,0 +1,534 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using NavisworksTransport.UI.WPF.ViewModels;
+using NavisworksTransport.UI.WPF.Collections;
+using NavisworksTransport.Core;
+using NavisworksTransport.Utils;
+using NavisworksTransport.Commands;
+
+namespace NavisworksTransport.UI.WPF.ViewModels
+{
+ ///
+ /// 系统管理ViewModel - 处理插件系统管理功能
+ ///
+ public class SystemManagementViewModel : ViewModelBase
+ {
+ #region 私有字段
+
+ private readonly UIStateManager _uiStateManager;
+
+ // 系统管理相关字段
+ private bool _isAutoSaveEnabled = true;
+ private bool _isDebugModeEnabled = false;
+ private ObservableCollection _logLevels;
+ private string _selectedLogLevel = "Info";
+ private string _logStatus = "日志系统正常";
+ private string _pluginVersion = "v1.0";
+ private string _navisworksVersion = "2026";
+ private string _settingsStatus = "设置已加载";
+ private string _systemStatus = "正常";
+ private string _systemStatusColor = "Green";
+ private string _memoryUsage = "0 MB";
+ private string _runningTime = "00:00:00";
+ private string _performanceInfo = "性能监控就绪";
+
+ #endregion
+
+ #region 公共属性
+
+ ///
+ /// 是否启用自动保存
+ ///
+ public bool IsAutoSaveEnabled
+ {
+ get => _isAutoSaveEnabled;
+ set => SetProperty(ref _isAutoSaveEnabled, value);
+ }
+
+ ///
+ /// 是否启用调试模式
+ ///
+ public bool IsDebugModeEnabled
+ {
+ get => _isDebugModeEnabled;
+ set => SetProperty(ref _isDebugModeEnabled, value);
+ }
+
+ ///
+ /// 日志级别集合
+ ///
+ public ObservableCollection LogLevels
+ {
+ get => _logLevels;
+ set => SetProperty(ref _logLevels, value);
+ }
+
+ ///
+ /// 选中的日志级别
+ ///
+ public string SelectedLogLevel
+ {
+ get => _selectedLogLevel;
+ set => SetProperty(ref _selectedLogLevel, value);
+ }
+
+ ///
+ /// 日志状态
+ ///
+ public string LogStatus
+ {
+ get => _logStatus;
+ set => SetProperty(ref _logStatus, value);
+ }
+
+
+ ///
+ /// 插件版本
+ ///
+ public string PluginVersion
+ {
+ get => _pluginVersion;
+ set => SetProperty(ref _pluginVersion, value);
+ }
+
+ ///
+ /// Navisworks版本
+ ///
+ public string NavisworksVersion
+ {
+ get => _navisworksVersion;
+ set => SetProperty(ref _navisworksVersion, value);
+ }
+
+ ///
+ /// 设置状态
+ ///
+ public string SettingsStatus
+ {
+ get => _settingsStatus;
+ set => SetProperty(ref _settingsStatus, value);
+ }
+
+ ///
+ /// 系统状态
+ ///
+ public string SystemStatus
+ {
+ get => _systemStatus;
+ set => SetProperty(ref _systemStatus, value);
+ }
+
+ ///
+ /// 系统状态颜色
+ ///
+ public string SystemStatusColor
+ {
+ get => _systemStatusColor;
+ set => SetProperty(ref _systemStatusColor, value);
+ }
+
+ ///
+ /// 内存使用情况
+ ///
+ public string MemoryUsage
+ {
+ get => _memoryUsage;
+ set => SetProperty(ref _memoryUsage, value);
+ }
+
+ ///
+ /// 运行时间
+ ///
+ public string RunningTime
+ {
+ get => _runningTime;
+ set => SetProperty(ref _runningTime, value);
+ }
+
+ ///
+ /// 性能信息
+ ///
+ public string PerformanceInfo
+ {
+ get => _performanceInfo;
+ set => SetProperty(ref _performanceInfo, value);
+ }
+
+ #endregion
+
+ #region 命令
+
+ public ICommand ClearLogCommand { get; private set; }
+ public ICommand ExportLogCommand { get; private set; }
+ public ICommand ViewLogCommand { get; private set; }
+ public ICommand OpenSettingsCommand { get; private set; }
+ public ICommand ResetSettingsCommand { get; private set; }
+ public ICommand ImportConfigCommand { get; private set; }
+ public ICommand CheckUpdateCommand { get; private set; }
+ public ICommand GeneratePerformanceReportCommand { get; private set; }
+
+ #endregion
+
+ #region 构造函数
+
+ public SystemManagementViewModel() : base()
+ {
+ try
+ {
+ // 获取UI状态管理器实例
+ _uiStateManager = UIStateManager.Instance;
+
+ // 验证关键组件是否正常初始化
+ if (_uiStateManager == null)
+ {
+ LogManager.Error("UIStateManager初始化失败");
+ throw new InvalidOperationException("UIStateManager初始化失败");
+ }
+
+ // 初始化线程安全的集合
+ LogLevels = new ThreadSafeObservableCollection();
+
+ // 初始化命令
+ InitializeCommands();
+
+ // 初始化系统管理设置
+ InitializeSystemManagementSettingsAsync();
+
+ LogManager.Info("SystemManagementViewModel构造函数执行完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex);
+
+ // 在构造函数中尽量保证对象处于可用状态
+ SystemStatus = "初始化失败,请检查日志";
+ throw;
+ }
+ }
+
+ #endregion
+
+ #region 初始化
+
+ ///
+ /// 初始化命令
+ ///
+ private void InitializeCommands()
+ {
+ try
+ {
+ // 系统管理命令
+ ViewLogCommand = new RelayCommand(() => ExecuteViewLog());
+ ClearLogCommand = new RelayCommand(() => ExecuteClearLog());
+ ExportLogCommand = new RelayCommand(() => ExecuteExportLog());
+ OpenSettingsCommand = new RelayCommand(() => ExecuteOpenSettings());
+ ResetSettingsCommand = new RelayCommand(() => ExecuteResetSettings());
+ ImportConfigCommand = new RelayCommand(() => ExecuteImportConfig());
+ CheckUpdateCommand = new RelayCommand(() => ExecuteCheckUpdate());
+ GeneratePerformanceReportCommand = new RelayCommand(() => ExecuteGeneratePerformanceReport());
+
+ LogManager.Info("系统管理命令初始化完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"初始化命令失败: {ex.Message}", ex);
+ throw;
+ }
+ }
+
+ ///
+ /// 初始化系统管理设置
+ ///
+ private async Task InitializeSystemManagementSettingsAsync()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ await _uiStateManager.ExecuteUIUpdateAsync(() =>
+ {
+ // 初始化日志级别
+ LogLevels.Clear();
+ var logLevels = new[] { "Debug", "Info", "Warning", "Error" };
+ foreach (var level in logLevels)
+ {
+ LogLevels.Add(level);
+ }
+ SelectedLogLevel = "Info";
+
+ // 初始化系统信息
+ LogStatus = "日志系统正常";
+ SettingsStatus = "设置已加载";
+ PluginVersion = "v1.0";
+ NavisworksVersion = "2026";
+ SystemStatus = "正常";
+ SystemStatusColor = "Green";
+ });
+
+ // 启动性能监控
+ StartPerformanceMonitoring();
+
+ LogManager.Info("系统管理设置初始化完成");
+ }, "初始化系统管理设置");
+ }
+
+ ///
+ /// 启动性能监控
+ ///
+ private void StartPerformanceMonitoring()
+ {
+ var startTime = DateTime.Now;
+
+ // 使用定时器更新性能信息
+ var timer = new System.Windows.Threading.DispatcherTimer();
+ timer.Interval = TimeSpan.FromSeconds(5);
+ timer.Tick += (s, e) =>
+ {
+ try
+ {
+ // 更新内存使用
+ var process = System.Diagnostics.Process.GetCurrentProcess();
+ var memoryMB = process.WorkingSet64 / (1024 * 1024);
+ MemoryUsage = $"{memoryMB} MB";
+
+ // 更新运行时间
+ var runTime = DateTime.Now - startTime;
+ RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}";
+
+ // 更新性能信息
+ PerformanceInfo = $"CPU: 正常, 内存: {memoryMB}MB, 运行时间: {RunningTime}";
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"性能监控更新失败: {ex.Message}");
+ }
+ };
+ timer.Start();
+ }
+
+ #endregion
+
+ #region 命令实现
+
+
+ ///
+ /// 查看日志
+ ///
+ private void ExecuteViewLog()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现日志查看功能
+ LogStatus = "打开日志查看器";
+ LogManager.Info("查看日志");
+ }, "查看日志");
+ }
+
+ ///
+ /// 清空日志
+ ///
+ private void ExecuteClearLog()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现日志清空功能
+ LogStatus = "日志已清空";
+ LogManager.Info("清空日志");
+ }, "清空日志");
+ }
+
+ ///
+ /// 导出日志
+ ///
+ private void ExecuteExportLog()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现日志导出功能
+ LogStatus = "日志导出完成";
+ LogManager.Info("导出日志");
+ }, "导出日志");
+ }
+
+ ///
+ /// 打开设置
+ ///
+ private void ExecuteOpenSettings()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现设置对话框
+ SettingsStatus = "打开插件设置";
+ LogManager.Info("打开设置");
+ }, "打开设置");
+ }
+
+ ///
+ /// 重置设置
+ ///
+ private void ExecuteResetSettings()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现设置重置功能
+ SettingsStatus = "设置已重置为默认值";
+ IsAutoSaveEnabled = true;
+ IsDebugModeEnabled = false;
+ LogManager.Info("重置设置");
+ }, "重置设置");
+ }
+
+ ///
+ /// 导入配置
+ ///
+ private void ExecuteImportConfig()
+ {
+ SafeExecute(() =>
+ {
+ // TODO: 实现配置导入功能
+ SettingsStatus = "配置导入完成";
+ LogManager.Info("导入配置");
+ }, "导入配置");
+ }
+
+ ///
+ /// 检查更新
+ ///
+ private void ExecuteCheckUpdate()
+ {
+ SafeExecute(() =>
+ {
+ SystemStatus = "正在检查更新...";
+
+ // 模拟检查更新
+ System.Threading.Tasks.Task.Run(() =>
+ {
+ System.Threading.Thread.Sleep(2000);
+
+ System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ try
+ {
+ SystemStatus = "当前版本已是最新版本";
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"更新检查UI更新失败: {ex.Message}");
+ }
+ }), System.Windows.Threading.DispatcherPriority.Background);
+ });
+
+ LogManager.Info("检查更新");
+ }, "检查更新");
+ }
+
+ ///
+ /// 生成性能报告
+ ///
+ private void ExecuteGeneratePerformanceReport()
+ {
+ SafeExecute(() =>
+ {
+ SystemStatus = "正在生成性能报告...";
+
+ // 模拟生成报告
+ System.Threading.Tasks.Task.Run(() =>
+ {
+ System.Threading.Thread.Sleep(1500);
+
+ System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ try
+ {
+ SystemStatus = "性能报告生成完成";
+ PerformanceInfo = $"报告已生成 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"性能报告UI更新失败: {ex.Message}");
+ }
+ }), System.Windows.Threading.DispatcherPriority.Background);
+ });
+
+ LogManager.Info("生成性能报告");
+ }, "生成性能报告");
+ }
+
+ #endregion
+
+ #region 辅助方法
+
+ ///
+ /// 安全执行异步操作
+ ///
+ private async Task SafeExecuteAsync(Func action, string operationName = "未知操作")
+ {
+ try
+ {
+ await action();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
+ SystemStatus = $"{operationName}失败: {ex.Message}";
+ }
+ }
+
+ ///
+ /// 安全执行同步操作
+ ///
+ private void SafeExecute(Action action, string operationName = "未知操作")
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
+ SystemStatus = $"{operationName}失败: {ex.Message}";
+ }
+ }
+
+ ///
+ /// 验证ViewModel状态是否正常
+ ///
+ public bool IsValidState()
+ {
+ return _uiStateManager != null &&
+ LogLevels != null;
+ }
+
+ ///
+ /// 获取ViewModel状态信息
+ ///
+ public string GetStateInfo()
+ {
+ return $"UIStateManager: {(_uiStateManager != null ? "已初始化" : "未初始化")}, " +
+ $"日志级别数量: {LogLevels?.Count ?? 0}, " +
+ $"系统状态: {SystemStatus}";
+ }
+
+ #endregion
+
+ #region 清理资源
+
+ public void Cleanup()
+ {
+ try
+ {
+ LogManager.Info("开始清理SystemManagementViewModel资源");
+
+ // 目前没有需要特别清理的资源
+
+ LogManager.Info("SystemManagementViewModel资源清理完成");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"SystemManagementViewModel清理失败: {ex.Message}");
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/UI/WPF/Views/SystemManagementView.xaml b/src/UI/WPF/Views/SystemManagementView.xaml
index 42349a0..7469adc 100644
--- a/src/UI/WPF/Views/SystemManagementView.xaml
+++ b/src/UI/WPF/Views/SystemManagementView.xaml
@@ -1,56 +1,159 @@
+
-
-
-
-
-
-
-
+ d:DesignHeight="800" d:DesignWidth="480">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -63,34 +166,53 @@
-
-
+
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file