NavisworksTransport/doc/working/BusinessCommands使用指南_20250817.md

12 KiB
Raw Permalink Blame History

Business Commands使用指南

概述

本文档介绍NavisworksTransport项目中新实现的7个业务Commands的使用方法和最佳实践。这些Commands基于Command Pattern设计与UIStateManager深度集成提供线程安全、异步执行和进度报告功能。

实现的Commands

1. SetLogisticsAttributeCommand - 设置物流属性

功能:为选中的模型项设置物流分类属性

使用方式

// 方式1直接创建Command
var targetItems = document.CurrentSelection.SelectedItems;
var parameters = new SetLogisticsAttributeParameters
{
    TargetItems = targetItems,
    ElementType = CategoryAttributeManager.LogisticsElementType.Door,
    IsTraversable = true,
    OverwriteExisting = true
};

var command = new SetLogisticsAttributeCommand(parameters);
var result = await command.ExecuteAsync();

// 方式2通过CommandManager
var result = await CommandManager.Instance.ExecuteCommandAsync("SetLogisticsAttribute", 
    new object[] { targetItems, CategoryAttributeManager.LogisticsElementType.Door, true, true });

支持的物流元素类型

  • Door (门)
  • Elevator (电梯)
  • Stairs (楼梯)
  • Channel (通道)
  • Obstacle (障碍物)
  • LoadingZone (装卸区)
  • Parking (停车区)
  • Checkpoint (检查点)

2. DeletePathCommand - 删除路径

功能:删除特定路径或所有路径,支持备份

使用方式

// 删除特定路径
var deleteParams = new DeletePathParameters();
deleteParams.PathsToDelete.Add(specificRoute);
deleteParams.CreateBackup = true;

var command = new DeletePathCommand(deleteParams);
var result = await command.ExecuteAsync();

// 删除所有路径(谨慎使用)
var deleteAllParams = new DeletePathParameters
{
    DeleteAll = true,
    CreateBackup = true,  // 强烈建议
    ForceDelete = false   // 安全模式
};

安全特性

  • 自动备份功能
  • 确认机制ForceDelete=false时
  • 批量删除支持

3. ImportPathCommand - 导入路径数据

功能从XML/JSON文件导入路径数据

使用方式

var importParams = new ImportPathParameters
{
    FilePath = @"C:\Data\logistics_paths.xml",
    ImportFormat = ExportFormat.Xml,
    MergeWithExisting = true,
    CreateBackup = true,
    DuplicateNameHandling = ImportPathParameters.DuplicateNameHandling.Rename
};

var command = new ImportPathCommand(importParams);
var result = await command.ExecuteAsync();

if (result.IsSuccess && result is PathPlanningResult<ImportPathResult> importResult)
{
    Console.WriteLine($"成功导入 {importResult.Data.ImportedPathCount} 个路径");
}

支持格式

  • XML格式
  • JSON格式
  • 自动格式检测

重复处理策略

  • Skip: 跳过重复项
  • Overwrite: 覆盖现有项
  • Rename: 自动重命名

4. ExportPathCommand - 导出路径数据

功能:将路径数据导出为多种格式

使用方式

var exportParams = new ExportPathParameters
{
    OutputFilePath = @"C:\Export\current_paths.xml",
    ExportAll = true,
    ExportFormat = ExportFormat.Xml,
    OverwriteExisting = false,
    GenerateReport = true
};

var command = new ExportPathCommand(exportParams);
var result = await command.ExecuteAsync();

支持格式

  • XML: 标准XML格式
  • JSON: 轻量级JSON格式
  • DELMIA: 兼容DELMIA软件格式

报告功能

  • HTML格式导出报告
  • 统计信息和验证结果
  • 导出性能指标

5. RunCollisionDetectionCommand - 碰撞检测

功能:检测路径与模型的碰撞冲突

使用方式

var collisionParams = new CollisionDetectionParameters
{
    TargetRoute = specificRoute,  // 或设置 CheckAllRoutes = true
    ObjectSize = 1.8,           // 物体尺寸(米)
    SafetyMargin = 0.5,          // 安全边距(米)
    GenerateReport = true
};

var command = new RunCollisionDetectionCommand(collisionParams);
var result = await command.ExecuteAsync();

