# 分层管理功能重构技术实现指南
## 技术架构概览
### 系统组件关系图
```
┌─────────────────────────────────────────────────────────────┐
│ LogisticsControlPanel │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ 类别设置 │ │ 路径编辑 │ │ 检测动画 │ │ 分层管理 │ │
│ │ Tab │ │ Tab │ │ Tab │ │ Tab │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ ModelLayerManagementView │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ 楼层分析 │ │ 设置层属性 │ │ 分层保存 │ │选中保存 │ │
│ │ 功能区 │ │ 功能区 │ │ 功能区 │ │ 功能区 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌─────────┐ ┌──────────────┐ ┌─────────────┐
│ViewModel│ │ Service │ │ Existing │
│ Layer │ │ Layer │ │ Components │
│ │ │ │ │ │
└─────────┘ └──────────────┘ └─────────────┘
```
### 核心技术栈
- **UI框架**: WPF (XAML + C#)
- **架构模式**: MVVM (Model-View-ViewModel)
- **API集成**: Navisworks 2026 Native + COM API
- **异步处理**: async/await + Task
- **事件驱动**: EventHandler + INotifyPropertyChanged
## 详细实现方案
### 1. 楼层分析功能实现
#### 1.1 核心数据结构
```csharp
///
/// 楼层分析结果数据模型
///
public class FloorAnalysisResult : INotifyPropertyChanged
{
public string AttributeName { get; set; } // 属性名称
public int FloorCount { get; set; } // 检测到的楼层数
public double QualityScore { get; set; } // 质量评分 (0-100)
public List FloorNames { get; set; } // 楼层名称列表
public bool IsFeasible { get; set; } // 是否可行
public string RecommendationText { get; set; } // 建议文本
public ObservableCollection Floors { get; set; } // 详细楼层信息
}
```
#### 1.2 分析算法实现
```csharp
///
/// 执行楼层分析
///
public async Task AnalyzeFloorsAsync()
{
try
{
OnStatusChanged("正在分析模型楼层结构...");
// 1. 获取可用的楼层属性
var availableAttributes = FloorDetector.GetAvailableFloorAttributes();
// 2. 为每个属性计算质量评分
var bestAttribute = await FindBestFloorAttributeAsync(availableAttributes);
// 3. 基于最佳属性检测楼层
var detectedFloors = await FloorDetector.DetectFloorsByAttributeAsync(bestAttribute);
// 4. 计算分析结果
var result = new FloorAnalysisResult
{
AttributeName = bestAttribute,
FloorCount = detectedFloors.Count,
QualityScore = CalculateQualityScore(detectedFloors),
FloorNames = detectedFloors.Select(f => f.FloorName).ToList(),
IsFeasible = detectedFloors.Count >= 2 && CalculateQualityScore(detectedFloors) > 60,
Floors = new ObservableCollection(detectedFloors)
};
result.RecommendationText = GenerateRecommendation(result);
OnStatusChanged($"楼层分析完成: 检测到 {result.FloorCount} 个楼层");
return result;
}
catch (Exception ex)
{
LogManager.Error($"楼层分析失败: {ex.Message}");
throw;
}
}
///
/// 计算楼层属性质量评分
///
private double CalculateQualityScore(List floors)
{
if (floors == null || floors.Count == 0) return 0;
double score = 0;
// 1. 楼层数量评分 (30%)
var countScore = Math.Min(floors.Count * 10, 30);
// 2. 命名规范性评分 (40%)
var namingScore = CalculateNamingQuality(floors) * 40;
// 3. 高程分布评分 (30%)
var elevationScore = CalculateElevationQuality(floors) * 30;
return countScore + namingScore + elevationScore;
}
```
#### 1.3 UI实现 (XAML片段)
```xml
```
### 2. 设置层属性功能实现
#### 2.1 属性设置服务
```csharp
///
/// 层属性设置服务
///
public class LayerAttributeService
{
private readonly CategoryAttributeManager _attributeManager;
public LayerAttributeService()
{
_attributeManager = new CategoryAttributeManager();
}
///
/// 为选中的模型项设置层属性
///
public async Task SetLayerAttributeAsync(ModelItemCollection items, string layerName)
{
try
{
OnStatusChanged($"正在为 {items.Count} 个构件设置层属性...");
// 使用COM API确保属性持久化
var success = await Task.Run(() =>
{
return _attributeManager.SetLogisticsAttribute(items, "Layer", layerName);
});
if (success)
{
OnStatusChanged($"成功为 {items.Count} 个构件设置层属性: {layerName}");
LayerAttributeChanged?.Invoke(this, new LayerAttributeChangedEventArgs(items, layerName));
}
return success;
}
catch (Exception ex)
{
LogManager.Error($"设置层属性失败: {ex.Message}");
return false;
}
}
///
/// 批量设置多个楼层的属性
///
public async Task> BatchSetLayerAttributesAsync(
Dictionary layerGroups)
{
var results = new Dictionary();
foreach (var group in layerGroups)
{
var success = await SetLayerAttributeAsync(group.Value, group.Key);
results[group.Key] = success;
// 添加延迟避免API过载
await Task.Delay(100);
}
return results;
}
public event EventHandler LayerAttributeChanged;
public event EventHandler StatusChanged;
private void OnStatusChanged(string status) => StatusChanged?.Invoke(this, status);
}
```
#### 2.2 选择树操作界面
```xml
```
### 3. 分层保存功能实现
#### 3.1 简化的分层配置
```csharp
///
/// 简化的分层保存配置
///
public class SimpleSplitConfiguration
{
public SplitStrategy Strategy { get; set; } = SplitStrategy.ByFloor;
public string AttributeName { get; set; } = "Layer";
public string OutputDirectory { get; set; }
public string FileNameTemplate { get; set; } = "{ProjectName}_{LayerName}";
public bool EnablePreview { get; set; } = true;
public bool GenerateReport { get; set; } = true;
///
/// 转换为完整的ModelSplitter配置
///
public SplitConfiguration ToFullConfiguration()
{
return new SplitConfiguration
{
Strategy = this.Strategy,
AttributeName = this.AttributeName,
OutputDirectory = this.OutputDirectory,
FileNamePattern = this.FileNameTemplate,
IncludeEmptyLayers = false,
PreserveOriginalStructure = true,
GenerateReport = this.GenerateReport,
CreateSubDirectories = false
};
}
}
```
#### 3.2 预览功能实现
```csharp
///
/// 生成分层保存预览
///
public async Task> GenerateLayerPreviewAsync(SimpleSplitConfiguration config)
{
try
{
OnStatusChanged("正在生成分层预览...");
// 复用ModelSplitterManager的预览功能
var fullConfig = config.ToFullConfiguration();
var previewResults = await _modelSplitter.PreviewSplit(fullConfig);
var previewInfos = previewResults.Select(result => new LayerPreviewInfo
{
LayerName = result.LayerName,
ItemCount = result.ItemCount,
EstimatedFileSize = EstimateFileSize(result.Items),
OutputPath = result.OutputFilePath,
IsValid = result.ItemCount > 0
}).ToList();
OnStatusChanged($"预览生成完成: {previewInfos.Count} 个图层");
return previewInfos;
}
catch (Exception ex)
{
LogManager.Error($"生成预览失败: {ex.Message}");
throw;
}
}
///
/// 执行分层保存
///
public async Task ExecuteLayerSplitAsync(SimpleSplitConfiguration config,
IProgress progress = null)
{
try
{
OnStatusChanged("开始分层保存...");
var fullConfig = config.ToFullConfiguration();
// 设置进度回调
if (progress != null)
{
_modelSplitter.ProgressChanged += (s, e) =>
{
progress.Report(new SplitProgressInfo
{
CurrentLayer = e.UserState?.ToString(),
ProgressPercentage = e.ProgressPercentage,
StatusText = $"正在处理: {e.UserState}"
});
};
}
var results = await _modelSplitter.ExecuteSplitAsync(fullConfig);
var successCount = results.Count(r => r.Success);
OnStatusChanged($"分层保存完成: {successCount}/{results.Count} 个文件成功保存");
return successCount == results.Count;
}
catch (Exception ex)
{
LogManager.Error($"分层保存失败: {ex.Message}");
return false;
}
}
```
#### 3.3 分层保存UI
```xml
```
### 4. 选中保存功能实现
#### 4.1 选中内容保存服务
```csharp
///
/// 选中内容保存服务
///
public class SelectionExportService
{
///
/// 导出当前选中的内容
///
public async Task ExportCurrentSelectionAsync(string outputPath,
IProgress progress = null)
{
try
{
// 获取当前选择
var selection = NavisApplication.ActiveDocument.CurrentSelection;
if (selection.IsEmpty)
{
throw new InvalidOperationException("当前没有选中任何内容");
}
OnStatusChanged($"正在导出 {selection.Count} 个选中项...");
// 创建临时文档
var tempDoc = new Document();
// 复制选中内容到临时文档
await Task.Run(() =>
{
tempDoc.CurrentSelection.CopyFrom(selection);
// 报告进度
progress?.Report(50);
// 保存文档
tempDoc.SaveFile(outputPath);
progress?.Report(100);
});
OnStatusChanged($"选中内容已成功导出到: {outputPath}");
return true;
}
catch (Exception ex)
{
LogManager.Error($"导出选中内容失败: {ex.Message}");
return false;
}
}
///
/// 获取选中内容的统计信息
///
public SelectionInfo GetSelectionInfo()
{
var selection = NavisApplication.ActiveDocument.CurrentSelection;
return new SelectionInfo
{
ItemCount = selection.Count,
IsEmpty = selection.IsEmpty,
BoundingBox = selection.IsEmpty ? null : selection.ComputeBoundingBox(),
Categories = GetSelectionCategories(selection)
};
}
public event EventHandler StatusChanged;
private void OnStatusChanged(string status) => StatusChanged?.Invoke(this, status);
}
///
/// 选中内容信息
///
public class SelectionInfo
{
public int ItemCount { get; set; }
public bool IsEmpty { get; set; }
public BoundingBox3D BoundingBox { get; set; }
public Dictionary Categories { get; set; }
public string Summary => IsEmpty ? "未选中任何内容" :
$"已选中 {ItemCount} 个构件,范围: {FormatBounds()}";
private string FormatBounds()
{
if (BoundingBox == null) return "未知";
var size = BoundingBox.Max - BoundingBox.Min;
return $"{size.X:F1}×{size.Y:F1}×{size.Z:F1}m";
}
}
```
#### 4.2 选中保存UI
```xml
```
## 性能优化策略
### 1. 内存管理优化
```csharp
///
/// 大模型处理的内存优化策略
///
public class MemoryOptimizedProcessor
{
private const int BATCH_SIZE = 1000; // 批处理大小
///
/// 分批处理大型模型
///
public async Task> ProcessInBatchesAsync(
IEnumerable source,
Func, Task>> processor,
IProgress progress = null)
{
var results = new List();
var batches = source.Batch(BATCH_SIZE).ToList();
for (int i = 0; i < batches.Count; i++)
{
var batch = batches[i];
var batchResults = await processor(batch);
results.AddRange(batchResults);
// 强制垃圾回收
if (i % 10 == 0)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
// 报告进度
progress?.Report((i + 1) * 100 / batches.Count);
}
return results;
}
}
```
### 2. 异步操作取消支持
```csharp
///
/// 支持取消的异步操作基类
///
public abstract class CancellableAsyncOperation
{
protected CancellationTokenSource _cancellationTokenSource;
public bool IsCancelled => _cancellationTokenSource?.Token.IsCancellationRequested ?? false;
public void Cancel()
{
_cancellationTokenSource?.Cancel();
OnStatusChanged("操作已取消");
}
protected virtual void OnStatusChanged(string status)
{
StatusChanged?.Invoke(this, status);
}
public event EventHandler StatusChanged;
}
```
## 错误处理与日志记录
### 1. 统一异常处理
```csharp
///
/// 分层管理异常处理器
///
public class LayerManagementExceptionHandler
{
public static async Task ExecuteWithExceptionHandlingAsync(
Func> operation,
string operationName,
TResult defaultValue = default(TResult))
{
try
{
return await operation();
}
catch (UnauthorizedAccessException ex)
{
var message = $"{operationName}失败: 文件访问权限不足 - {ex.Message}";
LogManager.Error(message);
MessageBox.Show(message, "权限错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return defaultValue;
}
catch (OutOfMemoryException ex)
{
var message = $"{operationName}失败: 内存不足,请尝试分批处理 - {ex.Message}";
LogManager.Error(message);
MessageBox.Show(message, "内存错误", MessageBoxButton.OK, MessageBoxImage.Error);
return defaultValue;
}
catch (Exception ex)
{
var message = $"{operationName}失败: {ex.Message}";
LogManager.Error(message, ex);
MessageBox.Show(message, "操作失败", MessageBoxButton.OK, MessageBoxImage.Error);
return defaultValue;
}
}
}
```
### 2. 操作日志记录
```csharp
///
/// 分层管理操作日志
///
public class LayerManagementAuditLog
{
public static void LogLayerAnalysis(FloorAnalysisResult result)
{
LogManager.Info($"楼层分析完成: 属性={result.AttributeName}, " +
$"楼层数={result.FloorCount}, 质量评分={result.QualityScore:F1}");
}
public static void LogAttributeSetting(string layerName, int itemCount, bool success)
{
var status = success ? "成功" : "失败";
LogManager.Info($"层属性设置{status}: 楼层={layerName}, 构件数={itemCount}");
}
public static void LogLayerSplit(string strategy, int layerCount, int successCount)
{
LogManager.Info($"分层保存完成: 策略={strategy}, " +
$"总层数={layerCount}, 成功={successCount}");
}
public static void LogSelectionExport(int itemCount, string outputPath, bool success)
{
var status = success ? "成功" : "失败";
LogManager.Info($"选中导出{status}: 构件数={itemCount}, 路径={outputPath}");
}
}
```
## 集成测试方案
### 1. 单元测试示例
```csharp
[TestClass]
public class LayerManagementTests
{
[TestMethod]
public async Task AnalyzeFloors_WithValidModel_ReturnsValidResult()
{
// Arrange
var viewModel = new ModelLayerManagementViewModel();
// Act
var result = await viewModel.AnalyzeFloorsAsync();
// Assert
Assert.IsNotNull(result);
Assert.IsTrue(result.FloorCount > 0);
Assert.IsTrue(result.QualityScore >= 0 && result.QualityScore <= 100);
}
[TestMethod]
public async Task SetLayerAttribute_WithValidSelection_ReturnsTrue()
{
// Arrange
var service = new LayerAttributeService();
var mockItems = CreateMockModelItems();
// Act
var success = await service.SetLayerAttributeAsync(mockItems, "TestFloor");
// Assert
Assert.IsTrue(success);
}
}
```
### 2. 集成测试检查清单
- [ ] 楼层分析功能在不同模型类型下的表现
- [ ] 属性设置在大型选择集下的性能
- [ ] 分层保存的文件完整性验证
- [ ] 选中导出的数据一致性检查
- [ ] 内存使用情况监控
- [ ] 异常恢复机制验证
---
**文档创建时间**: 2025-08-18
**技术架构版本**: v1.0
**适用范围**: NavisworksTransport分层管理功能重构