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
57f63bd8
Commit
57f63bd8
authored
Apr 13, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:默认工具展示
parent
e019d3ac
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
201 additions
and
35 deletions
+201
-35
src/api/conversation.ts
+5
-4
src/api/home.ts
+39
-1
src/components/ChatEditor/index.tsx
+35
-3
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
+14
-0
src/lib/utils.ts
+8
-1
src/pages/Chat/Chat.tsx
+73
-13
src/pages/Chat/components/ChatItem/ChatAnswerRecommend.tsx
+11
-2
src/pages/Home/HomeNew.tsx
+16
-11
No files found.
src/api/conversation.ts
View file @
57f63bd8
...
@@ -40,12 +40,13 @@ export function fetchDeleteUserConversation(conversationIdList: string[]) {
...
@@ -40,12 +40,13 @@ export function fetchDeleteUserConversation(conversationIdList: string[]) {
* @params
* @params
*/
*/
export
function
fetchSessionConversationId
<
T
>
(
data
:
T
)
{
export
function
fetchSessionConversationId
<
T
>
(
data
:
T
)
{
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
payload
=
(
data
||
{})
as
Record
<
string
,
any
>
const
sessionToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
requestData
=
{
const
requestData
=
{
...
(
data
as
Record
<
string
,
any
>
)
,
...
payload
,
busiType
:
'01'
,
busiType
:
'01'
,
busiId
:
(
data
as
Record
<
string
,
any
>
)
?.
busiId
||
''
,
busiId
:
sessionToolId
||
payload
?.
busiId
||
''
,
toolId
,
toolId
:
sessionToolId
||
payload
?.
toolId
||
''
,
}
}
return
http
.
post
(
'/conversation/api/conversation/mobile/v1/get_user_conversation_session'
,
requestData
)
return
http
.
post
(
'/conversation/api/conversation/mobile/v1/get_user_conversation_session'
,
requestData
)
}
}
src/api/home.ts
View file @
57f63bd8
import
http
from
'@/utils/request'
import
http
from
'@/utils/request'
const
TOOL_LIST_CACHE_TTL
=
5
*
60
*
1000
const
toolListCache
=
new
Map
<
string
,
{
timestamp
:
number
,
response
:
any
}
>
()
const
toolListPending
=
new
Map
<
string
,
Promise
<
any
>>
()
function
getToolListCacheKey
(
params
?:
{
userRoles
?:
string
[]
})
{
return
JSON
.
stringify
({
toolType
:
'03'
,
userRoles
:
params
?.
userRoles
||
[],
})
}
/**
/**
* 查询推荐问题列表
* 查询推荐问题列表
* @params
* @params
...
@@ -13,13 +24,40 @@ export function fetchQuestionList(data: any) {
...
@@ -13,13 +24,40 @@ export function fetchQuestionList(data: any) {
* @params params.userRoles: 角色数组,用于按角色返回工具
* @params params.userRoles: 角色数组,用于按角色返回工具
*/
*/
export
function
fetchToolList
(
params
?:
{
userRoles
?:
string
[]
})
{
export
function
fetchToolList
(
params
?:
{
userRoles
?:
string
[]
})
{
const
cacheKey
=
getToolListCacheKey
(
params
)
const
now
=
Date
.
now
()
const
cached
=
toolListCache
.
get
(
cacheKey
)
if
(
cached
&&
now
-
cached
.
timestamp
<
TOOL_LIST_CACHE_TTL
)
{
return
Promise
.
resolve
(
cached
.
response
)
}
const
pending
=
toolListPending
.
get
(
cacheKey
)
if
(
pending
)
{
return
pending
}
const
requestBody
:
Record
<
string
,
string
|
string
[]
>
=
{
const
requestBody
:
Record
<
string
,
string
|
string
[]
>
=
{
toolType
:
'03'
,
toolType
:
'03'
,
userRoles
:
[],
userRoles
:
[],
}
}
if
(
params
?.
userRoles
)
if
(
params
?.
userRoles
)
requestBody
.
userRoles
=
params
.
userRoles
requestBody
.
userRoles
=
params
.
userRoles
return
http
.
post
(
'/config-center/api/tool/mobile/v1/get_tool_list'
,
requestBody
)
const
request
=
http
.
post
(
'/config-center/api/tool/mobile/v1/get_tool_list'
,
requestBody
)
.
then
((
res
)
=>
{
toolListCache
.
set
(
cacheKey
,
{
timestamp
:
Date
.
now
(),
response
:
res
,
})
toolListPending
.
delete
(
cacheKey
)
return
res
})
.
catch
((
error
)
=>
{
toolListPending
.
delete
(
cacheKey
)
throw
error
})
toolListPending
.
set
(
cacheKey
,
request
)
return
request
}
}
/**
/**
...
...
src/components/ChatEditor/index.tsx
View file @
57f63bd8
...
@@ -127,13 +127,23 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -127,13 +127,23 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 获取工具列表
// 获取工具列表
const
getToolList
=
async
()
=>
{
const
getToolList
=
async
()
=>
{
try
{
try
{
console
.
log
(
'[get_tool_list][ChatEditor] start'
,
{
pathname
:
location
.
pathname
,
search
:
location
.
search
,
hideTools
,
})
// 等待 token 就绪后再调用接口
// 等待 token 就绪后再调用接口
await
waitForToken
()
await
waitForToken
()
// 从路由中获取 userRoles 参数
// 从路由中获取 userRoles 参数
const
userRoles
=
getUserRolesForApi
()
const
userRoles
=
getUserRolesForApi
()
console
.
log
(
'[get_tool_list][ChatEditor] request'
,
{
userRoles
})
// 调用真实 API 获取工具列表
// 调用真实 API 获取工具列表
const
res
=
await
fetchToolList
({
userRoles
})
const
res
=
await
fetchToolList
({
userRoles
})
console
.
log
(
'[get_tool_list][ChatEditor] response'
,
{
success
:
Boolean
(
res
),
length
:
Array
.
isArray
(
res
?.
data
)
?
res
.
data
.
length
:
-
1
,
})
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
)
// 存入第0个工具信息到缓存
// 存入第0个工具信息到缓存
...
@@ -149,9 +159,11 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -149,9 +159,11 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 根据 currentToolId 以及 sessionStorage 中的记录决定高亮逻辑
// 根据 currentToolId 以及 sessionStorage 中的记录决定高亮逻辑
useEffect
(()
=>
{
useEffect
(()
=>
{
console
.
log
(
'[chat-toolid-log] ChatEditor currentToolId:'
,
currentToolId
,
'| sessionToolId:'
,
sessionToolId
,
'| fromCollect:'
,
fromCollect
)
if
(
currentToolId
&&
!
sessionToolId
&&
!
fromCollect
)
{
if
(
currentToolId
&&
!
sessionToolId
&&
!
fromCollect
)
{
// 清除过期的 Redux 值
// 清除过期的 Redux 值
dispatch
(
clearCurrentToolId
())
dispatch
(
clearCurrentToolId
())
console
.
log
(
'[chat-toolid-log] ChatEditor 清除 Redux - 逻辑三 - line:155'
)
// 如果 URL 中还有 toolId,也清除它
// 如果 URL 中还有 toolId,也清除它
if
(
toolIdFromUrl
)
{
if
(
toolIdFromUrl
)
{
const
newSearchParams
=
new
URLSearchParams
(
searchParams
)
const
newSearchParams
=
new
URLSearchParams
(
searchParams
)
...
@@ -165,6 +177,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -165,6 +177,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
defaultTool
=
toolList
[
0
]
const
defaultTool
=
toolList
[
0
]
safeSessionStorageSetItem
(
'currentToolId'
,
defaultTool
.
toolId
)
safeSessionStorageSetItem
(
'currentToolId'
,
defaultTool
.
toolId
)
safeSessionStorageSetItem
(
'currentToolName'
,
defaultTool
.
toolName
)
safeSessionStorageSetItem
(
'currentToolName'
,
defaultTool
.
toolName
)
console
.
log
(
'[chat-toolid-log] ChatEditor 逻辑三 setItem:'
,
defaultTool
.
toolId
,
'| line:169'
)
}
}
return
return
}
}
...
@@ -238,6 +251,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -238,6 +251,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
storedToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
const
storedToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
// 如果 currentToolId 是空字符串,视为 null,确保制度活化能正确高亮
// 如果 currentToolId 是空字符串,视为 null,确保制度活化能正确高亮
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
console
.
log
(
'[chat-toolid-log] ChatEditor syncSessionToolId:'
,
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
,
'| line:242'
)
}
}
syncSessionToolId
()
syncSessionToolId
()
window
.
addEventListener
(
'storage'
,
syncSessionToolId
)
window
.
addEventListener
(
'storage'
,
syncSessionToolId
)
...
@@ -267,6 +281,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -267,6 +281,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
storedToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
const
storedToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
// 如果 currentToolId 是空字符串,视为 null,确保制度活化能正确高亮
// 如果 currentToolId 是空字符串,视为 null,确保制度活化能正确高亮
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
console
.
log
(
'[chat-toolid-log] ChatEditor location useEffect:'
,
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
,
'| line:272'
)
// 当路由切换(如点击历史记录)时,同步最新的 sessionStorage,避免同标签页删除后状态不同步
// 当路由切换(如点击历史记录)时,同步最新的 sessionStorage,避免同标签页删除后状态不同步
},
[
toolIdFromUrl
,
location
.
pathname
])
},
[
toolIdFromUrl
,
location
.
pathname
])
...
@@ -355,9 +370,10 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -355,9 +370,10 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
safeSessionStorageRemoveItem
(
'showToolQuestion'
)
safeSessionStorageRemoveItem
(
'showToolQuestion'
)
// 存入默认高亮按钮信息到缓存
// 存入默认高亮按钮信息到缓存
if
(
toolList
.
length
>
0
)
{
if
(
toolList
.
length
>
0
)
{
safeSessionStorage
SetItem
(
'currentToolId'
,
defaultTool
.
toolId
)
safeSessionStorage
RemoveItem
(
'currentToolId'
)
safeSessionStorageSetItem
(
'currentToolName'
,
defaultTool
.
toolName
)
safeSessionStorageSetItem
(
'currentToolName'
,
defaultTool
.
toolName
)
setSessionToolId
(
defaultTool
.
toolId
)
setSessionToolId
(
null
)
console
.
log
(
'[chat-toolid-log] ChatEditor defaultTool clearSessionToolId'
,
'| line:364'
)
}
}
setShowToolQuestion
(
false
)
setShowToolQuestion
(
false
)
// 先通知上层更新欢迎语(即便后续接口异常也能生效)
// 先通知上层更新欢迎语(即便后续接口异常也能生效)
...
@@ -440,6 +456,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -440,6 +456,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
safeSessionStorageSetItem
(
'currentToolId'
,
tool
.
toolId
)
safeSessionStorageSetItem
(
'currentToolId'
,
tool
.
toolId
)
safeSessionStorageSetItem
(
'currentToolName'
,
tool
.
toolName
)
safeSessionStorageSetItem
(
'currentToolName'
,
tool
.
toolName
)
setSessionToolId
(
tool
.
toolId
)
setSessionToolId
(
tool
.
toolId
)
console
.
log
(
'[chat-toolid-log] ChatEditor tool click setSessionToolId:'
,
tool
.
toolId
,
'| line:447'
)
// 先调用 fetchSessionConversationId 获取会话ID
// 先调用 fetchSessionConversationId 获取会话ID
// 等待 token 就绪后再调用接口
// 等待 token 就绪后再调用接口
...
@@ -530,6 +547,11 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -530,6 +547,11 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 组件加载时和路由参数变化时获取工具列表
// 组件加载时和路由参数变化时获取工具列表
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
hideTools
)
{
if
(
!
hideTools
)
{
console
.
log
(
'[get_tool_list][ChatEditor] useEffect trigger'
,
{
pathname
:
location
.
pathname
,
search
:
location
.
search
,
hideTools
,
})
getToolList
()
getToolList
()
}
}
},
[
location
.
pathname
,
location
.
search
,
hideTools
])
},
[
location
.
pathname
,
location
.
search
,
hideTools
])
...
@@ -651,7 +673,17 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -651,7 +673,17 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
selectedColor
=
isSelected
?
'primary'
:
'default'
const
selectedColor
=
isSelected
?
'primary'
:
'default'
const
handleButtonPress
=
async
()
=>
{
const
handleButtonPress
=
async
()
=>
{
// 高亮状态直接返回,避免重复触发
// 点击即同步缓存,制度活化清空 toolId,工具模式写入当前 toolId
if
(
index
===
0
)
{
safeSessionStorageRemoveItem
(
'currentToolId'
)
setSessionToolId
(
null
)
}
else
{
safeSessionStorageSetItem
(
'currentToolId'
,
toolIdStr
)
setSessionToolId
(
toolIdStr
)
}
safeSessionStorageSetItem
(
'currentToolName'
,
tool
.
toolName
||
''
)
// 高亮状态直接返回,避免重复触发后续逻辑
if
(
isSelected
)
if
(
isSelected
)
return
return
if
(
index
===
0
)
if
(
index
===
0
)
...
...
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
View file @
57f63bd8
...
@@ -33,16 +33,26 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
...
@@ -33,16 +33,26 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
})
})
if
(
conversation
.
toolId
)
{
if
(
conversation
.
toolId
)
{
sessionStorage
.
setItem
(
'currentToolId'
,
conversation
.
toolId
)
sessionStorage
.
setItem
(
'currentToolId'
,
conversation
.
toolId
)
console
.
log
(
'[chat-toolid-log] HistoryBarList setItem:'
,
conversation
.
toolId
,
'| line:35'
)
dispatch
(
setCurrentToolId
(
conversation
.
toolId
))
dispatch
(
setCurrentToolId
(
conversation
.
toolId
))
}
}
else
{
else
{
sessionStorage
.
removeItem
(
'currentToolId'
)
sessionStorage
.
removeItem
(
'currentToolId'
)
console
.
log
(
'[chat-toolid-log] HistoryBarList removeItem'
,
'| line:39'
)
dispatch
(
clearCurrentToolId
())
dispatch
(
clearCurrentToolId
())
}
}
// 仅当历史记录为“提质增效”时,进入对话页后自动触发一次提问接口
// 仅当历史记录为“提质增效”时,进入对话页后自动触发一次提问接口
// 用空格字符串触发 shouldSendQuestion 的监听,但不会在 UI 中新增用户问题气泡(question.trim() 为 false)。
// 用空格字符串触发 shouldSendQuestion 的监听,但不会在 UI 中新增用户问题气泡(question.trim() 为 false)。
const
isQualityImprovement
=
conversation
.
toolId
===
'6712395743241'
const
isQualityImprovement
=
conversation
.
toolId
===
'6712395743241'
const
isBusinessInsight
=
conversation
.
toolId
===
'6712395743242'
console
.
log
(
'工具ID:'
,
{
conversationId
:
conversation
.
conversationId
,
toolId
:
conversation
.
toolId
,
isQualityImprovement
,
isBusinessInsight
,
willAutoSubmitByShouldSendQuestion
:
isQualityImprovement
,
})
if
(
isQualityImprovement
)
{
if
(
isQualityImprovement
)
{
const
autoShouldSendQuestion
=
' '
const
autoShouldSendQuestion
=
' '
dispatch
(
setShouldSendQuestion
(
autoShouldSendQuestion
))
dispatch
(
setShouldSendQuestion
(
autoShouldSendQuestion
))
...
@@ -54,6 +64,10 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
...
@@ -54,6 +64,10 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
}
}
else
{
else
{
// 避免上一次残留的 shouldSendQuestion 误触发自动提问
// 避免上一次残留的 shouldSendQuestion 误触发自动提问
console
.
log
(
'工具ID:2'
,
{
conversationId
:
conversation
.
conversationId
,
toolId
:
conversation
.
toolId
,
})
dispatch
(
clearShouldSendQuestion
())
dispatch
(
clearShouldSendQuestion
())
}
}
// 直接导航到历史记录,不设置shouldSendQuestion
// 直接导航到历史记录,不设置shouldSendQuestion
...
...
src/lib/utils.ts
View file @
57f63bd8
...
@@ -13,7 +13,11 @@ export function cn(...inputs: ClassValue[]) {
...
@@ -13,7 +13,11 @@ export function cn(...inputs: ClassValue[]) {
*/
*/
export
function
safeSessionStorageGetItem
(
key
:
string
):
string
|
null
{
export
function
safeSessionStorageGetItem
(
key
:
string
):
string
|
null
{
try
{
try
{
return
sessionStorage
.
getItem
(
key
)
const
result
=
sessionStorage
.
getItem
(
key
)
if
(
key
===
'currentToolId'
)
{
console
.
log
(
'[chat-toolid-log] safeGetItem:'
,
result
,
'| caller line'
)
}
return
result
}
}
catch
{
catch
{
// 在无痕模式或存储被禁用时,静默失败
// 在无痕模式或存储被禁用时,静默失败
...
@@ -27,6 +31,9 @@ export function safeSessionStorageGetItem(key: string): string | null {
...
@@ -27,6 +31,9 @@ export function safeSessionStorageGetItem(key: string): string | null {
*/
*/
export
function
safeSessionStorageSetItem
(
key
:
string
,
value
:
string
):
void
{
export
function
safeSessionStorageSetItem
(
key
:
string
,
value
:
string
):
void
{
try
{
try
{
if
(
key
===
'currentToolId'
)
{
console
.
log
(
'[chat-toolid-log] safeSetItem:'
,
value
,
'| caller line'
)
}
sessionStorage
.
setItem
(
key
,
value
)
sessionStorage
.
setItem
(
key
,
value
)
}
}
catch
{
catch
{
...
...
src/pages/Chat/Chat.tsx
View file @
57f63bd8
...
@@ -77,13 +77,13 @@ export const Chat: React.FC = () => {
...
@@ -77,13 +77,13 @@ export const Chat: React.FC = () => {
const
hasAutoWelcomeCandidateRef
=
useRef
<
boolean
>
(
false
)
const
hasAutoWelcomeCandidateRef
=
useRef
<
boolean
>
(
false
)
// 当外部系统直接以 /chat/:id 链接进入(没有 location.state,且 URL 中也没有 toolId)时,
// 当外部系统直接以 /chat/:id 链接进入(没有 location.state,且 URL 中也没有 toolId)时,
//
视为一次新的会话入口:重置为制度活化,清除历史遗留的工具模式
状态
//
首次进入不清除 sessionStorage 中的 toolId,保留首页点击工具后的
状态
useEffect
(()
=>
{
//
useEffect(() => {
if
(
!
location
.
state
&&
!
rawToolIdFromUrl
)
{
//
if (!location.state && !rawToolIdFromUrl) {
dispatch
(
clearCurrentToolId
())
//
dispatch(clearCurrentToolId())
// sessionStorage.removeItem('currentToolId')
//
// sessionStorage.removeItem('currentToolId')
}
//
}
},
[
location
.
state
,
rawToolIdFromUrl
,
dispatch
])
//
}, [location.state, rawToolIdFromUrl, dispatch])
// 若链接中带有 toolId,进入页面后强制清空(避免沿用历史链接参数)
// 若链接中带有 toolId,进入页面后强制清空(避免沿用历史链接参数)
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
shouldForceClearUrlToolId
)
if
(
!
shouldForceClearUrlToolId
)
...
@@ -149,15 +149,18 @@ export const Chat: React.FC = () => {
...
@@ -149,15 +149,18 @@ export const Chat: React.FC = () => {
useEffect
(()
=>
{
useEffect
(()
=>
{
// 保存从 location.state 传递的 toolId 到 ref
// 保存从 location.state 传递的 toolId 到 ref
toolIdFromStateRef
.
current
=
initialToolId
toolIdFromStateRef
.
current
=
initialToolId
console
.
log
(
'[chat-toolid-log] Chat initialToolId:'
,
initialToolId
,
'| sessionStorage:'
,
sessionStorage
.
getItem
(
'currentToolId'
))
if
(
typeof
initialToolId
===
'undefined'
)
if
(
typeof
initialToolId
===
'undefined'
)
return
return
if
(
initialToolId
)
{
if
(
initialToolId
)
{
// 统一转换为字符串,确保类型一致(真实API可能返回数字,需要转换为字符串)
// 统一转换为字符串,确保类型一致(真实API可能返回数字,需要转换为字符串)
const
normalizedToolId
=
String
(
initialToolId
)
const
normalizedToolId
=
String
(
initialToolId
)
dispatch
(
setCurrentToolId
(
normalizedToolId
))
dispatch
(
setCurrentToolId
(
normalizedToolId
))
console
.
log
(
'[chat-toolid-log] Chat setCurrentToolId:'
,
normalizedToolId
)
}
}
else
{
else
{
dispatch
(
clearCurrentToolId
())
dispatch
(
clearCurrentToolId
())
console
.
log
(
'[chat-toolid-log] Chat clearCurrentToolId'
)
}
}
},
[
dispatch
,
initialToolId
])
},
[
dispatch
,
initialToolId
])
...
@@ -305,6 +308,19 @@ export const Chat: React.FC = () => {
...
@@ -305,6 +308,19 @@ export const Chat: React.FC = () => {
// 判断是否为提质增效模式的自动调用(空问题)
// 判断是否为提质增效模式的自动调用(空问题)
const
isEmptyQuestion
=
!
question
.
trim
()
const
isEmptyQuestion
=
!
question
.
trim
()
const
isQualityImprovement
=
resolvedToolId
===
'6712395743241'
const
isQualityImprovement
=
resolvedToolId
===
'6712395743241'
const
isBusinessInsight
=
resolvedToolId
===
'6712395743242'
console
.
log
(
'工具id3'
,
{
question
,
questionLength
:
question
.
length
,
isEmptyQuestion
,
toolIdFromArg
:
toolId
,
sessionToolId
,
reduxCurrentToolId
:
currentToolId
,
resolvedToolId
,
isQualityImprovement
,
isBusinessInsight
,
extraParams
,
})
isAutoSubmitQualityImprovementRef
.
current
=
isEmptyQuestion
&&
isQualityImprovement
isAutoSubmitQualityImprovementRef
.
current
=
isEmptyQuestion
&&
isQualityImprovement
if
(
isAutoSubmitQualityImprovementRef
.
current
)
{
if
(
isAutoSubmitQualityImprovementRef
.
current
)
{
// 重置欢迎语候选
// 重置欢迎语候选
...
@@ -320,7 +336,9 @@ export const Chat: React.FC = () => {
...
@@ -320,7 +336,9 @@ export const Chat: React.FC = () => {
dispatch
(
setIsAsking
(
true
))
dispatch
(
setIsAsking
(
true
))
// 检查token
// 检查token
console
.
log
(
'[Chat] before fetchCheckTokenApi'
)
await
fetchCheckTokenApi
()
await
fetchCheckTokenApi
()
console
.
log
(
'[Chat] after fetchCheckTokenApi'
)
// 如果 question 不为空,才添加用户问题和空的AI回答(自动提问时 question 为空,不显示)
// 如果 question 不为空,才添加用户问题和空的AI回答(自动提问时 question 为空,不显示)
if
(
question
.
trim
())
{
if
(
question
.
trim
())
{
...
@@ -671,14 +689,11 @@ export const Chat: React.FC = () => {
...
@@ -671,14 +689,11 @@ export const Chat: React.FC = () => {
}
}
// 无条件同步到 sessionStorage,确保 ChatEditor 和 handleSubmitQuestion 能获取到正确的 toolId
// 无条件同步到 sessionStorage,确保 ChatEditor 和 handleSubmitQuestion 能获取到正确的 toolId
sessionStorage
.
setItem
(
'currentToolId'
,
toolIdFromState
)
sessionStorage
.
setItem
(
'currentToolId'
,
toolIdFromState
)
console
.
log
(
'[chat-toolid-log] Chat setItem:'
,
toolIdFromState
,
'| line:676'
)
}
}
else
{
else
{
// 如果从 location.state 传递的是 null,清除 toolId
// 如果从 location.state 传递的是 null,视为未指定 toolId,保留当前缓存,避免首次进入时误清空
if
(
currentToolId
)
{
console
.
log
(
'[chat-toolid-log] Chat keep currentToolId when state toolId is null'
,
'| line:684'
)
dispatch
(
clearCurrentToolId
())
}
// 清除 sessionStorage,确保制度活化模式正确
sessionStorage
.
removeItem
(
'currentToolId'
)
}
}
// 清除 ref,避免下次路由变化时误用
// 清除 ref,避免下次路由变化时误用
toolIdFromStateRef
.
current
=
undefined
toolIdFromStateRef
.
current
=
undefined
...
@@ -695,12 +710,14 @@ export const Chat: React.FC = () => {
...
@@ -695,12 +710,14 @@ export const Chat: React.FC = () => {
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
if
(
fromCollect
)
{
if
(
fromCollect
)
{
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
console
.
log
(
'[chat-toolid-log] Chat setItem:'
,
finalToolId
,
'| line:702'
)
}
}
}
}
else
{
else
{
// 从收藏返回时,确保 sessionStorage 中有值
// 从收藏返回时,确保 sessionStorage 中有值
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
console
.
log
(
'[chat-toolid-log] Chat setItem:'
,
finalToolId
,
'| line:708'
)
}
}
}
}
}
}
...
@@ -709,12 +726,14 @@ export const Chat: React.FC = () => {
...
@@ -709,12 +726,14 @@ export const Chat: React.FC = () => {
// 如果有历史记录但没有 toolId,说明是制度活化,应该清除
// 如果有历史记录但没有 toolId,说明是制度活化,应该清除
if
(
hasQaRecords
&&
currentToolId
)
{
if
(
hasQaRecords
&&
currentToolId
)
{
dispatch
(
clearCurrentToolId
())
dispatch
(
clearCurrentToolId
())
console
.
log
(
'[chat-toolid-log] Chat clearCurrentToolId - hasQaRecords && currentToolId'
,
'| line:716'
)
}
}
// 如果没有历史记录,可能是新会话,但如果 Redux 中已经有 toolId(从 HistoryBarList 设置的),暂时保留
// 如果没有历史记录,可能是新会话,但如果 Redux 中已经有 toolId(从 HistoryBarList 设置的),暂时保留
// 因为可能是刚点击历史记录但 API 还没返回,或者 location.state 传递失败但 Redux 中已有正确的值
// 因为可能是刚点击历史记录但 API 还没返回,或者 location.state 传递失败但 Redux 中已有正确的值
else
if
(
!
hasQaRecords
&&
currentToolId
)
{
else
if
(
!
hasQaRecords
&&
currentToolId
)
{
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
sessionStorage
.
setItem
(
'currentToolId'
,
currentToolId
)
sessionStorage
.
setItem
(
'currentToolId'
,
currentToolId
)
console
.
log
(
'[chat-toolid-log] Chat setItem:'
,
currentToolId
,
'| line:722'
)
}
}
}
}
}
}
...
@@ -834,6 +853,15 @@ export const Chat: React.FC = () => {
...
@@ -834,6 +853,15 @@ export const Chat: React.FC = () => {
// 处理shouldSendQuestion的变化 - 自动发送问题
// 处理shouldSendQuestion的变化 - 自动发送问题
useEffect
(()
=>
{
useEffect
(()
=>
{
console
.
log
(
'[Chat] auto-send effect check:'
,
{
shouldSendQuestion
,
currentIdRef
:
currentIdRef
.
current
,
isLoading
,
allItemsLength
:
allItems
.
length
,
lastSentQuestion
:
lastSentQuestionRef
.
current
,
historyLoadedConversationId
:
historyLoadedRef
.
current
.
conversationId
,
currentToolId
,
})
if
(
if
(
shouldSendQuestion
shouldSendQuestion
&&
currentIdRef
.
current
&&
currentIdRef
.
current
...
@@ -864,9 +892,23 @@ export const Chat: React.FC = () => {
...
@@ -864,9 +892,23 @@ export const Chat: React.FC = () => {
}
}
else
{
else
{
// 如果历史记录还在加载中,保存待发送的问题,等待历史记录加载完成后再发送
// 如果历史记录还在加载中,保存待发送的问题,等待历史记录加载完成后再发送
console
.
log
(
'[Chat] auto-send blocked by history loading, stash pending question:'
,
{
shouldSendQuestion
,
historyLoadedConversationId
:
historyLoadedRef
.
current
.
conversationId
,
currentConversationId
:
currentIdRef
.
current
,
allItemsLength
:
allItems
.
length
,
})
pendingQuestionRef
.
current
=
shouldSendQuestion
pendingQuestionRef
.
current
=
shouldSendQuestion
}
}
}
}
else
{
console
.
log
(
'[Chat] auto-send conditions not met:'
,
{
hasShouldSendQuestion
:
Boolean
(
shouldSendQuestion
),
hasConversationId
:
Boolean
(
currentIdRef
.
current
),
isLoading
,
isDuplicateQuestion
:
shouldSendQuestion
===
lastSentQuestionRef
.
current
,
})
}
},
[
shouldSendQuestion
,
isLoading
,
allItems
.
length
,
currentToolId
,
id
])
},
[
shouldSendQuestion
,
isLoading
,
allItems
.
length
,
currentToolId
,
id
])
// 根据 currentToolId 获取对应的 toolName
// 根据 currentToolId 获取对应的 toolName
...
@@ -878,6 +920,12 @@ export const Chat: React.FC = () => {
...
@@ -878,6 +920,12 @@ export const Chat: React.FC = () => {
const
userRoles
=
getUserRolesForApi
()
const
userRoles
=
getUserRolesForApi
()
const
cacheKey
=
`toolList_
${
JSON
.
stringify
(
userRoles
)}
`
const
cacheKey
=
`toolList_
${
JSON
.
stringify
(
userRoles
)}
`
const
cached
=
sessionStorage
.
getItem
(
cacheKey
)
const
cached
=
sessionStorage
.
getItem
(
cacheKey
)
console
.
log
(
'[get_tool_list][Chat] check cache'
,
{
currentToolId
,
userRoles
,
cacheKey
,
hasCached
:
Boolean
(
cached
),
})
if
(
cached
)
{
if
(
cached
)
{
try
{
try
{
...
@@ -886,6 +934,10 @@ export const Chat: React.FC = () => {
...
@@ -886,6 +934,10 @@ export const Chat: React.FC = () => {
if
(
Date
.
now
()
-
timestamp
<
5
*
60
*
1000
)
{
if
(
Date
.
now
()
-
timestamp
<
5
*
60
*
1000
)
{
const
tool
=
toolList
.
find
((
t
:
any
)
=>
t
.
toolId
===
currentToolId
)
const
tool
=
toolList
.
find
((
t
:
any
)
=>
t
.
toolId
===
currentToolId
)
if
(
tool
?.
toolName
)
{
if
(
tool
?.
toolName
)
{
console
.
log
(
'[get_tool_list][Chat] cache hit'
,
{
currentToolId
,
toolName
:
tool
.
toolName
,
})
setCurrentToolName
(
tool
.
toolName
)
setCurrentToolName
(
tool
.
toolName
)
return
return
}
}
...
@@ -897,8 +949,16 @@ export const Chat: React.FC = () => {
...
@@ -897,8 +949,16 @@ export const Chat: React.FC = () => {
}
}
// 缓存无效或找不到工具时才调用接口
// 缓存无效或找不到工具时才调用接口
console
.
log
(
'[get_tool_list][Chat] cache miss, request get_tool_list'
,
{
currentToolId
,
userRoles
,
})
await
waitForToken
()
await
waitForToken
()
const
res
=
await
fetchToolList
({
userRoles
})
const
res
=
await
fetchToolList
({
userRoles
})
console
.
log
(
'[get_tool_list][Chat] response'
,
{
success
:
Boolean
(
res
),
length
:
Array
.
isArray
(
res
?.
data
)
?
res
.
data
.
length
:
-
1
,
})
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
)
if
(
tool
?.
toolName
)
{
if
(
tool
?.
toolName
)
{
...
...
src/pages/Chat/components/ChatItem/ChatAnswerRecommend.tsx
View file @
57f63bd8
...
@@ -54,13 +54,22 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
...
@@ -54,13 +54,22 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
busiType
=
'01'
busiType
=
'01'
recordType
=
'A17'
recordType
=
'A17'
}
}
// 特殊工具ID
// 特殊工具ID
提质增效
else
if
(
toolId
===
'6712395743241'
)
{
else
if
(
toolId
===
'6712395743241'
)
{
busiType
=
'01'
busiType
=
'01'
recordType
=
'A15'
recordType
=
'A15'
}
}
// 特殊工具ID 业务洞察
else
if
(
toolId
===
'6712395743242'
)
{
busiType
=
'01'
recordType
=
'A12'
}
// 特殊工具ID 数据助手
else
if
(
toolId
===
'6712395743240'
)
{
busiType
=
'01'
recordType
=
'A18'
}
}
}
try
{
try
{
const
res
=
await
fetchOrderQueryRecommendQuestion
(
const
res
=
await
fetchOrderQueryRecommendQuestion
(
answer
.
conversationId
||
''
,
answer
.
conversationId
||
''
,
...
...
src/pages/Home/HomeNew.tsx
View file @
57f63bd8
...
@@ -70,6 +70,7 @@ export const Home: React.FC = () => {
...
@@ -70,6 +70,7 @@ export const Home: React.FC = () => {
const
currentConversationId
=
useAppSelector
(
state
=>
state
.
conversation
.
currentConversationId
)
const
currentConversationId
=
useAppSelector
(
state
=>
state
.
conversation
.
currentConversationId
)
const
hasFetched
=
useRef
(
false
)
const
hasFetched
=
useRef
(
false
)
const
hasCalledBusinessApis
=
useRef
(
false
)
// 防止业务接口重复调用
const
hasCalledBusinessApis
=
useRef
(
false
)
// 防止业务接口重复调用
const
initialToolIdRef
=
useRef
<
string
>
(
''
)
// 首次进入时缓存的 toolId,避免登录清理后首次请求丢失
const
prevPathRef
=
useRef
<
string
>
(
location
.
pathname
)
// 记录上一次路径,用于检测从收藏页面返回
const
prevPathRef
=
useRef
<
string
>
(
location
.
pathname
)
// 记录上一次路径,用于检测从收藏页面返回
// 使用 useState
// 使用 useState
const
[
otherQuestions
,
setOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
otherQuestions
,
setOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
...
@@ -97,6 +98,9 @@ export const Home: React.FC = () => {
...
@@ -97,6 +98,9 @@ export const Home: React.FC = () => {
if
(
toolId
===
'6712395743241'
)
{
if
(
toolId
===
'6712395743241'
)
{
return
'A14'
// 提质增效
return
'A14'
// 提质增效
}
}
if
(
toolId
===
'6712395743242'
)
{
return
'A12'
// 业务洞察
}
// 未知的 toolId,默认返回制度活化
// 未知的 toolId,默认返回制度活化
return
'A16'
return
'A16'
}
}
...
@@ -106,18 +110,12 @@ export const Home: React.FC = () => {
...
@@ -106,18 +110,12 @@ export const Home: React.FC = () => {
try
{
try
{
// 等待 token 就绪后再调用接口
// 等待 token 就绪后再调用接口
await
waitForToken
()
await
waitForToken
()
// 从 sessionStorage 获取 toolId 作为 busiId
// 仅透传业务方附加参数,busiId/toolId 统一在接口层按 sessionStorage 实时解析
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
res
=
await
fetchSessionConversationId
(
data
||
{})
const
requestData
=
{
...(
data
||
{}),
busiId
:
toolId
,
}
const
res
=
await
fetchSessionConversationId
(
requestData
)
if
(
res
?.
data
?.
conversationId
)
{
if
(
res
?.
data
?.
conversationId
)
{
const
conversationId
=
res
.
data
.
conversationId
const
conversationId
=
res
.
data
.
conversationId
dispatch
(
setCurrentConversation
(
conversationId
))
dispatch
(
setCurrentConversation
(
conversationId
))
dispatch
(
setNavigationFlag
(
true
))
dispatch
(
setNavigationFlag
(
true
))
// 历史记录会在 Chat 页面自动渲染,不需要在这里获取
// 历史记录会在 Chat 页面自动渲染,不需要在这里获取
// 移除重复调用,避免接口被调用两次
// 移除重复调用,避免接口被调用两次
return
conversationId
return
conversationId
...
@@ -151,7 +149,7 @@ export const Home: React.FC = () => {
...
@@ -151,7 +149,7 @@ export const Home: React.FC = () => {
}
}
// 从 sessionStorage 获取 toolId 并确定 recordType
// 从 sessionStorage 获取 toolId 并确定 recordType
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
toolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
initialToolIdRef
.
current
||
''
const
recordType
=
getRecordTypeByToolId
(
toolId
)
const
recordType
=
getRecordTypeByToolId
(
toolId
)
const
res
=
await
fetchEfficiencyQuestionList
({
const
res
=
await
fetchEfficiencyQuestionList
({
...
@@ -214,7 +212,7 @@ export const Home: React.FC = () => {
...
@@ -214,7 +212,7 @@ export const Home: React.FC = () => {
}
}
// 从 sessionStorage 获取 toolId 并确定 recordType
// 从 sessionStorage 获取 toolId 并确定 recordType
const
currentToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
const
currentToolId
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
finalToolId
||
initialToolIdRef
.
current
||
''
const
recordType
=
getRecordTypeByToolId
(
currentToolId
)
const
recordType
=
getRecordTypeByToolId
(
currentToolId
)
// 调用真实 API 获取常见问题列表
// 调用真实 API 获取常见问题列表
...
@@ -250,10 +248,14 @@ export const Home: React.FC = () => {
...
@@ -250,10 +248,14 @@ export const Home: React.FC = () => {
if
(
!
isToolBtn
&&
toolId
)
{
if
(
!
isToolBtn
&&
toolId
)
{
// 提质增效模式,保存 toolId
// 提质增效模式,保存 toolId
dispatch
(
setCurrentToolId
(
toolId
))
dispatch
(
setCurrentToolId
(
toolId
))
safeSessionStorageSetItem
(
'currentToolId'
,
toolId
)
console
.
log
(
'[chat-toolid-log] HomeNew setItem:'
,
toolId
,
'| line:253'
)
}
}
else
{
else
{
// 制度活化,清除 toolId
// 制度活化,清除 toolId
dispatch
(
clearCurrentToolId
())
dispatch
(
clearCurrentToolId
())
sessionStorage
.
removeItem
(
'currentToolId'
)
console
.
log
(
'[chat-toolid-log] HomeNew removeItem'
,
'| line:260'
)
}
}
// 如果事件传递了 conversationId,延迟调用以确保路由更新完成
// 如果事件传递了 conversationId,延迟调用以确保路由更新完成
...
@@ -301,7 +303,10 @@ export const Home: React.FC = () => {
...
@@ -301,7 +303,10 @@ export const Home: React.FC = () => {
const
searchParams
=
new
URLSearchParams
(
url
.
search
)
const
searchParams
=
new
URLSearchParams
(
url
.
search
)
const
from
=
searchParams
.
get
(
'from'
)
const
from
=
searchParams
.
get
(
'from'
)
const
_loginCode
=
searchParams
.
get
(
'loginCode'
)
const
_loginCode
=
searchParams
.
get
(
'loginCode'
)
// 记录首次进入时的 toolId,避免在登录流程清理后丢失首次会话参数
if
(
!
initialToolIdRef
.
current
)
{
initialToolIdRef
.
current
=
safeSessionStorageGetItem
(
'currentToolId'
)
||
''
}
// 如果有 loginCode,执行 SSO 登录(包括 from=tactics 的情况)
// 如果有 loginCode,执行 SSO 登录(包括 from=tactics 的情况)
if
(
_loginCode
&&
viteOutputObj
===
'inner'
)
{
if
(
_loginCode
&&
viteOutputObj
===
'inner'
)
{
// 立即设置标志,防止重复执行(仅组件级别,每次组件挂载时会重置)
// 立即设置标志,防止重复执行(仅组件级别,每次组件挂载时会重置)
...
...
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