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
28c2d926
Commit
28c2d926
authored
Jan 06, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: token校验
parent
c1b6b8a5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
13 additions
and
80 deletions
+13
-80
src/components/ChatEditor/index.tsx
+2
-0
src/pages/Chat/Chat.tsx
+2
-79
src/pages/ChatTactics/TacticsChat.tsx
+2
-1
src/store/conversationSlice.ts
+4
-0
src/store/tacticsSlice.ts
+3
-0
No files found.
src/components/ChatEditor/index.tsx
View file @
28c2d926
...
...
@@ -328,6 +328,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
if
(
res
?.
data
?.
conversationId
)
{
const
conversationId
=
res
.
data
.
conversationId
// 使用获取到的会话ID调用历史会话
await
waitForToken
()
const
qaRes
=
await
fetchUserQaRecordPage
(
conversationId
,
''
)
console
.
log
(
'qaRes chatEditor11111'
,
qaRes
)
// 通过自定义事件将历史记录数据传递给父组件进行渲染
...
...
@@ -375,6 +376,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
if
(
res
?.
data
?.
conversationId
)
{
const
conversationId
=
res
.
data
.
conversationId
// 使用获取到的会话ID调用历史会话
await
waitForToken
()
const
qaRes
=
await
fetchUserQaRecordPage
(
conversationId
,
tool
.
toolId
)
console
.
log
(
'qaRes chatEditor11111'
,
qaRes
)
// 通过自定义事件将历史记录数据传递给父组件进行渲染
...
...
src/pages/Chat/Chat.tsx
View file @
28c2d926
...
...
@@ -15,7 +15,7 @@ import { fetchUserQaRecordPage } from '@/api/conversation'
import
{
fetchCheckTokenApi
,
fetchStreamResponse
}
from
'@/api/chat'
import
{
fetchToolList
}
from
'@/api/home'
import
{
clearCurrentToolId
,
clearShouldSendQuestion
,
fetchConversations
,
setCurrentToolId
}
from
'@/store/conversationSlice'
import
{
getUserRolesForApi
,
safeSessionStorageGetItem
}
from
'@/lib/utils'
import
{
getUserRolesForApi
,
safeSessionStorageGetItem
,
waitForToken
}
from
'@/lib/utils'
import
type
{
RootState
}
from
'@/store'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
ScrollBtoIcon
from
'@/assets/svg/scrollBto.svg?react'
...
...
@@ -314,6 +314,7 @@ export const Chat: React.FC = () => {
console
.
log
(
'[Chat] refreshQuestionsFromCollect 事件已触发'
)
},
100
)
}
await
waitForToken
()
const
res
=
await
fetchUserQaRecordPage
(
conversationId
,
toolId
||
''
)
console
.
log
(
'qaRes chatEditor2222222'
,
res
)
const
qaRecords
=
res
.
data
||
[]
...
...
@@ -424,84 +425,6 @@ 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
)
{
// 检查是否已通过 toolHistoryLoaded 事件加载过相同会话的数据
...
...
src/pages/ChatTactics/TacticsChat.tsx
View file @
28c2d926
...
...
@@ -23,7 +23,7 @@ import ScrollBtoIcon from '@/assets/svg/scrollBto.svg?react'
import
{
setIsAsking
}
from
'@/store/chatSlice'
import
SdreamLoading
from
'@/components/SdreamLoading'
import
useToast
from
'@/hooks/useToast'
import
{
safeLocalStorageGetItem
}
from
'@/lib/utils'
import
{
safeLocalStorageGetItem
,
waitForToken
}
from
'@/lib/utils'
export
const
TacticsChat
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
<
{
id
:
string
}
>
()
...
...
@@ -537,6 +537,7 @@ export const TacticsChat: React.FC = () => {
// 在异步操作开始前保存 createdFromClearRef 的值,避免在异步过程中被其他逻辑修改
const
wasCreatedFromClear
=
createdFromClearRef
.
current
try
{
await
waitForToken
()
const
res
=
await
fetchTacticsQaRecordPage
(
conversationId
)
const
qaRecords
=
res
.
data
||
[]
const
hasHistoryFlag
=
qaRecords
.
length
>
0
...
...
src/store/conversationSlice.ts
View file @
28c2d926
...
...
@@ -3,6 +3,7 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import
{
processConversationData
}
from
'./conversationSlice.helper'
import
type
{
Conversation
,
ConversationState
}
from
'@/types/conversation'
import
{
fetchCreateConversation
,
fetchDeleteUserConversation
,
fetchQueryUserConversationPage
}
from
'@/api/conversation'
import
{
waitForToken
}
from
'@/lib/utils'
const
initialState
:
ConversationState
=
{
conversations
:
[],
...
...
@@ -18,6 +19,7 @@ export const fetchConversations = createAsyncThunk(
'conversation/fetchConversations'
,
async
(
_
,
{
rejectWithValue
})
=>
{
try
{
await
waitForToken
()
// 调用真实接口获取会话列表
const
response
=
await
fetchQueryUserConversationPage
({
pageNum
:
1
,
...
...
@@ -41,6 +43,7 @@ export const deleteConversations = createAsyncThunk<
'conversation/deleteConversations'
,
async
(
conversationIds
,
{
dispatch
,
rejectWithValue
})
=>
{
try
{
await
waitForToken
()
// 调用删除会话的 API,传入 ID 集合
await
fetchDeleteUserConversation
(
conversationIds
)
...
...
@@ -63,6 +66,7 @@ export const createConversation = createAsyncThunk<
>
(
'conversation/createConversation'
,
async
({
conversationData
,
shouldNavigate
,
shouldSendQuestion
},
{
dispatch
})
=>
{
await
waitForToken
()
// 从缓存中获取 toolId 作为 busiId
const
cachedToolId
=
typeof
window
!==
'undefined'
?
sessionStorage
.
getItem
(
'currentToolId'
)
:
null
const
busiId
=
cachedToolId
||
''
...
...
src/store/tacticsSlice.ts
View file @
28c2d926
...
...
@@ -3,6 +3,7 @@ import type { PayloadAction } from '@reduxjs/toolkit'
import
{
createAsyncThunk
,
createSlice
}
from
'@reduxjs/toolkit'
import
type
{
TacticsConversation
,
TacticsConversationState
}
from
'@/types/tactics'
import
{
fetchCreateTacticsConversation
,
fetchDeleteTacticsConversation
}
from
'@/api/tactics'
import
{
waitForToken
}
from
'@/lib/utils'
const
initialState
:
TacticsConversationState
=
{
conversations
:
[],
...
...
@@ -29,6 +30,7 @@ export const deleteTacticsConversations = createAsyncThunk<
'tactics/deleteTacticsConversations'
,
async
(
conversationIds
,
{
dispatch
,
rejectWithValue
})
=>
{
try
{
await
waitForToken
()
await
fetchDeleteTacticsConversation
(
conversationIds
)
await
dispatch
(
fetchTacticsConversations
())
return
true
...
...
@@ -46,6 +48,7 @@ export const createTacticsConversation = createAsyncThunk<
>
(
'tactics/createTacticsConversation'
,
async
({
conversationData
,
shouldNavigate
,
shouldSendQuestion
},
{
dispatch
})
=>
{
await
waitForToken
()
const
response
=
await
fetchCreateTacticsConversation
(
conversationData
)
const
newConversation
=
response
.
data
...
...
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