Files
XCSDD/.trae/documents/fix_doc_link_matching_plan.md
ssdfasd 58a83f445a fix: improve doc link navigation and tree display
- Fix link resolution with proper relative/absolute path handling
- Improve link styling with underline decoration
- Hide leaf nodes from tree, only show directories
- Fix log file path for packaged app
2026-03-19 12:44:08 +08:00

3.4 KiB
Raw Blame History

修复文档链接匹配逻辑计划

1. 问题分析

用户反馈点击 rhi/buffer/d3d12/buffer.md 中的 [Initialize](initialize.md) 链接时,错误跳转到了 Logger::Initialize(可能位于其他目录)。 经过检查 src/components/ApiDocViewer.tsx 中的 handleReferenceClick 方法:

  const handleReferenceClick = useCallback((href: string) => {
    const ref = href.replace(/\.md$/, '')
    const match = externalDocs.find(d => {
      const docPath = d.relativePath.replace(/\.md$/, '')
      return docPath === ref || docPath.endsWith('/' + ref.split('/').pop())
    })
    if (match) {
      setSelectedPath(match.relativePath)
      setCurrentContent(match.content)
    }
  }, [externalDocs])

当前的匹配逻辑非常危险:docPath.endsWith('/' + ref.split('/').pop()) 这一行意味着只要文件名匹配(例如 initialize.md),不管它在哪个目录下,都可能被匹配到。这导致了跨目录的同名文件匹配错误。

2. 修复方案

修改文件: src/components/ApiDocViewer.tsx

我们需要实现基于当前文档路径的相对路径解析逻辑。由于 handleReferenceClick 目前只接收 href,我们需要让它知道当前所在的文档路径(selectedPath),以便正确解析相对路径。

  1. 依赖当前路径:确保 handleReferenceClick 能访问到 selectedPath
  2. 实现相对路径解析
    • 如果链接以 / 开头,视为基于文档根目录的绝对路径。
    • 如果是相对路径(./../ 或直接文件名),则基于当前文档的目录进行解析。
    • 解析出目标文件的完整 relativePath 后,再在 externalDocs 中查找精确匹配。

修改后的逻辑伪代码

  const handleReferenceClick = useCallback((href: string) => {
    // 1. 获取当前文档所在的目录
    const currentDir = selectedPath ? selectedPath.split('/').slice(0, -1).join('/') : '';
    
    // 2. 解析目标路径
    let targetPath = '';
    if (href.startsWith('/')) {
        // 绝对路径(相对于文档根目录)
        targetPath = href.slice(1);
    } else {
        // 相对路径处理
        const parts = currentDir ? currentDir.split('/') : [];
        const hrefParts = href.split('/');
        
        for (const part of hrefParts) {
            if (part === '.') continue;
            if (part === '..') {
                parts.pop();
            } else {
                parts.push(part);
            }
        }
        targetPath = parts.join('/');
    }
    
    // 3. 规范化目标路径(移除 .md 后缀以便对比,或者直接对比全名)
    // 考虑到 externalDocs 中的 relativePath 包含 .md我们也应该构造包含 .md 的路径
    if (!targetPath.endsWith('.md')) {
        targetPath += '.md';
    }

    // 4. 精确查找
    const match = externalDocs.find(d => d.relativePath === targetPath);
    
    if (match) {
      setSelectedPath(match.relativePath)
      setCurrentContent(match.content)
    } else {
       console.warn(`Document not found: ${targetPath}`);
    }
  }, [externalDocs, selectedPath]) // 添加 selectedPath 依赖

3. 影响与验证

  • 影响:修复了所有相对路径链接的跳转逻辑,不再会出现跨目录同名文件乱跳的情况。
  • 验证:点击 rhi/buffer/d3d12/buffer.md 中的 initialize.md,应该正确跳转到同目录下的 rhi/buffer/d3d12/initialize.md