Commit e7399f86 by Liu

fix: 切换工具时重复调用接口问题

parent 0a7d4e3c
......@@ -131,10 +131,30 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
await waitForToken()
// 从路由中获取 userRoles 参数
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 获取工具列表
const res = await fetchToolList({ userRoles })
if (res?.data && Array.isArray(res.data) && res.data.length > 0) {
setToolList(res.data)
// 缓存工具列表(包含 userRoles 和时间戳)
sessionStorage.setItem(cacheKey, JSON.stringify({
toolList: res.data,
timestamp: Date.now(),
}))
}
}
catch (error) {
......@@ -331,11 +351,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const res = await fetchSessionConversationId(requestData)
if (res?.data?.conversationId) {
const conversationId = res.data.conversationId
// 在 navigate 之前设置标记,避免 Chat 组件的 useEffect 重复调用接口
sessionStorage.setItem('toolHistoryLoading', conversationId)
// 更新路由到新的会话ID
navigate(`/chat/${conversationId}`, {
replace: true,
state: {
toolId: null,
skipHistoryLoad: true, // 标记跳过历史记录加载,因为 ChatEditor 会处理
},
})
// 使用获取到的会话ID调用历史会话
......@@ -351,10 +374,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
qaRecords: qaRes?.data || [],
},
}))
// 清除标记,避免影响后续路由切换
sessionStorage.removeItem('toolHistoryLoading')
}
}
catch (error) {
console.error('获取会话ID或历史记录失败:', error)
// 出错时也要清除标记
sessionStorage.removeItem('toolHistoryLoading')
}
}
......@@ -388,11 +415,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const res = await fetchSessionConversationId(requestData)
if (res?.data?.conversationId) {
const conversationId = res.data.conversationId
// 在 navigate 之前设置标记,避免 Chat 组件的 useEffect 重复调用接口
// 使用 sessionStorage 作为标记,因为 location.state 可能有时序问题
sessionStorage.setItem('toolHistoryLoading', conversationId)
// 更新路由到新的会话ID,并携带 toolId 参数
navigate(`/chat/${conversationId}?toolId=${tool.toolId}`, {
replace: true,
state: {
toolId: tool.toolId,
skipHistoryLoad: true, // 标记跳过历史记录加载,因为 ChatEditor 会处理
},
})
// 使用获取到的会话ID调用历史会话
......@@ -408,10 +439,14 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
qaRecords: qaRes?.data || [],
},
}))
// 清除标记,避免影响后续路由切换
sessionStorage.removeItem('toolHistoryLoading')
}
}
catch (error) {
console.error('获取会话ID或历史记录失败:', error)
// 出错时也要清除标记
sessionStorage.removeItem('toolHistoryLoading')
}
}
......
......@@ -539,6 +539,19 @@ export const Chat: React.FC = () => {
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)
if (skipHistoryLoad) {
......@@ -654,9 +667,30 @@ export const Chat: React.FC = () => {
const getToolNameFromToolId = async () => {
if (currentToolId) {
try {
// 等待 token 就绪后再调用接口
await waitForToken()
// 优先从缓存读取工具列表,避免重复调用接口
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 })
if (res?.data) {
const tool = res.data.find((t: any) => t.toolId === currentToolId)
......@@ -745,6 +779,11 @@ export const Chat: React.FC = () => {
setIsLoading(false)
// 标记该会话的历史记录已加载完成(通过工具切换事件加载)
historyLoadedRef.current.conversationId = conversationId
// 清除 toolHistoryLoading 标记,避免影响后续路由切换
const toolHistoryLoadingId = sessionStorage.getItem('toolHistoryLoading')
if (toolHistoryLoadingId === conversationId) {
sessionStorage.removeItem('toolHistoryLoading')
}
}
}
window.addEventListener('toolHistoryLoaded', handleToolHistoryLoaded as EventListener)
......
Markdown is supported
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