Commit 984a54ba by Liu

fix:调用顺序

parent e254a080
......@@ -44,9 +44,89 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const toolIdFromUrl = searchParams.get('toolId')
const fromCollect = location.state?.fromCollect
/** 等待 token 就绪,确保登录接口返回后才继续 */
const waitForToken = async (maxWaitTime = 3000): Promise<boolean> => {
const startTime = Date.now()
let initialToken = ''
// 先获取初始 token 值
try {
const initialTokenStr = window.localStorage.getItem('__TOKEN__') || '""'
initialToken = JSON.parse(initialTokenStr) || ''
}
catch {
initialToken = ''
}
// 如果初始没有 token,等待 token 出现(从无到有,说明登录完成)
if (!initialToken) {
while (Date.now() - startTime < maxWaitTime) {
const tokenStr = window.localStorage.getItem('__TOKEN__') || '""'
let token = ''
try {
token = JSON.parse(tokenStr) || ''
}
catch {
token = ''
}
if (token) {
// token 从无到有,说明登录完成,再等待一小段时间确保写入完成
await new Promise(resolve => setTimeout(resolve, 200))
return true
}
// 等待 100ms 后再次检查
await new Promise(resolve => setTimeout(resolve, 100))
}
return false
}
// 如果初始有 token,可能是旧 token 或新 token
// 等待一小段时间,确保登录流程有足够时间完成(登录接口可能会更新 token)
// 同时监听 token 变化
let tokenChanged = false
const checkTokenChange = () => {
try {
const currentTokenStr = window.localStorage.getItem('__TOKEN__') || '""'
const currentToken = JSON.parse(currentTokenStr) || ''
if (currentToken && currentToken !== initialToken) {
tokenChanged = true
}
}
catch {
// 忽略解析错误
}
}
// 监听 storage 事件(跨标签页)
window.addEventListener('storage', checkTokenChange)
// 轮询检查(同标签页)
const interval = setInterval(checkTokenChange, 100)
// 等待最多 1 秒,检测 token 是否变化
const waitForChange = new Promise<void>((resolve) => {
setTimeout(() => {
window.removeEventListener('storage', checkTokenChange)
clearInterval(interval)
resolve()
}, 1000)
})
await waitForChange
// 如果 token 变化了,说明登录完成,再等待一小段时间确保写入完成
if (tokenChanged) {
await new Promise(resolve => setTimeout(resolve, 200))
return true
}
// 如果 token 没有变化,可能是已经登录完成,但为了确保登录流程完成,再等待一小段时间
await new Promise(resolve => setTimeout(resolve, 300))
return true
}
// 获取工具列表
const getToolList = async () => {
try {
// 等待 token 就绪后再调用接口
await waitForToken()
// 从路由中获取 userRoles 参数
const userRoles = getUserRolesForApi()
// 调用真实 API 获取工具列表
......@@ -239,6 +319,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 先调用 fetchSessionConversationId 获取会话ID
try {
// 等待 token 就绪后再调用接口
await waitForToken()
const requestData = {
busiId: '',
}
......@@ -284,6 +366,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 先调用 fetchSessionConversationId 获取会话ID
try {
// 等待 token 就绪后再调用接口
await waitForToken()
const requestData = {
busiId: tool.toolId,
}
......
......@@ -401,6 +401,84 @@ export const Chat: React.FC = () => {
scrollableRef.current.scrollTo(scrollableRef.current.scrollHeight, { behavior: 'smooth' })
}
/** 等待 token 就绪,确保登录接口返回后才继续 */
const waitForToken = async (maxWaitTime = 3000): Promise<boolean> => {
const startTime = Date.now()
let initialToken = ''
// 先获取初始 token 值
try {
const initialTokenStr = window.localStorage.getItem('__TOKEN__') || '""'
initialToken = JSON.parse(initialTokenStr) || ''
}
catch {
initialToken = ''
}
// 如果初始没有 token,等待 token 出现(从无到有,说明登录完成)
if (!initialToken) {
while (Date.now() - startTime < maxWaitTime) {
const tokenStr = window.localStorage.getItem('__TOKEN__') || '""'
let token = ''
try {
token = JSON.parse(tokenStr) || ''
}
catch {
token = ''
}
if (token) {
// token 从无到有,说明登录完成,再等待一小段时间确保写入完成
await new Promise(resolve => setTimeout(resolve, 200))
return true
}
// 等待 100ms 后再次检查
await new Promise(resolve => setTimeout(resolve, 100))
}
return false
}
// 如果初始有 token,可能是旧 token 或新 token
// 等待一小段时间,确保登录流程有足够时间完成(登录接口可能会更新 token)
// 同时监听 token 变化
let tokenChanged = false
const checkTokenChange = () => {
try {
const currentTokenStr = window.localStorage.getItem('__TOKEN__') || '""'
const currentToken = JSON.parse(currentTokenStr) || ''
if (currentToken && currentToken !== initialToken) {
tokenChanged = true
}
}
catch {
// 忽略解析错误
}
}
// 监听 storage 事件(跨标签页)
window.addEventListener('storage', checkTokenChange)
// 轮询检查(同标签页)
const interval = setInterval(checkTokenChange, 100)
// 等待最多 1 秒,检测 token 是否变化
const waitForChange = new Promise<void>((resolve) => {
setTimeout(() => {
window.removeEventListener('storage', checkTokenChange)
clearInterval(interval)
resolve()
}, 1000)
})
await waitForChange
// 如果 token 变化了,说明登录完成,再等待一小段时间确保写入完成
if (tokenChanged) {
await new Promise(resolve => setTimeout(resolve, 200))
return true
}
// 如果 token 没有变化,可能是已经登录完成,但为了确保登录流程完成,再等待一小段时间
await new Promise(resolve => setTimeout(resolve, 300))
return true
}
useEffect(() => {
if (id) {
// 停止之前的请求
......@@ -411,7 +489,11 @@ export const Chat: React.FC = () => {
currentIdRef.current = id
lastSentQuestionRef.current = '' // 重置标记
// 等待 token 就绪后再调用接口
waitForToken().then(() => {
getUserQaRecordPage(id)
})
}
}, [id])
......@@ -438,9 +520,8 @@ export const Chat: React.FC = () => {
const getToolNameFromToolId = async () => {
if (currentToolId) {
try {
// 使用mock数据(已注释)
// const res = await mockFetchToolList()
// 真实API调用
// 等待 token 就绪后再调用接口
await waitForToken()
const userRoles = getUserRolesForApi()
const res = await fetchToolList({ userRoles })
if (res?.data) {
......
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