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
f5f96faf
Commit
f5f96faf
authored
Jan 06, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:处理token返回后再调用业务接口
parent
e0072bcc
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
5 deletions
+104
-5
src/lib/utils.ts
+82
-0
src/pages/ChatTactics/TacticsHome.tsx
+6
-2
src/pages/Home/HomeNew.tsx
+3
-1
src/utils/request.ts
+13
-2
No files found.
src/lib/utils.ts
View file @
f5f96faf
...
@@ -285,3 +285,85 @@ export function getUserRolesForApi(): string[] {
...
@@ -285,3 +285,85 @@ export function getUserRolesForApi(): string[] {
// 直接从路由中获取 userRoles(路由参数是唯一真实来源)
// 直接从路由中获取 userRoles(路由参数是唯一真实来源)
return
getUserRolesFromRoute
()
return
getUserRolesFromRoute
()
}
}
/**
* 等待 token 就绪,确保登录接口返回后才继续
* @param maxWaitTime 最大等待时间(毫秒),默认 3000ms
* @returns Promise<boolean> 返回 true 表示 token 已就绪,false 表示超时
*/
export
async
function
waitForToken
(
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
}
src/pages/ChatTactics/TacticsHome.tsx
View file @
f5f96faf
...
@@ -8,7 +8,7 @@ import { TacticsWelcome } from './components/TacticsWelcome'
...
@@ -8,7 +8,7 @@ import { TacticsWelcome } from './components/TacticsWelcome'
import
{
clearTacticsNavigationFlag
,
createTacticsConversation
,
fetchTacticsConversations
}
from
'@/store/tacticsSlice'
import
{
clearTacticsNavigationFlag
,
createTacticsConversation
,
fetchTacticsConversations
}
from
'@/store/tacticsSlice'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
type
{
RootState
}
from
'@/store'
import
type
{
RootState
}
from
'@/store'
import
{
getUserRolesFromRoute
,
safeLocalStorageGetItem
}
from
'@/lib/utils'
import
{
getUserRolesFromRoute
,
safeLocalStorageGetItem
,
waitForToken
}
from
'@/lib/utils'
import
{
TacticsChatEditor
}
from
'@/components/TacticsChatEditor'
import
{
TacticsChatEditor
}
from
'@/components/TacticsChatEditor'
export
const
TacticsHome
:
React
.
FC
=
()
=>
{
export
const
TacticsHome
:
React
.
FC
=
()
=>
{
...
@@ -111,10 +111,12 @@ export const TacticsHome: React.FC = () => {
...
@@ -111,10 +111,12 @@ export const TacticsHome: React.FC = () => {
return
{}
as
Partial
<
any
>
return
{}
as
Partial
<
any
>
},
[
orderMeta
,
tacticsMeta
,
userMeta
])
},
[
orderMeta
,
tacticsMeta
,
userMeta
])
const
initTacticsConversation
=
()
=>
{
const
initTacticsConversation
=
async
()
=>
{
const
fromCollect
=
location
.
state
?.
fromCollect
const
fromCollect
=
location
.
state
?.
fromCollect
// 只有在访问问答首页时才创建新对话
// 只有在访问问答首页时才创建新对话
if
(
!
fromCollect
&&
location
.
pathname
===
'/tactics'
)
{
if
(
!
fromCollect
&&
location
.
pathname
===
'/tactics'
)
{
// 等待 token 就绪后再调用接口
await
waitForToken
()
dispatch
(
dispatch
(
createTacticsConversation
({
createTacticsConversation
({
conversationData
:
getConversationExtra
(),
conversationData
:
getConversationExtra
(),
...
@@ -216,6 +218,7 @@ export const TacticsHome: React.FC = () => {
...
@@ -216,6 +218,7 @@ export const TacticsHome: React.FC = () => {
// 确保 token 存在后再执行业务逻辑
// 确保 token 存在后再执行业务逻辑
if
(
actualToken
)
{
if
(
actualToken
)
{
hasInitialized
.
current
=
true
hasInitialized
.
current
=
true
// initTacticsConversation 内部已有 waitForToken 等待,这里直接调用
initTacticsConversation
()
initTacticsConversation
()
dispatch
(
fetchTacticsConversations
())
dispatch
(
fetchTacticsConversations
())
}
}
...
@@ -242,6 +245,7 @@ export const TacticsHome: React.FC = () => {
...
@@ -242,6 +245,7 @@ export const TacticsHome: React.FC = () => {
if
(
actualToken
)
{
if
(
actualToken
)
{
hasInitialized
.
current
=
true
hasInitialized
.
current
=
true
// initTacticsConversation 内部已有 waitForToken 等待,这里直接调用
initTacticsConversation
()
initTacticsConversation
()
dispatch
(
fetchTacticsConversations
())
dispatch
(
fetchTacticsConversations
())
}
}
...
...
src/pages/Home/HomeNew.tsx
View file @
f5f96faf
...
@@ -14,7 +14,7 @@ import SdreamLoading from '@/components/SdreamLoading'
...
@@ -14,7 +14,7 @@ import SdreamLoading from '@/components/SdreamLoading'
import
{
fetchLoginByToken
,
fetchLoginByUid
}
from
'@/api/common'
import
{
fetchLoginByToken
,
fetchLoginByUid
}
from
'@/api/common'
import
{
fetchSessionConversationId
}
from
'@/api/conversation'
import
{
fetchSessionConversationId
}
from
'@/api/conversation'
import
{
fetchCheckTokenApi
}
from
'@/api/chat'
import
{
fetchCheckTokenApi
}
from
'@/api/chat'
import
{
getUserRolesFromRoute
,
safeLocalStorageGetItem
,
safeSessionStorageGetItem
,
safeSessionStorageRemoveItem
,
safeSessionStorageSetItem
}
from
'@/lib/utils'
import
{
getUserRolesFromRoute
,
safeLocalStorageGetItem
,
safeSessionStorageGetItem
,
safeSessionStorageRemoveItem
,
safeSessionStorageSetItem
,
waitForToken
}
from
'@/lib/utils'
// 从 localStorage 获取 token 的辅助函数
// 从 localStorage 获取 token 的辅助函数
function
getTokenFromStorage
():
string
|
null
{
function
getTokenFromStorage
():
string
|
null
{
...
@@ -88,6 +88,8 @@ export const Home: React.FC = () => {
...
@@ -88,6 +88,8 @@ export const Home: React.FC = () => {
// 获取会话ID并加载历史记录
// 获取会话ID并加载历史记录
const
getSessionConversationId
=
async
(
data
?:
any
)
=>
{
const
getSessionConversationId
=
async
(
data
?:
any
)
=>
{
try
{
try
{
// 等待 token 就绪后再调用接口
await
waitForToken
()
// 从 sessionStorage 获取 toolId 作为 busiId
// 从 sessionStorage 获取 toolId 作为 busiId
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
requestData
=
{
const
requestData
=
{
...
...
src/utils/request.ts
View file @
f5f96faf
...
@@ -29,9 +29,20 @@ const service = axios.create({
...
@@ -29,9 +29,20 @@ const service = axios.create({
service
.
interceptors
.
request
.
use
(
service
.
interceptors
.
request
.
use
(
(
config
:
any
)
=>
{
(
config
:
any
)
=>
{
const
token
=
window
.
localStorage
.
getItem
(
'__TOKEN__'
)
||
'""'
let
token
=
''
try
{
const
tokenStr
=
window
.
localStorage
.
getItem
(
'__TOKEN__'
)
if
(
tokenStr
)
{
// useLocalStorageState 会将值序列化为 JSON,需要解析
token
=
JSON
.
parse
(
tokenStr
)
||
''
}
}
catch
{
// 如果解析失败,使用空字符串
token
=
''
}
config
.
headers
=
{
config
.
headers
=
{
'X-Token'
:
JSON
.
parse
(
token
)
,
'X-Token'
:
token
,
'X-Request-Id'
:
`
${
Date
.
now
()}${
Math
.
random
().
toString
(
36
).
substring
(
2
)}
`
,
'X-Request-Id'
:
`
${
Date
.
now
()}${
Math
.
random
().
toString
(
36
).
substring
(
2
)}
`
,
'X-Request-By'
:
config
.
url
,
'X-Request-By'
:
config
.
url
,
}
}
...
...
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