From 77d017b70e6431daa985461cc49c9f70f0e1561e Mon Sep 17 00:00:00 2001 From: zhouhr Date: Thu, 21 May 2026 15:57:35 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(chat):=20=E6=B7=BB=E5=8A=A0=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E9=A1=B5=E9=9D=A2=E9=97=AE=E9=A2=98=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 nextQuestionAdvice 服务用于获取下一步问题建议 - 添加 questionTextRef 保存当前问题文本以供建议使用 - 在消息流完成时调用建议接口并更新建议问题列表 - 在 store 中新增 suggestProblem 和 suggestSuggestLoading 状态管理 - 在 MessageList 组件中显示建议问题及加载动画 - 根据配置项控制建议问题显示开关 ``` --- console/frontend/src/hooks/use-chat.ts | 21 +++++++++++ .../chat-page/components/message-list.tsx | 36 ++++++++++++++++++- console/frontend/src/store/chat-store.ts | 8 +++++ console/frontend/src/types/chat.ts | 4 +++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/console/frontend/src/hooks/use-chat.ts b/console/frontend/src/hooks/use-chat.ts index 114ff148..00799622 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 ff3d2fc6..397cee97 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 449d13fe..2a98fc2c 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 a0b1f04e..852752a8 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; //设置建议问题加载状态 } // 文件上传相关类型定义 -- Gitee