Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
水玉婷
ai-wechat
Commits
7d03462d
Commit
7d03462d
authored
Nov 27, 2025
by
水玉婷
Browse files
feat:样式优化
parent
7d94fbf4
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/assets/logo.png
View replaced file @
7d94fbf4
View file @
7d03462d
28 KB
|
W:
|
H:
177 KB
|
W:
|
H:
2-up
Swipe
Onion skin
src/views/Home.vue
View file @
7d03462d
...
...
@@ -40,8 +40,8 @@
stage
:
'
wechat-demo
'
,
};
const
dialogSessionId
=
'
20251028143404893-00045166
'
;
//
const dialogSessionId = '';
//
const dialogSessionId = '20251028143404893-00045166';
const
dialogSessionId
=
''
;
const
detailData
=
ref
({
title
:
'
国械小智
'
,
});
...
...
src/views/components/AiChat.vue
View file @
7d03462d
...
...
@@ -263,44 +263,82 @@ const contentTemplates = {
}
}
//
简单
的Markdown解析器
//
增强
的Markdown解析器
const
parseMarkdown
=
(
text
:
string
)
=>
{
// 确保text是字符串
if
(
typeof
text
!==
'
string
'
)
{
text
=
String
(
text
||
''
);
}
// 处理标题
text
=
text
.
replace
(
/^###
(
.*$
)
/gim
,
'
<h3>$1</h3>
'
);
text
=
text
.
replace
(
/^##
(
.*$
)
/gim
,
'
<h2>$1</h2>
'
);
text
=
text
.
replace
(
/^#
(
.*$
)
/gim
,
'
<h1>$1</h1>
'
);
// 处理粗体
// 转义HTML特殊字符,防止XSS攻击
text
=
text
.
replace
(
/&/g
,
'
&
'
)
.
replace
(
/</g
,
'
<
'
)
.
replace
(
/>/g
,
'
>
'
)
.
replace
(
/"/g
,
'
"
'
)
.
replace
(
/'/g
,
'
'
'
);
// 处理标题(支持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
,
'
<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
(
/`
(
.*
?)
`/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
(
/
\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
=
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
;
};
...
...
src/views/components/style.less
View file @
7d03462d
...
...
@@ -12,6 +12,7 @@
@white: #ffffff;
@gray-1: #f8f9fa;
@gray-2: #f5f5f5;
@gray-2-3: #ececec;
@gray-3: #e0e0e0;
@gray-4: #cccccc;
@gray-5: #999999;
...
...
@@ -125,18 +126,22 @@ li {
// 聊天头部样式
.chat-header {
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e8f2f1;
background: #FCFCFC;
padding: 10px 20px;
.header-avatar {
width:
45
px;
height:
45
px;
width:
36
px;
height:
36
px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
margin-right:
15
px;
margin-right:
8
px;
border: 2px solid rgba(255, 255, 255, 0.3);
img {
...
...
@@ -146,7 +151,7 @@ li {
}
.header-info {
flex: 1;
//
flex: 1;
h2 {
font-size: 18px;
...
...
@@ -217,7 +222,7 @@ li {
justify-content: center;
font-size: 16px;
color: @white;
border:
2
px solid @
white
;
border:
1
px solid @
blue-light-1
;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
img {
...
...
@@ -380,6 +385,7 @@ li {
cursor: not-allowed;
}
}
.send-button {
position: absolute;
right: 12px;
...
...
@@ -756,7 +762,6 @@ li {
@media (max-width: 480px) {
:deep(.message-table) {
.data-table {
th,
td {
min-width: 50px;
...
...
@@ -767,10 +772,33 @@ li {
}
@media (max-width: 600px) {
.header-avatar {
width: 40px;
height: 40px;
.chat-container{
.chat-header {
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 {
background: none;
}
// 下划线
hr {
border: 0;
border-top: 1px solid @gray-2-3;
}
// 表格样式(如果Markdown中包含表格)
table {
width: 100%;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment