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
e7399f86
Commit
e7399f86
authored
Jan 08, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 切换工具时重复调用接口问题
parent
0a7d4e3c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
76 additions
and
2 deletions
+76
-2
src/components/ChatEditor/index.tsx
+35
-0
src/pages/Chat/Chat.tsx
+41
-2
No files found.
src/components/ChatEditor/index.tsx
View file @
e7399f86
...
@@ -131,10 +131,30 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -131,10 +131,30 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
await
waitForToken
()
await
waitForToken
()
// 从路由中获取 userRoles 参数
// 从路由中获取 userRoles 参数
const
userRoles
=
getUserRolesForApi
()
const
userRoles
=
getUserRolesForApi
()
// 检查缓存(包含 userRoles 信息,有效期 5 分钟)
const
cacheKey
=
`toolList_
${
JSON
.
stringify
(
userRoles
)}
`
const
cached
=
sessionStorage
.
getItem
(
cacheKey
)
if
(
cached
)
{
try
{
const
{
toolList
,
timestamp
}
=
JSON
.
parse
(
cached
)
if
(
Date
.
now
()
-
timestamp
<
5
*
60
*
1000
)
{
setToolList
(
toolList
)
return
}
}
catch
{
// 缓存解析失败,继续调用接口
}
}
// 调用真实 API 获取工具列表
// 调用真实 API 获取工具列表
const
res
=
await
fetchToolList
({
userRoles
})
const
res
=
await
fetchToolList
({
userRoles
})
if
(
res
?.
data
&&
Array
.
isArray
(
res
.
data
)
&&
res
.
data
.
length
>
0
)
{
if
(
res
?.
data
&&
Array
.
isArray
(
res
.
data
)
&&
res
.
data
.
length
>
0
)
{
setToolList
(
res
.
data
)
setToolList
(
res
.
data
)
// 缓存工具列表(包含 userRoles 和时间戳)
sessionStorage
.
setItem
(
cacheKey
,
JSON
.
stringify
({
toolList
:
res
.
data
,
timestamp
:
Date
.
now
(),
}))
}
}
}
}
catch
(
error
)
{
catch
(
error
)
{
...
@@ -331,11 +351,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -331,11 +351,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
res
=
await
fetchSessionConversationId
(
requestData
)
const
res
=
await
fetchSessionConversationId
(
requestData
)
if
(
res
?.
data
?.
conversationId
)
{
if
(
res
?.
data
?.
conversationId
)
{
const
conversationId
=
res
.
data
.
conversationId
const
conversationId
=
res
.
data
.
conversationId
// 在 navigate 之前设置标记,避免 Chat 组件的 useEffect 重复调用接口
sessionStorage
.
setItem
(
'toolHistoryLoading'
,
conversationId
)
// 更新路由到新的会话ID
// 更新路由到新的会话ID
navigate
(
`/chat/
${
conversationId
}
`
,
{
navigate
(
`/chat/
${
conversationId
}
`
,
{
replace
:
true
,
replace
:
true
,
state
:
{
state
:
{
toolId
:
null
,
toolId
:
null
,
skipHistoryLoad
:
true
,
// 标记跳过历史记录加载,因为 ChatEditor 会处理
},
},
})
})
// 使用获取到的会话ID调用历史会话
// 使用获取到的会话ID调用历史会话
...
@@ -351,10 +374,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -351,10 +374,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
qaRecords
:
qaRes
?.
data
||
[],
qaRecords
:
qaRes
?.
data
||
[],
},
},
}))
}))
// 清除标记,避免影响后续路由切换
sessionStorage
.
removeItem
(
'toolHistoryLoading'
)
}
}
}
}
catch
(
error
)
{
catch
(
error
)
{
console
.
error
(
'获取会话ID或历史记录失败:'
,
error
)
console
.
error
(
'获取会话ID或历史记录失败:'
,
error
)
// 出错时也要清除标记
sessionStorage
.
removeItem
(
'toolHistoryLoading'
)
}
}
}
}
...
@@ -388,11 +415,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -388,11 +415,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
res
=
await
fetchSessionConversationId
(
requestData
)
const
res
=
await
fetchSessionConversationId
(
requestData
)
if
(
res
?.
data
?.
conversationId
)
{
if
(
res
?.
data
?.
conversationId
)
{
const
conversationId
=
res
.
data
.
conversationId
const
conversationId
=
res
.
data
.
conversationId
// 在 navigate 之前设置标记,避免 Chat 组件的 useEffect 重复调用接口
// 使用 sessionStorage 作为标记,因为 location.state 可能有时序问题
sessionStorage
.
setItem
(
'toolHistoryLoading'
,
conversationId
)
// 更新路由到新的会话ID,并携带 toolId 参数
// 更新路由到新的会话ID,并携带 toolId 参数
navigate
(
`/chat/
${
conversationId
}
?toolId=
${
tool
.
toolId
}
`
,
{
navigate
(
`/chat/
${
conversationId
}
?toolId=
${
tool
.
toolId
}
`
,
{
replace
:
true
,
replace
:
true
,
state
:
{
state
:
{
toolId
:
tool
.
toolId
,
toolId
:
tool
.
toolId
,
skipHistoryLoad
:
true
,
// 标记跳过历史记录加载,因为 ChatEditor 会处理
},
},
})
})
// 使用获取到的会话ID调用历史会话
// 使用获取到的会话ID调用历史会话
...
@@ -408,10 +439,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -408,10 +439,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
qaRecords
:
qaRes
?.
data
||
[],
qaRecords
:
qaRes
?.
data
||
[],
},
},
}))
}))
// 清除标记,避免影响后续路由切换
sessionStorage
.
removeItem
(
'toolHistoryLoading'
)
}
}
}
}
catch
(
error
)
{
catch
(
error
)
{
console
.
error
(
'获取会话ID或历史记录失败:'
,
error
)
console
.
error
(
'获取会话ID或历史记录失败:'
,
error
)
// 出错时也要清除标记
sessionStorage
.
removeItem
(
'toolHistoryLoading'
)
}
}
}
}
...
...
src/pages/Chat/Chat.tsx
View file @
e7399f86
...
@@ -539,6 +539,19 @@ export const Chat: React.FC = () => {
...
@@ -539,6 +539,19 @@ export const Chat: React.FC = () => {
return
return
}
}
// 检查是否正在通过工具切换加载历史记录(ChatEditor 正在处理)
// 通过 sessionStorage 标记判断,避免时序问题导致的重复调用
const
toolHistoryLoadingId
=
sessionStorage
.
getItem
(
'toolHistoryLoading'
)
if
(
toolHistoryLoadingId
===
id
)
{
console
.
log
(
'[Chat] 检测到 toolHistoryLoading 标记,ChatEditor 正在加载历史记录,跳过重复调用'
)
currentIdRef
.
current
=
id
// 更新 toolId 相关状态(如果有)
if
(
initialToolId
!==
undefined
)
{
toolIdFromStateRef
.
current
=
initialToolId
}
return
}
// 检查是否跳过历史记录加载(点击常见问题时)
// 检查是否跳过历史记录加载(点击常见问题时)
const
skipHistoryLoad
=
Boolean
((
location
.
state
as
{
skipHistoryLoad
?:
boolean
}
|
null
)?.
skipHistoryLoad
)
const
skipHistoryLoad
=
Boolean
((
location
.
state
as
{
skipHistoryLoad
?:
boolean
}
|
null
)?.
skipHistoryLoad
)
if
(
skipHistoryLoad
)
{
if
(
skipHistoryLoad
)
{
...
@@ -654,9 +667,30 @@ export const Chat: React.FC = () => {
...
@@ -654,9 +667,30 @@ export const Chat: React.FC = () => {
const
getToolNameFromToolId
=
async
()
=>
{
const
getToolNameFromToolId
=
async
()
=>
{
if
(
currentToolId
)
{
if
(
currentToolId
)
{
try
{
try
{
// 等待 token 就绪后再调用接口
// 优先从缓存读取工具列表,避免重复调用接口
await
waitForToken
()
const
userRoles
=
getUserRolesForApi
()
const
userRoles
=
getUserRolesForApi
()
const
cacheKey
=
`toolList_
${
JSON
.
stringify
(
userRoles
)}
`
const
cached
=
sessionStorage
.
getItem
(
cacheKey
)
if
(
cached
)
{
try
{
const
{
toolList
,
timestamp
}
=
JSON
.
parse
(
cached
)
// 缓存有效(5分钟内)
if
(
Date
.
now
()
-
timestamp
<
5
*
60
*
1000
)
{
const
tool
=
toolList
.
find
((
t
:
any
)
=>
t
.
toolId
===
currentToolId
)
if
(
tool
?.
toolName
)
{
setCurrentToolName
(
tool
.
toolName
)
return
}
}
}
catch
{
// 缓存解析失败,继续调用接口
}
}
// 缓存无效或找不到工具时才调用接口
await
waitForToken
()
const
res
=
await
fetchToolList
({
userRoles
})
const
res
=
await
fetchToolList
({
userRoles
})
if
(
res
?.
data
)
{
if
(
res
?.
data
)
{
const
tool
=
res
.
data
.
find
((
t
:
any
)
=>
t
.
toolId
===
currentToolId
)
const
tool
=
res
.
data
.
find
((
t
:
any
)
=>
t
.
toolId
===
currentToolId
)
...
@@ -745,6 +779,11 @@ export const Chat: React.FC = () => {
...
@@ -745,6 +779,11 @@ export const Chat: React.FC = () => {
setIsLoading
(
false
)
setIsLoading
(
false
)
// 标记该会话的历史记录已加载完成(通过工具切换事件加载)
// 标记该会话的历史记录已加载完成(通过工具切换事件加载)
historyLoadedRef
.
current
.
conversationId
=
conversationId
historyLoadedRef
.
current
.
conversationId
=
conversationId
// 清除 toolHistoryLoading 标记,避免影响后续路由切换
const
toolHistoryLoadingId
=
sessionStorage
.
getItem
(
'toolHistoryLoading'
)
if
(
toolHistoryLoadingId
===
conversationId
)
{
sessionStorage
.
removeItem
(
'toolHistoryLoading'
)
}
}
}
}
}
window
.
addEventListener
(
'toolHistoryLoaded'
,
handleToolHistoryLoaded
as
EventListener
)
window
.
addEventListener
(
'toolHistoryLoaded'
,
handleToolHistoryLoaded
as
EventListener
)
...
...
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