# 分层预览智能遍历需求分析

## 需求概述

### 新的分层处理逻辑需求

修改分层预览的业务逻辑，实现基于属性的智能停止遍历机制：

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<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config);
}
```

**接口局限性**：

- 只能处理预收集的节点集合
- 无法在遍历过程中动态决策是否继续遍历
- 不支持单节点的属性检查和分支控制

### 3. 属性检查机制的缺陷

**现有策略类的问题**：

- 如`FloorAttributeStrategy`仅检查特定的固定属性
- 没有通用的"分层信息"属性类别检查机制
- 不支持候选属性组和优先级评分
- 缺乏多属性竞争选择逻辑

## 架构改造方案

### 1. 核心遍历算法重设计

**新的智能遍历算法**：

```csharp
public List<SplitPreviewResult> PreviewSplitWithSmartTraversal(
    SplitConfiguration config, ISmartGroupingStrategy strategy)
{
    var results = new List<SplitPreviewResult>();
    
    // 从每个模型的一级节点开始遍历
    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<SplitPreviewResult> 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; }
    
    /// <summary>
    /// 核心方法：检查单个节点的分层信息
    /// </summary>
    LayerInfo ExtractLayerInfo(ModelItem node);
    
    /// <summary>
    /// 支持候选属性组的智能检测
    /// </summary>
    LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> 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<string, string> ValueProcessor { get; set; }  // 值处理函数
}
```

### 3. 智能检测策略实现

**SmartLayerDetectionStrategy类**：

```csharp
public class SmartLayerDetectionStrategy : ISmartGroupingStrategy
{
    private readonly List<AttributeCandidate> _candidates = new List<AttributeCandidate>
    {
        // 按优先级排序的候选属性
        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<AttributeCandidate> 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<AttributeCandidate> 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<string, object>
        {
            ["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<SplitPreviewResult> 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. **性能监控**：关注新算法的性能表现，必要时进行优化

**预期收益**：

- **更精确的分层**：基于实际属性内容而非固定深度
- **更高的效率**：避免不必要的深度遍历
- **更灵活的配置**：支持多种属性检查策略
- **更好的用户体验**：提供智能化的分层建议