检测功能

  • 单路径检测
  • 全部路径批量检测
  • 可配置物体尺寸和安全边距
  • 详细碰撞报告

6. StartAnimationCommand - 启动动画

功能:启动路径动画播放

使用方式

var animationParams = new StartAnimationParameters
{
    TargetRoute = animationRoute,
    AnimationSpeed = 2.0,        // 米/秒
    Loop = false,               // 是否循环
    AutoStart = true            // 自动开始
};

var command = new StartAnimationCommand(animationParams);
var result = await command.ExecuteAsync();

// 快捷创建方式
var quickCommand = StartAnimationCommand.CreateForRoute(route, speed: 1.5, loop: true);

动画控制

  • 可调节播放速度
  • 循环播放选项
  • 与LogisticsAnimationManager集成
  • TimeLiner兼容

7. ModelSplitterCommand - 模型分层

功能:按不同策略分割和导出模型

使用方式

// 按楼层分层
var splitConfig = new ModelSplitterManager.SplitConfiguration
{
    Strategy = ModelSplitterManager.SplitStrategy.ByFloor,
    OutputDirectory = @"C:\ModelSplits\ByFloor",
    AttributeName = "Level",
    GenerateReport = true
};

var command = new ModelSplitterCommand(splitConfig);
var result = await command.ExecuteAsync();

// 快捷创建方式
var quickCommand = ModelSplitterCommand.CreateByFloor(@"C:\Output", "LevelName");

分层策略

  • ByFloor: 按楼层分层
  • ByCategory: 按类别分层
  • 自定义属性分层

CommandManager集成

队列执行

// 添加命令到执行队列
var task1 = CommandManager.Instance.EnqueueCommandAsync("ExportPath", 
    new object[] { @"C:\backup.xml", true, ExportFormat.Xml, true },
    CommandPriority.High);

var task2 = CommandManager.Instance.EnqueueCommandAsync("RunCollisionDetection", 
    new object[] { true, 2.0, 0.5 },
    CommandPriority.Normal);

// 等待所有任务完成
var results = await Task.WhenAll(task1, task2);

批量工作流

// 典型的备份-清理-导入-验证工作流
public async Task ExecuteMaintenanceWorkflow()
{
    // 1. 备份现有数据
    var backupResult = await CommandManager.Instance.ExecuteCommandAsync("ExportPath", 
        new object[] { GetBackupPath(), true, ExportFormat.Xml, false });
    
    if (!backupResult.IsSuccess) return;
    
    // 2. 清理现有路径
    await CommandManager.Instance.ExecuteCommandAsync("DeletePath", 
        new object[] { true, false, false });
    
    // 3. 导入新配置
    await CommandManager.Instance.ExecuteCommandAsync("ImportPath", 
        new object[] { GetConfigPath(), ExportFormat.Xml, true, false });
    
    // 4. 安全验证
    await CommandManager.Instance.ExecuteCommandAsync("RunCollisionDetection", 
        new object[] { true, 1.8, 0.5 });
}

事件处理

进度监控

command.ProgressChanged += (sender, e) =>
{
    // 更新UI进度条
    progressBar.Value = e.Progress;
    statusLabel.Text = e.Message;
};

command.StatusChanged += (sender, e) =>
{
    // 处理状态变化
    switch (e.CurrentStatus)
    {
        case CommandStatus.Running:
            startButton.Enabled = false;
            break;
        case CommandStatus.Completed:
        case CommandStatus.Failed:
            startButton.Enabled = true;
            break;
    }
};

CommandManager事件

CommandManager.Instance.CommandExecutionStarted += (sender, e) =>
{
    LogManager.Info($"开始执行命令: {e.CommandId}");
};

CommandManager.Instance.CommandExecutionCompleted += (sender, e) =>
{
    LogManager.Info($"命令执行完成: {e.CommandId}, 结果: {e.Result.IsSuccess}");
};

最佳实践

1. 错误处理

try
{
    var result = await command.ExecuteAsync(cancellationToken);
    
    if (result.IsSuccess)
    {
        // 处理成功结果
        ProcessSuccessResult(result);
    }
    else
    {
        // 处理业务错误
        HandleBusinessError(result.ErrorMessage);
    }
}
catch (OperationCanceledException)
{
    // 处理用户取消
    HandleUserCancellation();
}
catch (Exception ex)
{
    // 处理系统异常
    HandleSystemError(ex);
}

