# 分层预览智能遍历需求分析 ## 需求概述 ### 新的分层处理逻辑需求 修改分层预览的业务逻辑,实现基于属性的智能停止遍历机制: 1. **智能遍历逻辑**:从一级节点开始,遍历每个节点查找指定的分层属性 2. **分支停止机制**:如果找到分层属性,记录下来作为一个分层,不再遍历其下级节点 3. **深度递归控制**:如果没找到,继续遍历其子节点,直到找到为止,遍历深度受到用户指定的遍历深度限制 4. **智能检测特殊处理**:使用一组候选的分层属性,对每个节点进行查找,按属性的评分(优先级)确定选择何种属性 5. **自定义查找特殊处理**:用指定的分层属性,在每个节点的"分层信息"属性类别中查找 ## 现有架构分析 ### 1. 当前遍历机制的局限性 **现有实现方式**: ```csharp // 当前的两阶段处理方式 var allItems = GetAllModelItems(config.MaxDepth); // 阶段1:收集所有指定深度内的节点 var groups = strategy.GroupItems(allItems, config); // 阶段2:对所有节点进行属性分析和分组 ``` **存在的问题**: - 采用固定深度遍历,无法实现智能停止 - 先收集所有节点,再统一分组,无法在遍历过程中动态决策 - **核心问题:无法实现"找到属性就停止该分支遍历"的逻辑** **需要的新逻辑**: ```csharp // 需要的边遍历边检查逻辑 foreach (一级节点) { if (节点有指定分层属性) { 记录为分层,停止遍历该分支; } else { 递归遍历子节点(深度限制); } } ``` ### 2. 现有策略接口的不足 **当前IGroupingStrategy接口**: ```csharp public interface IGroupingStrategy { Dictionary GroupItems(ModelItemCollection items, SplitConfiguration config); } ``` **接口局限性**: - 只能处理预收集的节点集合 - 无法在遍历过程中动态决策是否继续遍历 - 不支持单节点的属性检查和分支控制 ### 3. 属性检查机制的缺陷 **现有策略类的问题**: - 如`FloorAttributeStrategy`仅检查特定的固定属性 - 没有通用的"分层信息"属性类别检查机制 - 不支持候选属性组和优先级评分 - 缺乏多属性竞争选择逻辑 ## 架构改造方案 ### 1. 核心遍历算法重设计 **新的智能遍历算法**: ```csharp public List PreviewSplitWithSmartTraversal( SplitConfiguration config, ISmartGroupingStrategy strategy) { var results = new List(); // 从每个模型的一级节点开始遍历 foreach (Model model in document.Models) { foreach (ModelItem rootChild in model.RootItem.Children) { TraverseNodeWithAttributeCheck(rootChild, strategy, config, results, 1); } } return results; } private void TraverseNodeWithAttributeCheck(ModelItem node, ISmartGroupingStrategy strategy, SplitConfiguration config, List results, int currentDepth) { // 检查当前节点是否有分层属性 var layerInfo = strategy.ExtractLayerInfo(node); if (layerInfo != null && layerInfo.IsValid) { // 找到分层属性,停止遍历该分支,添加到结果 var layerResult = CreateLayerResult(layerInfo, node); results.Add(layerResult); return; // 关键:停止该分支遍历 } // 未找到属性且未达深度限制,继续遍历子节点 if (currentDepth < config.MaxDepth && node.Children != null) { foreach (ModelItem child in node.Children) { TraverseNodeWithAttributeCheck(child, strategy, config, results, currentDepth + 1); } } } ``` ### 2. 新策略接口设计 **ISmartGroupingStrategy接口**: ```csharp public interface ISmartGroupingStrategy { string GroupTypeName { get; } /// /// 核心方法:检查单个节点的分层信息 /// LayerInfo ExtractLayerInfo(ModelItem node); /// /// 支持候选属性组的智能检测 /// LayerInfo ExtractBestLayerInfo(ModelItem node, List candidates); } ``` **支持数据结构**: ```csharp public class LayerInfo { public bool IsValid { get; set; } public string LayerName { get; set; } public string AttributeName { get; set; } public string AttributeValue { get; set; } public int Priority { get; set; } // 用于智能检测的优先级 public string CategoryName { get; set; } // 属性类别 } public class AttributeCandidate { public string AttributeName { get; set; } public string CategoryName { get; set; } // 如"分层信息" public int Priority { get; set; } // 优先级评分 public Func ValueProcessor { get; set; } // 值处理函数 } ``` ### 3. 智能检测策略实现 **SmartLayerDetectionStrategy类**: ```csharp public class SmartLayerDetectionStrategy : ISmartGroupingStrategy { private readonly List _candidates = new List { // 按优先级排序的候选属性 new AttributeCandidate { AttributeName = "楼层", CategoryName = "分层信息", Priority = 10 }, new AttributeCandidate { AttributeName = "Floor", CategoryName = "Identity Data", Priority = 9 }, new AttributeCandidate { AttributeName = "Level", CategoryName = "Constraints", Priority = 8 }, new AttributeCandidate { AttributeName = "分区", CategoryName = "分层信息", Priority = 7 }, new AttributeCandidate { AttributeName = "Zone", CategoryName = "Identity Data", Priority = 6 }, new AttributeCandidate { AttributeName = "子系统", CategoryName = "分层信息", Priority = 5 }, new AttributeCandidate { AttributeName = "System Type", CategoryName = "Mechanical", Priority = 4 }, // ... 更多候选属性 }; public LayerInfo ExtractLayerInfo(ModelItem node) { return ExtractBestLayerInfo(node, _candidates); } public LayerInfo ExtractBestLayerInfo(ModelItem node, List candidates) { LayerInfo bestMatch = null; int highestPriority = -1; // 遍历所有候选属性,找到优先级最高的有效属性 foreach (var candidate in candidates) { var value = GetAttributeValue(node, candidate.CategoryName, candidate.AttributeName); if (!string.IsNullOrEmpty(value) && candidate.Priority > highestPriority) { bestMatch = new LayerInfo { IsValid = true, LayerName = candidate.ValueProcessor?.Invoke(value) ?? value, AttributeName = candidate.AttributeName, AttributeValue = value, Priority = candidate.Priority, CategoryName = candidate.CategoryName }; highestPriority = candidate.Priority; } } return bestMatch ?? new LayerInfo { IsValid = false }; } private string GetAttributeValue(ModelItem node, string categoryName, string attributeName) { try { // 实现Navisworks属性检查逻辑 foreach (PropertyCategory category in node.PropertyCategories) { if (category.DisplayName == categoryName) { foreach (DataProperty property in category.Properties) { if (property.DisplayName == attributeName) { return property.Value.ToDisplayString(); } } } } } catch (Exception ex) { LogManager.Warning($"获取属性值失败: {ex.Message}"); } return null; } } ``` ### 4. 自定义属性检查策略 **CustomAttributeStrategy类**: ```csharp public class CustomAttributeStrategy : ISmartGroupingStrategy { private readonly string _targetAttributeName; private readonly string _targetCategoryName; public string GroupTypeName => $"自定义属性({_targetAttributeName})"; public CustomAttributeStrategy(string attributeName, string categoryName = "分层信息") { _targetAttributeName = attributeName; _targetCategoryName = categoryName; } public LayerInfo ExtractLayerInfo(ModelItem node) { var value = GetAttributeValue(node, _targetCategoryName, _targetAttributeName); if (!string.IsNullOrEmpty(value)) { return new LayerInfo { IsValid = true, LayerName = value, AttributeName = _targetAttributeName, AttributeValue = value, Priority = 1, CategoryName = _targetCategoryName }; } return new LayerInfo { IsValid = false }; } public LayerInfo ExtractBestLayerInfo(ModelItem node, List candidates) { // 对于自定义策略,只检查指定的单个属性 return ExtractLayerInfo(node); } private string GetAttributeValue(ModelItem node, string categoryName, string attributeName) { // 与智能检测策略相同的实现 // ... } } ``` ### 5. 遍历结果处理 **CreateLayerResult方法设计**: ```csharp private SplitPreviewResult CreateLayerResult(LayerInfo layerInfo, ModelItem rootNode) { // 收集该节点下的所有子项 var allChildItems = new ModelItemCollection(); CollectAllDescendants(rootNode, allChildItems); return new SplitPreviewResult { LayerName = SanitizeLayerName(layerInfo.LayerName), ItemCount = allChildItems.Count, EstimatedFileSize = EstimateFileSize(allChildItems.Count), Status = "就绪", Items = allChildItems, Metadata = new Dictionary { ["AttributeName"] = layerInfo.AttributeName, ["AttributeValue"] = layerInfo.AttributeValue, ["CategoryName"] = layerInfo.CategoryName, ["Priority"] = layerInfo.Priority, ["RootNodeName"] = rootNode.DisplayName } }; } private void CollectAllDescendants(ModelItem rootNode, ModelItemCollection collection) { // 添加根节点本身 collection.Add(rootNode); // 递归添加所有后代节点 if (rootNode.Children != null) { foreach (ModelItem child in rootNode.Children) { CollectAllDescendants(child, collection); } } } ``` ## 配置和UI适配 ### 1. 分层策略配置 **新的策略类型枚举**: ```csharp public enum SmartSplitStrategy { SmartLayerDetection, // 智能检测 CustomFloorAttribute, // 自定义楼层属性 CustomZoneAttribute, // 自定义分区属性 CustomSystemAttribute, // 自定义系统属性 CustomAttribute // 完全自定义属性 } ``` ### 2. UI配置选项 **智能检测配置**: - 候选属性优先级设置 - 属性类别选择 - 值处理规则配置 **自定义查找配置**: - 属性名称输入 - 属性类别选择(默认"分层信息") - 值过滤规则 ## 兼容性考虑 ### 1. 向后兼容 **保留现有接口**: - 现有的`IGroupingStrategy`接口和实现类保持不变 - 在`SimplifiedModelSplitterManager`中增加新的智能遍历方法 - UI层提供策略选择开关 **渐进式迁移**: ```csharp public List PreviewSplit(SplitConfiguration config) { // 根据配置选择使用新的智能遍历还是传统方式 if (config.UseSmartTraversal) { return PreviewSplitWithSmartTraversal(config, CreateSmartStrategy(config)); } else { // 保留原有的实现逻辑 return PreviewSplitTraditional(config); } } ``` ### 2. 性能考虑 **优化策略**: - 属性检查缓存机制 - 早期终止优化(找到高优先级属性立即停止) - 内存管理优化(避免大量节点同时加载) ## 实施复杂度评估 ### 高复杂度任务 1. **核心遍历算法重写**:需要完全重新设计遍历逻辑 2. **属性检查机制实现**:涉及Navisworks API的深度使用 3. **测试验证**:需要大量的模型测试和边界情况验证 ### 中等复杂度任务 1. **新策略接口和实现类**:相对标准的面向对象设计 2. **UI适配**:在现有界面基础上增加配置选项 ### 低复杂度任务 1. **配置管理**:基于现有的配置系统扩展 2. **日志和错误处理**:基于现有的LogManager扩展 ## 结论 **现有架构评估**: - **不满足新需求**:当前的"先收集后分组"模式无法实现智能停止遍历 - **需要重大改造**:核心算法、策略接口、属性检查机制都需要重新设计 - **改造工作量大**:预计需要重写30%以上的核心代码 **建议实施策略**: 1. **并行开发**:新旧算法并存,确保系统稳定性 2. **分阶段验证**:先实现基础功能,再逐步完善高级特性 3. **充分测试**:准备多种类型的测试模型,验证各种边界情况 4. **性能监控**:关注新算法的性能表现,必要时进行优化 **预期收益**: - **更精确的分层**:基于实际属性内容而非固定深度 - **更高的效率**:避免不必要的深度遍历 - **更灵活的配置**:支持多种属性检查策略 - **更好的用户体验**:提供智能化的分层建议