import React, { useState, useEffect, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fetchMessages, sendMessage } from '../../store/chat/chat.messages.thunks'; import { resetMessages, resetSendMessageStatus, addMessage } from '../../store/chat/chat.slice'; import { showNotification } from '../../store/notification.slice'; import SvgIcon from '../../components/SvgIcon'; import { fetchKnowledgeBases } from '../../store/knowledgeBase/knowledgeBase.thunks'; export default function ChatWindow({ chatId, knowledgeBaseId }) { const dispatch = useDispatch(); const [inputMessage, setInputMessage] = useState(''); const messagesEndRef = useRef(null); // 从 Redux store 获取数据 const { items: messages, status: messagesStatus, error: messagesError, } = useSelector((state) => state.chat.messages); const { status: sendStatus, error: sendError } = useSelector((state) => state.chat.sendMessage); const knowledgeBase = useSelector((state) => state.knowledgeBase.list.data?.items?.find((kb) => kb.id === knowledgeBaseId) ); const isLoadingKnowledgeBases = useSelector((state) => state.knowledgeBase.list.isLoading); // 获取聊天消息 useEffect(() => { if (chatId) { dispatch(fetchMessages(chatId)); } // 组件卸载时重置消息状态 return () => { dispatch(resetMessages()); }; }, [chatId, dispatch]); // 监听发送消息状态 useEffect(() => { if (sendStatus === 'failed' && sendError) { dispatch( showNotification({ message: `发送失败: ${sendError}`, type: 'danger', }) ); dispatch(resetSendMessageStatus()); } }, [sendStatus, sendError, dispatch]); // 滚动到底部 useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]); // 从 Redux store 获取知识库信息 useEffect(() => { if (!knowledgeBase && !isLoadingKnowledgeBases) { dispatch(fetchKnowledgeBases()); } }, [dispatch, knowledgeBase, isLoadingKnowledgeBases]); const handleSendMessage = (e) => { e.preventDefault(); if (!inputMessage.trim() || sendStatus === 'loading') return; // 立即添加用户消息到界面 const userMessage = { id: Date.now(), content: inputMessage, sender: 'user', timestamp: new Date().toISOString(), }; dispatch(addMessage(userMessage)); // 清空输入框 setInputMessage(''); // 发送消息到服务器 dispatch(sendMessage({ chatId, content: inputMessage })); }; // 渲染加载状态 const renderLoading = () => (
加载中...
加载聊天记录...
); // 渲染错误状态 const renderError = () => (
加载聊天记录失败,请重试
); // 渲染空状态 const renderEmpty = () => (
暂无聊天记录,发送一条消息开始聊天吧
); return (
{/* Chat header */}
{knowledgeBase?.name || '加载中...'}
{knowledgeBase?.description}
{/* Chat messages */}
{messagesStatus === 'loading' ? renderLoading() : messagesStatus === 'failed' ? renderError() : messages.length === 0 ? renderEmpty() : messages.map((message) => (
{message.content}
))} {sendStatus === 'loading' && (
加载中...
)}
{/* Chat input */}
setInputMessage(e.target.value)} disabled={sendStatus === 'loading'} />
); }