feat: 富文本消息类型支持 — Markdown/代码块安全渲染 + 审查解析器

添加 review_parser.go 从 LLM 输出中提取 Markdown 和代码块,创建独立
ReviewMessage 类型 (markdown/code/search_result)。前端新增安全 Markdown
渲染器 (HTML 转义优先),代码块以深色背景+语言标签展示。Markdown/代码
类型禁止断句拆分,避免格式损坏。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 21:57:09 +08:00
parent 9f3b0f386d
commit 24f827fe02
10 changed files with 473 additions and 87 deletions
+52
View File
@@ -197,3 +197,55 @@
.tts-playing {
animation: tts-wave 1s ease-in-out infinite;
}
/* ===== Markdown 渲染样式 ===== */
.markdown-body h1 { font-size: 1.25rem; font-weight: 700; margin: 0.75rem 0 0.5rem; }
.markdown-body h2 { font-size: 1.1rem; font-weight: 700; margin: 0.75rem 0 0.4rem; }
.markdown-body h3 { font-size: 1rem; font-weight: 700; margin: 0.6rem 0 0.3rem; }
.markdown-body h4, .markdown-body h5, .markdown-body h6 { font-size: 0.95rem; font-weight: 600; margin: 0.5rem 0 0.25rem; }
.markdown-body p { margin: 0.3rem 0; }
.markdown-body ul, .markdown-body ol { margin: 0.3rem 0; padding-left: 1.5rem; }
.markdown-body li { margin: 0.15rem 0; }
.markdown-body ul li { list-style-type: disc; }
.markdown-body ol li { list-style-type: decimal; }
.markdown-body strong { font-weight: 700; color: inherit; }
.markdown-body em { font-style: italic; }
.markdown-body a { color: #ec4899; text-decoration: underline; word-break: break-all; }
.markdown-body a:hover { color: #be185d; }
.markdown-body blockquote {
border-left: 3px solid #f9a8d4;
padding-left: 0.75rem;
margin: 0.4rem 0;
color: #9ca3af;
font-style: italic;
}
.markdown-body hr { border: none; border-top: 1px solid #fce7f3; margin: 0.75rem 0; }
.markdown-body table { width: 100%; border-collapse: collapse; margin: 0.5rem 0; font-size: 0.85rem; }
.markdown-body th, .markdown-body td { border: 1px solid #fce7f3; padding: 0.35rem 0.6rem; text-align: left; }
.markdown-body th { background: #fdf2f8; font-weight: 600; }
.markdown-body img { max-width: 100%; height: auto; border-radius: 0.5rem; margin: 0.3rem 0; }
.markdown-body pre { background: #1e293b; border-radius: 0.5rem; padding: 0; margin: 0.5rem 0; overflow-x: auto; }
.markdown-body pre code { display: block; padding: 0.75rem 1rem; color: #e2e8f0; font-size: 0.8rem; line-height: 1.6; white-space: pre; }
.markdown-body code.inline-code {
background: #fce7f3;
color: #be185d;
padding: 0.1rem 0.35rem;
border-radius: 0.25rem;
font-size: 0.85em;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}
.markdown-body > *:first-child { margin-top: 0; }
.markdown-body > *:last-child { margin-bottom: 0; }
/* 深色模式 Markdown */
@media (prefers-color-scheme: dark) {
.markdown-body a { color: #f472b6; }
.markdown-body a:hover { color: #fbcfe8; }
.markdown-body blockquote { border-left-color: #9d174d; color: #9ca3af; }
.markdown-body th, .markdown-body td { border-color: #374151; }
.markdown-body th { background: #1f2937; }
.markdown-body hr { border-top-color: #374151; }
.markdown-body code.inline-code { background: #4a1942; color: #fbcfe8; }
.markdown-body pre { background: #0f172a; }
.markdown-body pre code { color: #e2e8f0; }
}