2. 参数验证

// 在执行前验证参数
var canExecute = command.CanExecute();
if (!canExecute.IsSuccess)
{
    MessageBox.Show($"参数验证失败: {canExecute.ErrorMessage}");
    return;
}

3. 取消支持

using (var cts = new CancellationTokenSource())
{
    // 设置取消按钮
    cancelButton.Click += (s, e) => cts.Cancel();
    
    try
    {
        var result = await command.ExecuteAsync(cts.Token);
    }
    catch (OperationCanceledException)
    {
        // 用户取消操作
    }
}

4. UI线程安全

// Commands会自动处理UI线程调用
command.ProgressChanged += async (sender, e) =>
{
    // 这个事件处理器在UI线程中执行
    await UIStateManager.Instance.ExecuteUIUpdateAsync(() =>
    {
        progressBar.Value = e.Progress;
        statusLabel.Text = e.Message;
    });
};

性能考虑

1. 批量操作优化

// 对于大量路径操作,使用批量模式
var exportParams = new ExportPathParameters
{
    ExportAll = true,           // 批量导出
    GenerateReport = false,     // 跳过报告生成以提高性能
    BatchSize = 100            // 分批处理
};

2. 并发限制

// CommandManager会自动管理并发但可以检查状态
var status = CommandManager.Instance.GetStatus();
if (status.RunningCommandCount > 3)
{
    // 等待当前命令完成或使用队列
    await CommandManager.Instance.EnqueueCommandAsync(commandKey, parameters);
}

3. 内存管理

// 对于大文件操作,监控内存使用
var memoryBefore = GC.GetTotalMemory(false);
var result = await importCommand.ExecuteAsync();
var memoryAfter = GC.GetTotalMemory(true); // 强制GC

LogManager.Info($"内存使用: {memoryAfter - memoryBefore} 字节");

故障排除

常见问题

  1. 文件访问权限错误

    • 确保输出目录具有写权限
    • 检查文件是否被其他程序占用
  2. UI线程阻塞

    • 所有Commands都是异步执行不会阻塞UI
    • 使用await而不是.Result来等待结果
  3. 取消操作无响应

    • 确保传递了CancellationToken
    • 检查命令是否支持取消操作
  4. 内存占用过高

    • 对大文件分批处理
    • 及时释放不再使用的资源

调试技巧

// 启用详细日志记录
LogManager.SetLogLevel(LogLevel.Debug);

// 监控命令执行状态
var status = CommandManager.Instance.GetStatus();
LogManager.Debug($"运行中命令: {status.RunningCommandCount}");
LogManager.Debug($"队列中命令: {status.QueuedCommandCount}");

// 检查命令注册状态
var registeredCommands = CommandManager.Instance.GetRegisteredCommands();
foreach (var cmd in registeredCommands)
{
    LogManager.Debug($"已注册命令: {cmd}");
}

测试

运行测试

# 运行所有业务Commands测试
./run-tests.bat

# 或者在代码中运行
await NavisworksTransport.Tests.TestRunner.RunBusinessCommandsTests();

# 快速验证测试
await NavisworksTransport.Tests.TestRunner.RunQuickTests();

# 特定命令测试
await NavisworksTransport.Tests.TestRunner.RunSpecificCommandTest("SetLogisticsAttribute");

测试覆盖

  • 参数验证测试
  • 命令创建测试
  • 执行流程测试
  • 错误处理测试
  • 取消操作测试
  • 集成测试
  • 性能测试

总结

新实现的7个业务Commands提供了完整的物流路径管理功能

  1. 设置属性 - 为模型元素分类
  2. 路径管理 - 删除、导入、导出路径数据
  3. 安全检查 - 碰撞检测和验证
  4. 可视化 - 动画播放和演示
  5. 模型处理 - 分层和导出

所有Commands都基于统一的Command Pattern架构提供

  • 异步执行和进度报告
  • 线程安全的UI集成
  • 完整的错误处理和取消支持
  • 灵活的参数化配置
  • 高性能的批量操作支持

通过CommandManager可以方便地进行命令组合和工作流管理满足复杂的业务需求。