Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sdream-ai-fe
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
侯明涛
sdream-ai-fe
Commits
80e91beb
Commit
80e91beb
authored
Dec 18, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:流式换行处理
parent
4780fa33
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
30 additions
and
8 deletions
+30
-8
src/pages/Chat/Chat.tsx
+5
-2
src/pages/Chat/components/ChatItem/markdownFormatter.ts
+16
-2
src/pages/ChatTactics/TacticsChat.tsx
+9
-4
No files found.
src/pages/Chat/Chat.tsx
View file @
80e91beb
...
...
@@ -8,6 +8,7 @@ import { processApiResponse } from './helper'
import
{
ChatWelcome
}
from
'./components/ChatWelcome'
import
{
ChatItemUser
}
from
'./components/ChatItem/ChatItemUser'
import
{
ChatAnswerBox
}
from
'./components/ChatItem/ChatAnswerBox'
import
{
trimSpacesOnly
}
from
'./components/ChatItem/markdownFormatter'
import
{
ChatEditor
}
from
'@/components/ChatEditor'
import
type
{
ChatRecord
}
from
'@/types/chat'
import
{
fetchUserQaRecordPage
}
from
'@/api/conversation'
...
...
@@ -162,9 +163,11 @@ export const Chat: React.FC = () => {
// 创建最后一项的新对象,合并现有数据和新的 answer
const
originalAnswer
=
(
newItems
[
lastIndex
].
answerList
?.[
0
]?.
answer
||
''
)
+
msg
.
content
.
data
.
answer
// 移除所有括号及其内容
let
filteredAnswer
=
originalAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
.
trim
()
let
filteredAnswer
=
originalAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
).
trim
()
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
)
// 只移除空格和制表符,保留换行符(避免移除末尾的 \n\n)
filteredAnswer
=
trimSpacesOnly
(
filteredAnswer
)
newItems
[
lastIndex
]
=
{
...
newItems
[
lastIndex
],
...
...
src/pages/Chat/components/ChatItem/markdownFormatter.ts
View file @
80e91beb
/**
* 只移除字符串开头和结尾的空格和制表符,保留换行符
* 用于流式处理时保留末尾的 \n\n 换行符
*/
export
function
trimSpacesOnly
(
text
:
string
):
string
{
return
text
.
replace
(
/^
[
\t]
+|
[
\t]
+$/g
,
''
)
}
export
function
formatMarkdown
(
text
:
string
):
string
{
// 首先移除 ♪ 符号之后的所有文本
let
formattedText
=
text
.
split
(
'♪'
)[
0
].
trim
()
// 使用 trimSpacesOnly 保留换行符,避免移除末尾的 \n\n
let
formattedText
=
text
.
split
(
'♪'
)[
0
]
formattedText
=
trimSpacesOnly
(
formattedText
)
// 处理换行
formattedText
=
formattedText
.
replace
(
/
(?<
!
\n)\n(?!\n)
/g
,
'
\
n'
)
// 先处理连续的换行符(\n\n 或更多),确保它们被保留为段落分隔
// 然后将单独的 \n 替换为 Markdown 的硬换行(两个空格 + \n)
// 注意:\n\n 在 Markdown 中表示段落分隔,应该被保留
formattedText
=
formattedText
.
replace
(
/
\n{3,}
/g
,
'
\
n
\
n'
)
// 将3个或更多连续换行符压缩为2个
formattedText
=
formattedText
.
replace
(
/
(?<
!
\n)\n(?!\n)
/g
,
'
\
n'
)
// 单独的 \n 转换为硬换行
// 处理代码块
formattedText
=
formattedText
.
replace
(
/```
(\w
+
)?\n([\s\S]
*
?)\n
```/g
,
(
match
,
language
,
code
)
=>
{
...
...
src/pages/ChatTactics/TacticsChat.tsx
View file @
80e91beb
...
...
@@ -8,6 +8,7 @@ import styles from '../Chat/Chat.module.less'
import
{
processApiResponse
}
from
'../Chat/helper'
import
{
ChatItemUser
}
from
'../Chat/components/ChatItem/ChatItemUser'
import
{
ChatAnswerBox
}
from
'../Chat/components/ChatItem/ChatAnswerBox'
import
{
trimSpacesOnly
}
from
'../Chat/components/ChatItem/markdownFormatter'
import
{
TacticsWelcome
}
from
'./components/TacticsWelcome'
import
DeleteIcon
from
'@/assets/svg/delete.svg?react'
import
RefreshIcon
from
'@/assets/svg/refresh.svg?react'
...
...
@@ -282,9 +283,11 @@ export const TacticsChat: React.FC = () => {
// 移除 ♪ 符号之后的所有文本(与历史记录保持一致)
let
filteredAnswer
=
originalAnswer
.
split
(
'♪'
)[
0
]
// 移除所有括号及其内容
filteredAnswer
=
filteredAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
.
trim
()
filteredAnswer
=
filteredAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
).
trim
()
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
)
// 只移除空格和制表符,保留换行符(避免移除末尾的 \n\n)
filteredAnswer
=
trimSpacesOnly
(
filteredAnswer
)
newItems
[
lastAiIndex
]
=
{
...
newItems
[
lastAiIndex
],
...
...
@@ -312,9 +315,11 @@ export const TacticsChat: React.FC = () => {
// 移除 ♪ 符号之后的所有文本(与历史记录保持一致)
let
filteredAnswer
=
newAnswer
.
split
(
'♪'
)[
0
]
// 移除所有括号及其内容
filteredAnswer
=
filteredAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
.
trim
()
filteredAnswer
=
filteredAnswer
.
replace
(
/
\([^
)
]
*
\)
/g
,
''
)
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
).
trim
()
filteredAnswer
=
filteredAnswer
.
replace
(
/
\[
参考文档
(?:
《
[^
》
]
*》
\s
*
)
+
\]
/g
,
''
)
// 只移除空格和制表符,保留换行符(避免移除末尾的 \n\n)
filteredAnswer
=
trimSpacesOnly
(
filteredAnswer
)
newItems
.
push
({
role
:
'ai'
,
question
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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