Commit 7d03462d authored by 水玉婷's avatar 水玉婷
Browse files

feat:样式优化

parent 7d94fbf4
src/assets/logo.png

28 KB | W: | H:

src/assets/logo.png

177 KB | W: | H:

src/assets/logo.png
src/assets/logo.png
src/assets/logo.png
src/assets/logo.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
stage: 'wechat-demo', stage: 'wechat-demo',
}; };
const dialogSessionId = '20251028143404893-00045166'; // const dialogSessionId = '20251028143404893-00045166';
// const dialogSessionId = ''; const dialogSessionId = '';
const detailData = ref({ const detailData = ref({
title: '国械小智', title: '国械小智',
}); });
......
...@@ -263,44 +263,82 @@ const contentTemplates = { ...@@ -263,44 +263,82 @@ const contentTemplates = {
} }
} }
// 简单的Markdown解析器 // 增强的Markdown解析器
const parseMarkdown = (text: string) => { const parseMarkdown = (text: string) => {
// 确保text是字符串 // 确保text是字符串
if (typeof text !== 'string') { if (typeof text !== 'string') {
text = String(text || ''); text = String(text || '');
} }
// 处理标题 // 转义HTML特殊字符,防止XSS攻击
text = text.replace(/^### (.*$)/gim, '<h3>$1</h3>'); text = text
text = text.replace(/^## (.*$)/gim, '<h2>$1</h2>'); .replace(/&/g, '&amp;')
text = text.replace(/^# (.*$)/gim, '<h1>$1</h1>'); .replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
// 处理粗体 .replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;');
// 处理标题(支持1-6级)
text = text.replace(/^######\s+(.*)$/gim, '<h6>$1</h6>');
text = text.replace(/^#####\s+(.*)$/gim, '<h5>$1</h5>');
text = text.replace(/^####\s+(.*)$/gim, '<h4>$1</h4>');
text = text.replace(/^###\s+(.*)$/gim, '<h3>$1</h3>');
text = text.replace(/^##\s+(.*)$/gim, '<h2>$1</h2>');
text = text.replace(/^#\s+(.*)$/gim, '<h1>$1</h1>');
// 处理粗体和斜体
text = text.replace(/\*\*(.*?)\*\*/gim, '<strong>$1</strong>'); text = text.replace(/\*\*(.*?)\*\*/gim, '<strong>$1</strong>');
text = text.replace(/\*(.*?)\*/gim, '<em>$1</em>'); text = text.replace(/\*(.*?)\*/gim, '<em>$1</em>');
text = text.replace(/__(.*?)__/gim, '<strong>$1</strong>');
text = text.replace(/_(.*?)_/gim, '<em>$1</em>');
// 处理删除线
text = text.replace(/~~(.*?)~~/gim, '<del>$1</del>');
// 处理代码块 // 处理代码块(支持语言标识)
text = text.replace(/```(\w+)?\n([\s\S]*?)```/gim, '<pre><code class="language-$1">$2</code></pre>');
text = text.replace(/```([\s\S]*?)```/gim, '<pre><code>$1</code></pre>'); text = text.replace(/```([\s\S]*?)```/gim, '<pre><code>$1</code></pre>');
text = text.replace(/`(.*?)`/gim, '<code>$1</code>'); text = text.replace(/`([^`]+)`/gim, '<code>$1</code>');
// 处理链接(支持相对路径和绝对路径)
text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/gim, (match, text, url) => {
// 验证URL格式
const isValidUrl = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i.test(url);
const target = isValidUrl ? 'target="_blank" rel="noopener noreferrer"' : '';
return `<a href="${url}" ${target}>${text}</a>`;
});
// 处理链接 // 处理图片(添加加载失败处理)
text = text.replace(/\[([^\[]+)\]\(([^\)]+)\)/gim, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'); text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/gim, (match, alt, src) => {
return `<img src="${src}" alt="${alt || '图片'}" style="max-width: 100%; height: auto;" onerror="this.style.display='none'" />`;
});
// 处理图片 // 处理有序列表
text = text.replace(/!\[([^\[]+)\]\(([^\)]+)\)/gim, '<img src="$2" alt="$1" style="max-width: 100%; height: auto;" />'); text = text.replace(/^\d+\.\s+(.*)$/gim, '<li>$1</li>');
text = text.replace(/(<li>.*<\/li>)(?=\s*<li>)/gim, '$1');
text = text.replace(/(<li>.*<\/li>)/gim, '<ol>$1</ol>');
// 处理列表 // 处理无序列表
text = text.replace(/^\s*-\s(.*$)/gim, '<li>$1</li>'); text = text.replace(/^[-*+]\s+(.*)$/gim, '<li>$1</li>');
text = text.replace(/(<li>.*<\/li>)/gim, '<ul>$1</ul>'); text = text.replace(/(<li>.*<\/li>)/gim, '<ul>$1</ul>');
// 处理换行 // 处理引用块
text = text.replace(/\n/gim, '<br>'); text = text.replace(/^>\s+(.*)$/gim, '<blockquote>$1</blockquote>');
// 处理水平分割线
text = text.replace(/^\s*---\s*$/gim, '<hr />');
text = text.replace(/^\s*\*\*\*\s*$/gim, '<hr />');
// 处理段落 // 处理换行(保留段落结构)
text = text.replace(/<br><br>/gim, '</p><p>'); text = text.replace(/\n{3,}/g, '\n\n'); // 多个换行合并为两个
text = text.replace(/\n\n/g, '</p><p>');
text = text.replace(/\n/g, '<br>');
text = '<p>' + text + '</p>'; text = '<p>' + text + '</p>';
text = text.replace(/<p><(h[1-6]|ul|pre|img)/gim, '</p><$1');
text = text.replace(/(<\/(h[1-6]|ul|pre|img)>)<p>/gim, '$1</p><p>'); // 清理HTML结构
text = text.replace(/<p><(h[1-6]|ul|ol|blockquote|pre|img|hr)/gim, '</p><$1');
text = text.replace(/(<\/(h[1-6]|ul|ol|blockquote|pre|img|hr)>)<p>/gim, '$1</p><p>');
text = text.replace(/<p>\s*<\/p>/g, ''); // 移除空段落
return text; return text;
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
@white: #ffffff; @white: #ffffff;
@gray-1: #f8f9fa; @gray-1: #f8f9fa;
@gray-2: #f5f5f5; @gray-2: #f5f5f5;
@gray-2-3: #ececec;
@gray-3: #e0e0e0; @gray-3: #e0e0e0;
@gray-4: #cccccc; @gray-4: #cccccc;
@gray-5: #999999; @gray-5: #999999;
...@@ -125,18 +126,22 @@ li { ...@@ -125,18 +126,22 @@ li {
// 聊天头部样式 // 聊天头部样式
.chat-header { .chat-header {
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
border-bottom: 1px solid #e8f2f1;
background: #FCFCFC;
padding: 10px 20px;
.header-avatar { .header-avatar {
width: 45px; width: 36px;
height: 45px; height: 36px;
border-radius: 50%; border-radius: 50%;
background-color: rgba(255, 255, 255, 0.2); background-color: rgba(255, 255, 255, 0.2);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 20px; font-size: 20px;
margin-right: 15px; margin-right: 8px;
border: 2px solid rgba(255, 255, 255, 0.3); border: 2px solid rgba(255, 255, 255, 0.3);
img { img {
...@@ -146,7 +151,7 @@ li { ...@@ -146,7 +151,7 @@ li {
} }
.header-info { .header-info {
flex: 1; // flex: 1;
h2 { h2 {
font-size: 18px; font-size: 18px;
...@@ -217,7 +222,7 @@ li { ...@@ -217,7 +222,7 @@ li {
justify-content: center; justify-content: center;
font-size: 16px; font-size: 16px;
color: @white; color: @white;
border: 2px solid @white; border: 1px solid @blue-light-1;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
img { img {
...@@ -380,6 +385,7 @@ li { ...@@ -380,6 +385,7 @@ li {
cursor: not-allowed; cursor: not-allowed;
} }
} }
.send-button { .send-button {
position: absolute; position: absolute;
right: 12px; right: 12px;
...@@ -756,7 +762,6 @@ li { ...@@ -756,7 +762,6 @@ li {
@media (max-width: 480px) { @media (max-width: 480px) {
:deep(.message-table) { :deep(.message-table) {
.data-table { .data-table {
th, th,
td { td {
min-width: 50px; min-width: 50px;
...@@ -767,10 +772,33 @@ li { ...@@ -767,10 +772,33 @@ li {
} }
@media (max-width: 600px) { @media (max-width: 600px) {
.header-avatar { .chat-container{
width: 40px; .chat-header {
height: 40px; padding: 2px 10px;
.header-info {
h2 {
font-size: 16px;
}
}
}
.header-avatar {
width: 40px;
height: 40px;
}
}
.avatar-container {
display: none;
}
.message{
margin-bottom: 8px;
} }
.chat-container{
.chat-input-container{
padding:12px;
}
}
} }
// ============================================= // =============================================
...@@ -1106,6 +1134,12 @@ li { ...@@ -1106,6 +1134,12 @@ li {
background: none; background: none;
} }
// 下划线
hr {
border: 0;
border-top: 1px solid @gray-2-3;
}
// 表格样式(如果Markdown中包含表格) // 表格样式(如果Markdown中包含表格)
table { table {
width: 100%; width: 100%;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment