fix: DisplayPath 所有层级加#N去重 + 移除旧格式兼容

- BuildNode 不再剥离父路径#N后缀
- FromModelItem 对每层祖先计算 siblingIndex 追加#N,与树加载一致
- 解决复制子树中节点别名泄露给其他子树的问题
- FromKey 移除纯 DisplayPath 旧格式兼容
This commit is contained in:
tian 2026-06-06 10:05:35 +08:00
parent 7dec26b1ac
commit f38fba6506
2 changed files with 13 additions and 32 deletions

View File

@ -17,9 +17,6 @@ namespace NavisworksTransport.Core.AliasTree
/// 可读可调试IndexPath 失效时作为降级定位手段。
///
/// 序列化格式ToKey "IndexPath||DisplayPath"
/// 示例: "0,2,5,1||模型/楼层/墙#0"
///
/// 向后兼容:不含 "||" 的 key 按旧格式(纯 DisplayPath解析。
/// </summary>
public readonly struct AliasNodeIdentity : IEquatable<AliasNodeIdentity>
{
@ -66,22 +63,17 @@ namespace NavisworksTransport.Core.AliasTree
indexPath = string.Empty;
}
// 2. DisplayPath — 父链 DisplayName + 同级索引
// 2. DisplayPath — 父链 DisplayName + 每层同名去重索引
var parts = new List<string>();
var current = item;
while (current != null)
{
parts.Insert(0, current.DisplayName ?? "?");
int siblingIdx = ComputeSiblingIndex(current);
string name = current.DisplayName ?? "?";
parts.Insert(0, siblingIdx > 0 ? $"{name}#{siblingIdx}" : name);
current = current.Parent;
}
string displayPath = string.Join("/", parts);
// 3. 同级同名节点去重索引
int siblingIndex = ComputeSiblingIndex(item);
string displayPathWithIndex = siblingIndex > 0
? $"{displayPath}#{siblingIndex}"
: displayPath;
string displayPathWithIndex = string.Join("/", parts);
return new AliasNodeIdentity(indexPath, displayPathWithIndex);
}
@ -129,10 +121,11 @@ namespace NavisworksTransport.Core.AliasTree
if (string.IsNullOrEmpty(key))
throw new ArgumentException("key 不能为空", nameof(key));
// 检查是否有双字段分隔符
// key 必须包含 "||" 分隔符
int separatorIndex = key.IndexOf("||", StringComparison.Ordinal);
if (separatorIndex >= 0)
{
if (separatorIndex < 0)
throw new FormatException($"key 缺少 || 分隔符: {key}");
string indexPath = key.Substring(0, separatorIndex);
string displayPath = key.Substring(separatorIndex + 2);
if (string.IsNullOrEmpty(displayPath))
@ -140,10 +133,6 @@ namespace NavisworksTransport.Core.AliasTree
return new AliasNodeIdentity(indexPath, displayPath);
}
// 向后兼容:纯 DisplayPath 格式(旧数据)
return new AliasNodeIdentity(string.Empty, key);
}
/// <summary>
/// 提前验证 key 字符串格式是否合法
/// </summary>

View File

@ -355,14 +355,6 @@ namespace NavisworksTransport.UI.WPF.Views
string parentPath = parentDisplayPath;
int sepIdx = parentPath.IndexOf("||", StringComparison.Ordinal);
if (sepIdx >= 0) parentPath = parentPath.Substring(sepIdx + 2);
// 去掉结尾的 #数字 后缀(中间层不加 siblingIndex
int hashIdx = parentPath.LastIndexOf('#');
if (hashIdx > 0)
{
string suffix = parentPath.Substring(hashIdx + 1);
bool isNumeric = suffix.Length > 0 && suffix.All(char.IsDigit);
if (isNumeric) parentPath = parentPath.Substring(0, hashIdx);
}
string displayPath = string.IsNullOrEmpty(parentPath)
? displayName
: parentPath + "/" + displayName;