聊天室更新markdown

This commit is contained in:
2025-12-25 12:33:12 +08:00
parent 41bc41cfcd
commit 78db3fc9e4
9 changed files with 578 additions and 35 deletions

View File

@@ -345,3 +345,86 @@ $brand-color-hover: #004488;
}
}
}
// ==================== Markdown样式 ====================
.message-bubble {
// 粗体
strong {
font-weight: 600;
color: inherit;
}
// 斜体
em {
font-style: italic;
}
// 行内代码
.inline-code {
background: rgba(0, 0, 0, 0.05);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 13px;
color: #e53e3e;
}
// 代码块
.code-block {
background: rgba(0, 0, 0, 0.05);
padding: 12px;
border-radius: 8px;
overflow-x: auto;
margin: 8px 0;
code {
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 13px;
line-height: 1.5;
color: #334155;
}
}
// 链接
.md-link {
color: $brand-color;
text-decoration: underline;
&:hover {
color: $brand-color-hover;
}
}
// 标题
.md-h1 {
font-size: 20px;
font-weight: 700;
margin: 12px 0 8px;
color: inherit;
}
.md-h2 {
font-size: 18px;
font-weight: 600;
margin: 10px 0 6px;
color: inherit;
}
.md-h3 {
font-size: 16px;
font-weight: 600;
margin: 8px 0 4px;
color: inherit;
}
// 列表
.md-ul, .md-ol {
margin: 8px 0;
padding-left: 20px;
}
.md-li {
margin: 4px 0;
line-height: 1.6;
}
}

View File

@@ -40,7 +40,10 @@
<!-- 消息内容 -->
<div class="message-content-wrapper">
<div class="message-bubble">
<p class="message-text">{{ message.content }}</p>
<div
class="message-text"
v-html="renderMarkdown(message.content || '')"
></div>
<!-- 文件列表 -->
<div v-if="message.files && message.files.length > 0" class="message-files">
@@ -235,14 +238,59 @@ const formatTime = (time?: string) => {
const date = new Date(time)
const now = new Date()
const diff = now.getTime() - date.getTime()
if (diff < 60000) return '刚刚'
if (diff < 3600000) return Math.floor(diff / 60000) + '分钟前'
if (diff < 86400000) return Math.floor(diff / 3600000) + '小时前'
return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' })
}
// Markdown渲染函数
const renderMarkdown = (text: string): string => {
if (!text) return ''
// 转义HTML标签
let html = text
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
// 处理代码块(```语法)
html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
return `<pre class="code-block"><code class="language-${lang || 'text'}">${code.trim()}</code></pre>`
})
// 处理行内代码(`语法)
html = html.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>')
// 处理粗体(**语法)
html = html.replace(/\*\*([^\*]+)\*\*/g, '<strong>$1</strong>')
// 处理斜体(*语法)
html = html.replace(/\*([^\*]+)\*/g, '<em>$1</em>')
// 处理链接([text](url)语法)
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" class="md-link">$1</a>')
// 处理标题(# ## ###等)
html = html.replace(/^### (.+)$/gm, '<h3 class="md-h3">$1</h3>')
html = html.replace(/^## (.+)$/gm, '<h2 class="md-h2">$1</h2>')
html = html.replace(/^# (.+)$/gm, '<h1 class="md-h1">$1</h1>')
// 处理无序列表(- 或 * 开头)
html = html.replace(/^[*-] (.+)$/gm, '<li class="md-li">$1</li>')
html = html.replace(/(<li class="md-li">.*<\/li>)/s, '<ul class="md-ul">$1</ul>')
// 处理有序列表(数字. 开头)
html = html.replace(/^\d+\. (.+)$/gm, '<li class="md-li">$1</li>')
// 处理换行
html = html.replace(/\n/g, '<br>')
return html
}
// 暴露方法给父组件
defineExpose({
scrollToBottom