Commit c3794c2d by weiyudumei

fix: 修复 workFlowSeeionId 传递和自动提交重复调用问题

- 修复流式响应更新时 workFlowSeeionId 和 recordId 被覆盖的问题,保留之前保存的值
- 修复自动提交逻辑重复调用问题,只在 firstQaFlag 首次变为 true 时执行一次
- 添加 lastFirstQaFlagRef 跟踪 firstQaFlag 变化,避免流式更新时重复触发
- 移除 answer.recordId 和 answer.workFlowSeeionId 作为 useEffect 依赖项
- 修复 TacticsChat.tsx 中 existingAnswer 变量名冲突问题
parent 36e5fdc6
......@@ -39,6 +39,7 @@ export const Chat: React.FC = () => {
const [allItems, setAllItems] = useState<ChatRecord[]>([])
const dispatch = useAppDispatch()
const { shouldSendQuestion, currentToolId, conversations } = useAppSelector((state: RootState) => state.conversation)
const isAsking = useAppSelector((state: RootState) => state.chat.isAsking)
// 标记历史记录是否已加载完成,用于确保自动发送问题在历史记录加载后执行
const historyLoadedRef = useRef<{ conversationId: string | null }>({ conversationId: null })
// 保存待发送的问题,用于在历史记录加载完成后发送
......@@ -152,12 +153,19 @@ export const Chat: React.FC = () => {
// 在流式响应过程中,忽略服务器返回的 endAnswerFlag,避免过早禁用输入框
const { endAnswerFlag: _omitEndAnswerFlag, ...dataWithoutEndFlag } = msg.content.data || {}
// 保留之前保存的 workFlowSeeionId 和 recordId,避免被覆盖
const existingAnswer = newItems[lastIndex].answerList?.[0] || {}
newItems[lastIndex] = {
...newItems[lastIndex],
question,
answerList: [
{
...existingAnswer,
...dataWithoutEndFlag,
// 如果新的数据中没有 workFlowSeeionId,保留之前的值
workFlowSeeionId: dataWithoutEndFlag.workFlowSeeionId ?? existingAnswer.workFlowSeeionId,
// 如果新的数据中没有 recordId,保留之前的值
recordId: dataWithoutEndFlag.recordId ?? existingAnswer.recordId,
isShow: false,
answer: filteredAnswer,
},
......
......@@ -21,6 +21,7 @@ export const CardWorkflowForm: React.FC<CardWorkflowFormProps> = ({
const [formValues, setFormValues] = useState<Record<string, string>>({})
const [searchParams] = useSearchParams()
const hasAutoSubmittedRef = useRef(false) // 防止重复自动提交
const lastFirstQaFlagRef = useRef<boolean | undefined>(undefined) // 记录上次的 firstQaFlag 值
// 获取 text 类型的字段,使用 useMemo 稳定引用
const textFields = useMemo(() => {
......@@ -49,12 +50,19 @@ export const CardWorkflowForm: React.FC<CardWorkflowFormProps> = ({
// 重置自动提交标志,当 firstQaFlag 变化时重新评估
if (answer.firstQaFlag !== true) {
hasAutoSubmittedRef.current = false
lastFirstQaFlagRef.current = false // 重置记录的值,确保下次变为 true 时能正确触发
}
}, [attachment, answer.firstQaFlag, searchParams, textFields])
// 如果 firstQaFlag 为 true,自动提交
useEffect(() => {
if (answer.firstQaFlag === true && !hasAutoSubmittedRef.current && !isSubmitting && !isCompleted) {
// 检查 firstQaFlag 是否从 false/undefined 变为 true(首次变为 true)
const isFirstQaFlagChangedToTrue = answer.firstQaFlag === true && lastFirstQaFlagRef.current !== true
// 更新记录的值
lastFirstQaFlagRef.current = answer.firstQaFlag
// 只在 firstQaFlag 首次变为 true 且尚未自动提交时执行
if (isFirstQaFlagChangedToTrue && !hasAutoSubmittedRef.current && !isSubmitting && !isCompleted) {
// 检查是否所有字段都有值(从 URL query 中读取的)
const allFieldsHaveValues = textFields.every((field) => {
const queryValue = searchParams.get(field.key)
......@@ -71,6 +79,7 @@ export const CardWorkflowForm: React.FC<CardWorkflowFormProps> = ({
})
// 获取 recordId 和 workFlowSeeionId(从 answer 中获取,第一次可能没有)
// 注意:这里使用最新的 answer 值,即使依赖项中没有包含它们
const recordId = answer.recordId
const workFlowSeeionId = answer.workFlowSeeionId
......@@ -80,7 +89,8 @@ export const CardWorkflowForm: React.FC<CardWorkflowFormProps> = ({
}, 100)
}
}
}, [answer.firstQaFlag, answer.recordId, answer.workFlowSeeionId, isSubmitting, isCompleted, searchParams, textFields, onSubmitWorkflow])
// 移除 answer.recordId 和 answer.workFlowSeeionId 作为依赖项,避免流式更新时重复触发
}, [answer.firstQaFlag, isSubmitting, isCompleted, searchParams, textFields, onSubmitWorkflow])
const handleInputChange = (key: string, value: string) => {
setFormValues(prev => ({
......
......@@ -241,8 +241,8 @@ export const TacticsChat: React.FC = () => {
// 确保 answer 字段存在,如果不存在则使用空字符串,null 替换为 \n
const newAnswer = msg.content?.data?.answer ?? '\n'
// 创建最后一项的新对象,合并现有数据和新的 answer
const existingAnswer = newItems[lastAiIndex].answerList?.[0]?.answer || ''
const originalAnswer = existingAnswer + newAnswer
const existingAnswerText = newItems[lastAiIndex].answerList?.[0]?.answer || ''
const originalAnswer = existingAnswerText + newAnswer
// 移除 ♪ 符号之后的所有文本(与历史记录保持一致)
let filteredAnswer = originalAnswer.split('♪')[0]
// 移除所有括号及其内容
......@@ -254,12 +254,19 @@ export const TacticsChat: React.FC = () => {
// 在流式响应过程中,忽略服务器返回的 endAnswerFlag,避免过早禁用输入框
const { endAnswerFlag: _omitEndAnswerFlag, ...dataWithoutEndFlag } = msg.content.data || {}
// 保留之前保存的 workFlowSeeionId 和 recordId,避免被覆盖
const existingAnswer = newItems[lastAiIndex].answerList?.[0] || {}
newItems[lastAiIndex] = {
...newItems[lastAiIndex],
question,
answerList: [
{
...existingAnswer,
...dataWithoutEndFlag,
// 如果新的数据中没有 workFlowSeeionId,保留之前的值
workFlowSeeionId: dataWithoutEndFlag.workFlowSeeionId ?? existingAnswer.workFlowSeeionId,
// 如果新的数据中没有 recordId,保留之前的值
recordId: dataWithoutEndFlag.recordId ?? existingAnswer.recordId,
isShow: false,
answer: filteredAnswer,
},
......
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