497 lines
12 KiB
Markdown
497 lines
12 KiB
Markdown
# Business Commands使用指南
|
||
|
||
## 概述
|
||
|
||
本文档介绍NavisworksTransport项目中新实现的7个业务Commands的使用方法和最佳实践。这些Commands基于Command Pattern设计,与UIStateManager深度集成,提供线程安全、异步执行和进度报告功能。
|
||
|
||
## 实现的Commands
|
||
|
||
### 1. SetLogisticsAttributeCommand - 设置物流属性
|
||
|
||
**功能**:为选中的模型项设置物流分类属性
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
// 方式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 - 删除路径
|
||
|
||
**功能**:删除特定路径或所有路径,支持备份
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
// 删除特定路径
|
||
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文件导入路径数据
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
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 - 导出路径数据
|
||
|
||
**功能**:将路径数据导出为多种格式
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
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 - 碰撞检测
|
||
|
||
**功能**:检测路径与模型的碰撞冲突
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
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 - 启动动画
|
||
|
||
**功能**:启动路径动画播放
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
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 - 模型分层
|
||
|
||
**功能**:按不同策略分割和导出模型
|
||
|
||
**使用方式**:
|
||
```csharp
|
||
// 按楼层分层
|
||
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集成
|
||
|
||
### 队列执行
|
||
|
||
```csharp
|
||
// 添加命令到执行队列
|
||
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);
|
||
```
|
||
|
||
### 批量工作流
|
||
|
||
```csharp
|
||
// 典型的备份-清理-导入-验证工作流
|
||
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 });
|
||
}
|
||
```
|
||
|
||
## 事件处理
|
||
|
||
### 进度监控
|
||
|
||
```csharp
|
||
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事件
|
||
|
||
```csharp
|
||
CommandManager.Instance.CommandExecutionStarted += (sender, e) =>
|
||
{
|
||
LogManager.Info($"开始执行命令: {e.CommandId}");
|
||
};
|
||
|
||
CommandManager.Instance.CommandExecutionCompleted += (sender, e) =>
|
||
{
|
||
LogManager.Info($"命令执行完成: {e.CommandId}, 结果: {e.Result.IsSuccess}");
|
||
};
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 错误处理
|
||
|
||
```csharp
|
||
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. 参数验证
|
||
|
||
```csharp
|
||
// 在执行前验证参数
|
||
var canExecute = command.CanExecute();
|
||
if (!canExecute.IsSuccess)
|
||
{
|
||
MessageBox.Show($"参数验证失败: {canExecute.ErrorMessage}");
|
||
return;
|
||
}
|
||
```
|
||
|
||
### 3. 取消支持
|
||
|
||
```csharp
|
||
using (var cts = new CancellationTokenSource())
|
||
{
|
||
// 设置取消按钮
|
||
cancelButton.Click += (s, e) => cts.Cancel();
|
||
|
||
try
|
||
{
|
||
var result = await command.ExecuteAsync(cts.Token);
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
// 用户取消操作
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4. UI线程安全
|
||
|
||
```csharp
|
||
// Commands会自动处理UI线程调用
|
||
command.ProgressChanged += async (sender, e) =>
|
||
{
|
||
// 这个事件处理器在UI线程中执行
|
||
await UIStateManager.Instance.ExecuteUIUpdateAsync(() =>
|
||
{
|
||
progressBar.Value = e.Progress;
|
||
statusLabel.Text = e.Message;
|
||
});
|
||
};
|
||
```
|
||
|
||
## 性能考虑
|
||
|
||
### 1. 批量操作优化
|
||
|
||
```csharp
|
||
// 对于大量路径操作,使用批量模式
|
||
var exportParams = new ExportPathParameters
|
||
{
|
||
ExportAll = true, // 批量导出
|
||
GenerateReport = false, // 跳过报告生成以提高性能
|
||
BatchSize = 100 // 分批处理
|
||
};
|
||
```
|
||
|
||
### 2. 并发限制
|
||
|
||
```csharp
|
||
// CommandManager会自动管理并发,但可以检查状态
|
||
var status = CommandManager.Instance.GetStatus();
|
||
if (status.RunningCommandCount > 3)
|
||
{
|
||
// 等待当前命令完成或使用队列
|
||
await CommandManager.Instance.EnqueueCommandAsync(commandKey, parameters);
|
||
}
|
||
```
|
||
|
||
### 3. 内存管理
|
||
|
||
```csharp
|
||
// 对于大文件操作,监控内存使用
|
||
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. **内存占用过高**
|
||
- 对大文件分批处理
|
||
- 及时释放不再使用的资源
|
||
|
||
### 调试技巧
|
||
|
||
```csharp
|
||
// 启用详细日志记录
|
||
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}");
|
||
}
|
||
```
|
||
|
||
## 测试
|
||
|
||
### 运行测试
|
||
|
||
```bash
|
||
# 运行所有业务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可以方便地进行命令组合和工作流管理,满足复杂的业务需求。 |