diff --git a/console/frontend/src/hooks/use-chat.ts b/console/frontend/src/hooks/use-chat.ts index 114ff148466e72622f69e785059445e6980eafb2..00799622dd77b23dd0d799e48a0b5b30fbc566c3 100644 --- a/console/frontend/src/hooks/use-chat.ts +++ b/console/frontend/src/hooks/use-chat.ts @@ -5,6 +5,7 @@ import { useRef } from 'react'; import type { Option } from '@/types/chat'; import { useNavigate } from 'react-router-dom'; import { baseURL } from '@/utils/http'; +import { nextQuestionAdvice } from '@/services/common'; // SSE 数据类型定义 interface SSEData { @@ -46,6 +47,7 @@ const useChat = () => { const controllerRef = useRef(new AbortController()); //sse请求控制器 const sidRef = useRef(''); //sid const reqIdRef = useRef(0); //reqId + const questionTextRef = useRef(''); //当前问题文本,用于结束后获取建议问题 const messageList = useChatStore(state => state.messageList); //消息列表 const currentChatId = useChatStore(state => state.currentChatId); //当前聊天id const chatFileListNoReq = useChatStore(state => state.chatFileListNoReq); //文件列表 @@ -74,6 +76,8 @@ const useChat = () => { ); //工作流操作 const setIsWorkflowOption = useChatStore(state => state.setIsWorkflowOption); //是否是选项 const setWorkflowOption = useChatStore(state => state.setWorkflowOption); //工作流选项 + const setSuggestProblem = useChatStore(state => state.setSuggestProblem); //设置建议问题列表 + const setSuggestLoading = useChatStore(state => state.setSuggestLoading); //设置建议问题加载状态 const navigate = useNavigate(); /** * @@ -227,6 +231,21 @@ const useChat = () => { } // 完成流式消息,添加sid和id finishStreamingMessage(sidRef.current, reqIdRef.current); + // 获取下一步问题建议 + const questionText = questionTextRef.current; + if (questionText) { + setSuggestLoading(true); + nextQuestionAdvice({ question: questionText }) + .then((data: any) => { + setSuggestProblem( + Array.isArray(data) ? data : data?.data || [] + ); + }) + .catch(() => { + setSuggestProblem([]); + }) + .finally(() => setSuggestLoading(false)); + } controller.abort('结束'); return; } @@ -270,6 +289,8 @@ const useChat = () => { form.append('chatId', `${currentChatId}`); form.append('workflowVersion', version || ''); workflowOperation && form.append('workflowOperation', workflowOperation); + // 存储问题文本,用于结束后获取建议问题 + questionTextRef.current = msg; // 执行回调函数 onSendCallback && onSendCallback(); fetchSSE(esURL, form); diff --git a/console/frontend/src/pages/chat-page/components/message-list.tsx b/console/frontend/src/pages/chat-page/components/message-list.tsx index ff3d2fc60ae4a9082d62ee1b6da3b7de0b77a26c..397cee97d97f2a3cbc7c452839a01fb230134432 100644 --- a/console/frontend/src/pages/chat-page/components/message-list.tsx +++ b/console/frontend/src/pages/chat-page/components/message-list.tsx @@ -56,6 +56,10 @@ const MessageList = (props: { const isLoading = useChatStore(state => state.isLoading); //是否正在加载 const streamId = useChatStore(state => state.streamId); //流式回复id const workflowOperation = useChatStore(state => state.workflowOperation); //工作流操作 + const suggestProblem = useChatStore(state => state.suggestProblem); //下一步问题建议列表 + const suggestSuggestLoading = useChatStore( + state => state.suggestSuggestLoading + ); //建议问题加载状态 const { user } = useUserStore(); const lastClickedQA: MutableRefObject = useRef(null); @@ -69,6 +73,9 @@ const MessageList = (props: { option: { id: string }; } | null>(null); + const [suggestedQuestionsAfterAnswerEnabled, setSuggestedQuestionsAfterAnswerEnabled] = useState(false); + + // 处理节点选项点击 const handleNodeClick = (option: Option, messageId: number) => { setSelectedOptionId({ id: messageId, option }); @@ -95,6 +102,9 @@ const MessageList = (props: { setInputExample( inputExample?.filter((item: string) => item.length > 0)?.slice(0, 3) ); + setSuggestedQuestionsAfterAnswerEnabled( + advancedConfig?.suggestedQuestionsAfterAnswer?.enabled || false + ); } catch (error) { setInputExample([]); } @@ -273,6 +283,31 @@ const MessageList = (props: { chatType={chatType} /> )} + {suggestedQuestionsAfterAnswerEnabled && + isLastMessage && + item.sid && ( +
+ {suggestSuggestLoading ? ( +
+ + + +
+ ) : suggestProblem.length > 0 ? ( +
+ {suggestProblem.map((text, idx) => ( +
handleSendMessage({ item: text })} + > + {text} +
+ ))} +
+ ) : null} +
+ )} ); }; @@ -308,7 +343,6 @@ const MessageList = (props: { ); })} - {renderHeaderAndRecommend()} diff --git a/console/frontend/src/store/chat-store.ts b/console/frontend/src/store/chat-store.ts index 449d13fe64ac406dd81e36e65241022166ae29e0..2a98fc2c990b980718a856fe5cbd7dcd7cb5c1da 100644 --- a/console/frontend/src/store/chat-store.ts +++ b/console/frontend/src/store/chat-store.ts @@ -29,6 +29,8 @@ const useChatStore = create((set, get) => ({ vmsInteractiveRef: null, vmsInteractiveRefStatus: '', vmsInteractiveRefPlayer: null, + suggestProblem: [], + suggestSuggestLoading: false, // 操作 initChatStore: (): void => { set({ @@ -48,6 +50,8 @@ const useChatStore = create((set, get) => ({ option: [] as Option[], content: '', }, + suggestProblem: [], + suggestSuggestLoading: false, }); }, @@ -188,5 +192,9 @@ const useChatStore = create((set, get) => ({ getVmsInteractiveRefStatus: () => get().vmsInteractiveRefStatus, setChatType: chatType => set({ chatType }), getChatType: () => get().chatType, + setSuggestProblem: (suggestProblem: string[]): void => + set({ suggestProblem }), + setSuggestLoading: (suggestSuggestLoading: boolean): void => + set({ suggestSuggestLoading }), })); export default useChatStore; diff --git a/console/frontend/src/types/chat.ts b/console/frontend/src/types/chat.ts index a0b1f04ecaf13b84a100365b914d43d2e4a98498..852752a82069aae3c71e7c3337933135ebb44ce1 100644 --- a/console/frontend/src/types/chat.ts +++ b/console/frontend/src/types/chat.ts @@ -261,6 +261,8 @@ export interface ChatState { vmsInteractiveRefStatus: string; //虚拟人实例状态,主要记录是否被打断了 vmsInteractiveRefPlayer: any; //虚拟人sdk实例播放器 chatType: string; //聊天类型四种:1、文本 2、语音通话 3、虚拟人播报 4、语音虚拟人 + suggestProblem: string[]; //下一步问题建议列表 + suggestSuggestLoading: boolean; //建议问题加载中 } // 聊天Store操作接口 @@ -294,6 +296,8 @@ export interface ChatActions { getVmsInteractiveRefStatus: () => string; setChatType: (chatType: string) => void; getChatType: () => string; + setSuggestProblem: (suggestProblem: string[]) => void; //设置下一步问题建议列表 + setSuggestLoading: (suggestLoading: boolean) => void; //设置建议问题加载状态 } // 文件上传相关类型定义