From 709a0d702347c472fe4fb96e7dda5252db467863 Mon Sep 17 00:00:00 2001 From: 666ghj <670939375@qq.com> Date: Sat, 14 Feb 2026 17:04:04 +0800 Subject: [PATCH] feat(report_agent): enhance markdown rendering for lists and improve formatting; support nested lists and clean up HTML output --- frontend/src/components/Step4Report.vue | 75 ++++++++++++++++---- frontend/src/components/Step5Interaction.vue | 28 +++++++- 2 files changed, 89 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/Step4Report.vue b/frontend/src/components/Step4Report.vue index f44aedc..f383344 100644 --- a/frontend/src/components/Step4Report.vue +++ b/frontend/src/components/Step4Report.vue @@ -1887,14 +1887,29 @@ const renderMarkdown = (content) => { // 处理引用块 html = html.replace(/^> (.+)$/gm, '
$1
') - // 处理无序列表 - html = html.replace(/^- (.+)$/gm, '
  • $1
  • ') - html = html.replace(/(
  • [\s\S]*?<\/li>)(\s*.*<\/li>)+/g, '') - - // 处理有序列表 - html = html.replace(/^\d+\. (.+)$/gm, '
  • $1
  • ') - html = html.replace(/(
  • .*<\/li>)+/g, '
      $&
    ') + // 处理列表 - 支持子列表 + html = html.replace(/^(\s*)- (.+)$/gm, (match, indent, text) => { + const level = Math.floor(indent.length / 2) + return `
  • ${text}
  • ` + }) + html = html.replace(/^(\s*)(\d+)\. (.+)$/gm, (match, indent, num, text) => { + const level = Math.floor(indent.length / 2) + return `
  • ${text}
  • ` + }) + + // 包装无序列表 + html = html.replace(/(
  • ]*>.*?<\/li>\s*)+/g, '') + // 包装有序列表 + html = html.replace(/(
  • ]*>.*?<\/li>\s*)+/g, '
      $&
    ') + + // 清理列表项之间的所有空白 + html = html.replace(/<\/li>\s+
  • \s+/g, '') + html = html.replace(/\s+<\/ol>/g, '') // 处理粗体和斜体 html = html.replace(/\*\*(.+?)\*\*/g, '$1') @@ -1917,7 +1932,40 @@ const renderMarkdown = (content) => { html = html.replace(/(<\/h[2-5]>)<\/p>/g, '$1') html = html.replace(/

    (|<\/ol>|<\/blockquote>|<\/pre>)<\/p>/g, '$1') - + // 清理列表前后的
    标签 + html = html.replace(/
    \s*(|<\/ol>)\s*
    /g, '$1') + // 清理连续的
    标签 + html = html.replace(/(
    \s*){2,}/g, '
    ') + // 清理列表后紧跟的段落开始标签前的
    + html = html.replace(/(<\/ol>|<\/ul>)
    ( 被段落内容隔开时,保持编号递增 + const tokens = html.split(/(

      (?:
    1. ]*>[\s\S]*?<\/li>)+<\/ol>)/g) + let olCounter = 0 + let inSequence = false + for (let i = 0; i < tokens.length; i++) { + if (tokens[i].startsWith('
        ')) { + const liCount = (tokens[i].match(/
      1. 1) { + tokens[i] = tokens[i].replace('
          ', `
            `) + } + inSequence = true + } else { + olCounter = 0 + inSequence = false + } + } else if (inSequence) { + if (/ props.reportId, (newId) => { .generated-content :deep(.md-ul), .generated-content :deep(.md-ol) { - padding-left: 20px; - margin-bottom: 1em; + padding-left: 24px; + margin: 12px 0; } -.generated-content :deep(.md-li) { - margin-bottom: 0.5em; +.generated-content :deep(.md-li), +.generated-content :deep(.md-oli) { + margin: 6px 0; } .generated-content :deep(.md-quote) { diff --git a/frontend/src/components/Step5Interaction.vue b/frontend/src/components/Step5Interaction.vue index abade15..d09de03 100644 --- a/frontend/src/components/Step5Interaction.vue +++ b/frontend/src/components/Step5Interaction.vue @@ -606,7 +606,33 @@ const renderMarkdown = (content) => { html = html.replace(/(
            \s*){2,}/g, '
            ') // 清理列表后紧跟的段落开始标签前的
            html = html.replace(/(<\/ol>|<\/ul>)
            ( 被段落内容隔开时,保持编号递增 + const tokens = html.split(/(
              (?:
            1. ]*>[\s\S]*?<\/li>)+<\/ol>)/g) + let olCounter = 0 + let inSequence = false + for (let i = 0; i < tokens.length; i++) { + if (tokens[i].startsWith('
                ')) { + const liCount = (tokens[i].match(/
              1. 1) { + tokens[i] = tokens[i].replace('
                  ', `
                    `) + } + inSequence = true + } else { + olCounter = 0 + inSequence = false + } + } else if (inSequence) { + if (/