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
eea71f34
Commit
eea71f34
authored
Mar 24, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:饼图对重新分析的影响
parent
84526182
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
32 additions
and
21 deletions
+32
-21
src/pages/Chat/components/ChatItem/ChatAnswerParser.tsx
+32
-21
No files found.
src/pages/Chat/components/ChatItem/ChatAnswerParser.tsx
View file @
eea71f34
import
React
,
{
useEffect
,
use
Ref
,
use
State
}
from
'react'
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
Chip
}
from
'@heroui/react'
import
{
ChatAnswerAttachment
}
from
'./ChatAnswerAttchment'
import
{
ChatAnswerOperate
}
from
'./ChatAnswerOperate'
...
...
@@ -43,10 +43,11 @@ function CheckIcon({ ...props }) {
export
const
ChatAnswerParser
:
React
.
FC
<
ChatAnswerParserProps
>
=
({
isLastAnswer
,
onTyping
,
onComplate
,
answer
,
isStopTyping
,
onSubmitQuestion
,
hideOperate
,
onWorkflowSubmit
,
isWorkflowSubmitting
,
isAsking
=
false
})
=>
{
const
formatAnswer
=
formatMarkdown
(
answer
.
answer
||
''
)
const
[
displayedText
,
setDisplayedText
]
=
useState
(
''
)
const
[
currentIndex
,
setCurrentIndex
]
=
useState
(
0
)
const
[
isTyping
,
setIsTyping
]
=
useState
(
false
)
const
[
hideOperateByCard
,
setHideOperateByCard
]
=
useState
(
false
)
const
[
isImageAnswer
,
setIsImageAnswer
]
=
useState
(
false
)
const
[
hasProcessedCardList
,
setHasProcessedCardList
]
=
useState
(
false
)
// 添加标记,避免重复处理cardList
const
completedOnceRef
=
useRef
(
false
)
function
extractImageSources
(
htmlString
:
string
):
string
[]
{
const
imgRegex
=
/<img
[^
>
]
+src="
([^
">
]
+
)
"/gi
...
...
@@ -118,34 +119,44 @@ export const ChatAnswerParser: React.FC<ChatAnswerParserProps> = ({ isLastAnswer
}
useEffect
(()
=>
{
// Streaming stage: render plain text only (no markdown parsing / no typewriter),
// to avoid heavy re-rendering and page flicker.
if
(
!
answer
.
endAnswerFlag
)
{
setDisplayedText
(
answer
.
answer
||
''
)
setIsTyping
(
false
)
completedOnceRef
.
current
=
false
if
(
isStopTyping
)
{
return
}
// Stream ended: render full markdown once (no typewriter) to avoid heavy re-renders.
if
(
completedOnceRef
.
current
)
return
completedOnceRef
.
current
=
true
// Keep existing contract: notify typing start/end callbacks once.
if
(
!
isTyping
)
{
onTyping
()
setIsTyping
(
false
)
if
(
formatAnswer
.
includes
(
'<img'
))
{
setIsTyping
(
true
)
}
if
(
currentIndex
<
formatAnswer
.
length
)
{
const
nextChar
=
formatAnswer
[
currentIndex
]
if
(
nextChar
===
'<'
||
isImageAnswer
)
{
setIsImageAnswer
(
true
)
const
timer
=
setTimeout
(()
=>
{
setCurrentIndex
(
prevIndex
=>
prevIndex
+
1
)
},
10
)
// 调整此值以改变打字速度
return
()
=>
clearTimeout
(
timer
)
}
else
{
const
timer
=
setTimeout
(()
=>
{
setDisplayedText
(
formatAnswer
.
slice
(
0
,
currentIndex
+
1
))
setCurrentIndex
(
prevIndex
=>
prevIndex
+
1
)
},
10
)
// 调整此值以改变打字速度
return
()
=>
clearTimeout
(
timer
)
}
}
else
{
if
(
answer
.
endAnswerFlag
)
{
if
(
isImageAnswer
)
{
handleImageAnswer
()
}
else
{
setDisplayedText
(
formatAnswer
)
setIsTyping
(
false
)
onComplate
()
}
// 流式输出结束时检查 cardList 中的 URL
handleCardListUrls
()
},
[
answer
.
endAnswerFlag
,
answer
.
answer
])
}
}
},
[
answer
,
currentIndex
])
const
handleStopTyping
=
async
()
=>
{
const
res
=
await
fetchTerminateQuestion
(
answer
)
...
...
@@ -186,7 +197,7 @@ export const ChatAnswerParser: React.FC<ChatAnswerParserProps> = ({ isLastAnswer
{
!!
displayedText
.
length
&&
(
<
div
style=
{
{
background
:
'#F7FAFD'
}
}
className=
{
answer
.
cardList
?.
length
?
'mb-[20px]'
:
''
}
>
<
MarkdownDetail
disablePie=
{
!
answer
.
endAnswerFlag
}
>
<
MarkdownDetail
>
{
displayedText
}
</
MarkdownDetail
>
</
div
>
...
...
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