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
e9c54c3a
Commit
e9c54c3a
authored
May 28, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:answer自动提问逻辑
parent
c877b1a4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
27 deletions
+85
-27
src/pages/Chat/Chat.tsx
+52
-21
src/pages/Chat/components/ChatItem/ChatAnswerBox.tsx
+15
-5
src/pages/Chat/helper.ts
+18
-1
No files found.
src/pages/Chat/Chat.tsx
View file @
e9c54c3a
...
...
@@ -17,7 +17,7 @@ import { fetchCheckTokenApi, fetchStreamResponse } from '@/api/chat'
import
{
clearCurrentToolId
,
clearShouldSendQuestion
,
exitBusinessInsightSubWorkflow
,
fetchConversations
,
setBusinessInsightMainWorkflow
,
setBusinessInsightPendingQuestion
,
setBusinessInsightSubWorkflow
,
setCurrentToolId
,
updateBusinessInsightParamMap
}
from
'@/store/conversationSlice'
import
{
getUserRolesForApi
,
safeSessionStorageGetItem
,
waitForToken
}
from
'@/lib/utils'
import
{
findToolRowBySessionToolId
,
getFirstToolListRow
,
readToolListFromSessionStorage
,
resolveSubmitQuestionToolPair
}
from
'@/lib/toolRoleRecordTypes'
import
{
setWorkflowLastToolPair
}
from
'@/lib/workflowToolParams'
import
{
getWorkflowLastToolPair
,
setWorkflowLastToolPair
}
from
'@/lib/workflowToolParams'
import
type
{
RootState
}
from
'@/store'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
ScrollBtoIcon
from
'@/assets/svg/scrollBto.svg?react'
...
...
@@ -111,6 +111,8 @@ export const Chat: React.FC = () => {
const
expectingSubWorkflowOpenRef
=
useRef
(
false
)
const
pendingSubOpenRecordTypeRef
=
useRef
<
string
|
null
>
(
null
)
const
pendingSubQuestionRef
=
useRef
<
string
|
null
>
(
null
)
/** 最近一次向主工作流提交的用户问题(开子后 cardList 为空时优先用于问子) */
const
lastMainUserQuestionRef
=
useRef
<
string
|
null
>
(
null
)
/** 当前流式请求过程中最后一条 AI 回答的快照(避免流结束回调读到过期的 allItems) */
const
lastStreamedAiAnswerRef
=
useRef
<
WorkflowStreamAnswer
|
null
>
(
null
)
...
...
@@ -249,6 +251,25 @@ export const Chat: React.FC = () => {
)
=>
Promise
<
void
>
const
handleSubmitQuestionRef
=
useRef
<
SubmitQuestionFn
|
null
>
(
null
)
interface
WorkflowContinueExtra
{
workFlowSessionId
:
string
recordType
?:
string
busiType
?:
string
}
const
buildWorkflowContinueExtraFromRef
=
():
WorkflowContinueExtra
|
undefined
=>
{
const
wf
=
lastLoadedQaWorkflowContextRef
.
current
const
sessionId
=
wf
?.
workFlowSessionId
?.
trim
()
if
(
!
sessionId
)
return
undefined
const
recordType
=
wf
?.
recordType
?.
trim
()
return
{
workFlowSessionId
:
sessionId
,
...(
recordType
?
{
recordType
}
:
{}),
busiType
:
wf
?.
busiType
??
'01'
,
}
}
const
resolveWorkflowToolId
=
useCallback
(()
=>
{
try
{
return
(
sessionStorage
.
getItem
(
'currentToolId'
)
??
''
).
trim
()
...
...
@@ -376,7 +397,9 @@ export const Chat: React.FC = () => {
if
(
parsedAnswer
?.
recordType
!=
null
&&
parsedAnswer
.
question
!=
null
)
{
const
subRecordType
=
String
(
parsedAnswer
.
recordType
).
trim
()
const
pendingQ
=
String
(
parsedAnswer
.
question
)
const
controlQ
=
parsedAnswer
.
question
!=
null
?
String
(
parsedAnswer
.
question
).
trim
()
:
''
const
mainUserQ
=
lastMainUserQuestionRef
.
current
?.
trim
()
||
''
const
pendingQ
=
mainUserQ
||
controlQ
if
(
subRecordType
)
{
const
mainSessionId
=
(
lastAnswerSessionId
||
businessInsightWorkflowRef
.
current
.
mainWorkflowSessionId
?.
trim
()
||
''
...
...
@@ -389,8 +412,8 @@ export const Chat: React.FC = () => {
isInSubWorkflow
:
false
,
}
}
dispatch
(
setBusinessInsightPendingQuestion
(
pendingQ
))
pendingSubQuestionRef
.
current
=
pendingQ
dispatch
(
setBusinessInsightPendingQuestion
(
pendingQ
||
null
))
pendingSubQuestionRef
.
current
=
pendingQ
||
null
pendingSubOpenRecordTypeRef
.
current
=
subRecordType
expectingSubWorkflowOpenRef
.
current
=
true
queueMicrotask
(()
=>
{
...
...
@@ -428,6 +451,7 @@ export const Chat: React.FC = () => {
window
.
setTimeout
(()
=>
{
void
handleSubmitQuestionRef
.
current
?.(
followQ
,
undefined
,
resolveWorkflowToolId
()
||
undefined
,
{
busiType
:
'01'
,
...(
reopenRt
?
{
recordType
:
reopenRt
}
:
{}),
...(
mainSessionId
?
{
workFlowSessionId
:
mainSessionId
}
:
{}),
})
},
400
)
...
...
@@ -621,6 +645,14 @@ export const Chat: React.FC = () => {
const
sessionToolId
=
sessionStorage
.
getItem
(
'currentToolId'
)
??
undefined
const
resolvedToolId
=
toolId
??
sessionToolId
??
currentToolId
??
undefined
const
omitWorkFlowSessionId
=
extraParams
?.
omitWorkFlowSessionId
===
true
const
isEmptyQuestion
=
!
question
.
trim
()
if
(
!
isEmptyQuestion
&&
!
extraParams
?.
submitViaParamMap
&&
!
businessInsightWorkflowRef
.
current
.
isInSubWorkflow
)
{
lastMainUserQuestionRef
.
current
=
question
.
trim
()
}
// 业务洞察等工作流参数:有主/子会话态时合并进 extra(新建会话首包静默提问不传 session)
let
workflowExtraParams
=
extraParams
if
(
!
omitWorkFlowSessionId
&&
businessInsightWorkflowRef
.
current
)
{
...
...
@@ -644,16 +676,23 @@ export const Chat: React.FC = () => {
}
const
submitPairFromList
=
resolveSubmitQuestionToolPair
(
resolvedToolId
)
if
(
!
workflowExtraParams
?.
recordType
&&
submitPairFromList
.
recordType
)
{
workflowExtraParams
=
{
...
workflowExtraParams
,
recordType
:
submitPairFromList
.
recordType
,
if
(
!
workflowExtraParams
?.
recordType
)
{
const
resolvedRecordType
=
(
lastLoadedQaWorkflowContextRef
.
current
?.
recordType
?.
trim
()
||
getWorkflowLastToolPair
()?.
recordType
?.
trim
()
||
submitPairFromList
.
recordType
?.
trim
()
||
''
)
if
(
resolvedRecordType
)
{
workflowExtraParams
=
{
...
workflowExtraParams
,
recordType
:
resolvedRecordType
,
}
}
}
// 空问题 + 显式传入 recordType/busiType(如工具入口 autoSubmit)时走自动欢迎语流式逻辑;
// 开子工作流、已带 session、或已有主会话的空问题不应走欢迎语分支
const
isEmptyQuestion
=
!
question
.
trim
()
const
bootstrapBusiType
=
workflowExtraParams
?.
busiType
??
extraParams
?.
busiType
??
'01'
const
isNewSessionSilentBootstrap
=
isEmptyQuestion
&&
omitWorkFlowSessionId
...
...
@@ -1288,10 +1327,7 @@ export const Chat: React.FC = () => {
// 延迟发送,确保状态已更新
setTimeout
(()
=>
{
// 左侧常见问题自动发送:若 QA 列表最后一条带 recordType + workFlowSessionId,一并透传
const
wfExtra
=
lastLoadedQaWorkflowContextRef
.
current
const
autoExtra
=
wfExtra
?.
workFlowSessionId
?
{
workFlowSessionId
:
wfExtra
.
workFlowSessionId
,
busiType
:
wfExtra
.
busiType
??
'01'
}
:
undefined
const
autoExtra
=
buildWorkflowContinueExtraFromRef
()
handleSubmitQuestion
(
questionToSend
,
undefined
,
currentToolId
,
autoExtra
)
},
100
)
}
...
...
@@ -1364,6 +1400,7 @@ export const Chat: React.FC = () => {
// 重置历史记录加载标记,确保新会话时能正确触发自动发送
historyLoadedRef
.
current
.
conversationId
=
null
lastLoadedQaWorkflowContextRef
.
current
=
null
lastMainUserQuestionRef
.
current
=
null
// 保存 fromCollect 标记到 ref,避免 location.state 被清除后丢失
// 优先使用 location.state,其次使用 sessionStorage(用于 navigate(-1) 的情况)
fromCollectRef
.
current
=
Boolean
(
location
.
state
?.
fromCollect
)
||
Boolean
(
sessionStorage
.
getItem
(
'fromCollect'
))
...
...
@@ -1421,10 +1458,7 @@ export const Chat: React.FC = () => {
// 确保历史记录加载完成后再发送问题
setTimeout
(()
=>
{
console
.
log
(
'[Chat] 执行自动发送问题:'
,
questionToSend
)
const
wfExtra
=
lastLoadedQaWorkflowContextRef
.
current
const
autoExtra
=
wfExtra
?.
workFlowSessionId
?
{
workFlowSessionId
:
wfExtra
.
workFlowSessionId
,
busiType
:
wfExtra
.
busiType
??
'01'
}
:
undefined
const
autoExtra
=
buildWorkflowContinueExtraFromRef
()
handleSubmitQuestion
(
questionToSend
,
undefined
,
currentToolId
,
autoExtra
)
},
100
)
}
...
...
@@ -1684,10 +1718,7 @@ export const Chat: React.FC = () => {
<
ChatEditor
inputDisabled=
{
disableChatEditorForWorkflowForm
}
onSubmit=
{
(
question
,
toolId
)
=>
{
const
wf
=
lastLoadedQaWorkflowContextRef
.
current
const
extra
=
wf
?.
workFlowSessionId
?
{
workFlowSessionId
:
wf
.
workFlowSessionId
,
busiType
:
wf
.
busiType
??
'01'
}
:
undefined
const
extra
=
buildWorkflowContinueExtraFromRef
()
handleSubmitQuestion
(
question
,
undefined
,
toolId
,
extra
)
}
}
onToolClick=
{
(
isToolBtn
,
toolId
,
toolName
,
shouldChangeStyle
,
conversationId
,
isLoading
,
toolMeta
)
=>
{
...
...
src/pages/Chat/components/ChatItem/ChatAnswerBox.tsx
View file @
e9c54c3a
...
...
@@ -70,19 +70,29 @@ export const ChatAnswerBox: React.FC<ChatAnswerBoxProps> = ({ record, showIndex,
const
handleSubmitQuestionWithWorkflow
=
(
question
:
string
,
productCode
?:
string
)
=>
{
// 从会话历史中找到最后一个有 workFlowSessionId 的答案(从后往前查找)
let
lastWorkFlowSessionId
:
string
|
undefined
let
lastRecordType
:
string
|
undefined
let
lastRecordId
:
string
|
undefined
for
(
let
i
=
items
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
historyItem
=
items
[
i
]
if
(
historyItem
.
role
===
'ai'
&&
historyItem
.
answerList
?.[
0
]?.
workFlowSessionId
)
{
lastWorkFlowSessionId
=
historyItem
.
answerList
[
0
].
workFlowSessionId
lastRecordId
=
historyItem
.
answerList
[
0
].
recordId
const
ans
=
historyItem
.
answerList
[
0
]
lastWorkFlowSessionId
=
ans
.
workFlowSessionId
lastRecordId
=
ans
.
recordId
if
(
ans
.
recordType
!=
null
&&
String
(
ans
.
recordType
).
trim
())
lastRecordType
=
String
(
ans
.
recordType
).
trim
()
break
}
}
// 调用父组件传递的 onSubmitQuestion,传递 workFlowSessionId 和 recordId
// 跳过 toolId 和 extraParams 参数,正确传递 workFlowSessionId 和 recordId
onSubmitQuestion
(
question
,
productCode
,
undefined
,
undefined
,
lastWorkFlowSessionId
,
lastRecordId
)
const
workflowExtra
=
lastWorkFlowSessionId
?
{
workFlowSessionId
:
lastWorkFlowSessionId
,
...(
lastRecordType
?
{
recordType
:
lastRecordType
}
:
{}),
busiType
:
'01'
as
const
,
}
:
undefined
onSubmitQuestion
(
question
,
productCode
,
undefined
,
workflowExtra
,
lastWorkFlowSessionId
,
lastRecordId
)
}
return
(
...
...
src/pages/Chat/helper.ts
View file @
e9c54c3a
...
...
@@ -202,6 +202,23 @@ function parseWorkflowControlFromText(text: string): WorkflowControlPayload | nu
return
null
}
/** 兼容 API 返回 workFlowSessionId / workflowSessionId 等字段名 */
export
function
resolveWorkFlowSessionId
(
data
:
Record
<
string
,
unknown
>
|
Answer
|
null
|
undefined
,
fallback
?:
string
|
null
,
):
string
|
undefined
{
if
(
data
&&
typeof
data
===
'object'
)
{
const
record
=
data
as
Record
<
string
,
unknown
>
for
(
const
key
of
[
'workFlowSessionId'
,
'workflowSessionId'
,
'work_flow_session_id'
])
{
const
val
=
record
[
key
]
if
(
val
!=
null
&&
String
(
val
).
trim
())
return
String
(
val
).
trim
()
}
}
const
fb
=
fallback
!=
null
?
String
(
fallback
).
trim
()
:
''
return
fb
||
undefined
}
/** 流式分包元数据是否携带工作流结束标识 */
export
function
isWorkflowPacketEnd
(
data
:
Record
<
string
,
unknown
>
|
null
|
undefined
):
boolean
{
if
(
!
data
)
...
...
@@ -314,7 +331,7 @@ export function getLastQaRecordWorkflowContext(qaRecords: OriginalRecord[] | nul
for
(
let
i
=
list
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
a
=
list
[
i
]
as
Answer
const
recordType
=
a
?.
recordType
!=
null
?
String
(
a
.
recordType
).
trim
()
:
''
const
workFlowSessionId
=
a
?.
workFlowSessionId
!=
null
?
String
(
a
.
workFlowSessionId
).
trim
()
:
''
const
workFlowSessionId
=
resolveWorkFlowSessionId
(
a
)
??
''
if
(
recordType
&&
workFlowSessionId
)
{
const
busiType
=
a
?.
busiType
!=
null
?
String
(
a
.
busiType
).
trim
()
:
''
return
{
...
...
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