KnowledgeBase_frontend/src/pages/Chat/Chat.jsx

159 lines
6.0 KiB
React
Raw Normal View History

2025-03-05 03:46:45 +08:00
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
2025-03-13 09:14:25 +08:00
import { useDispatch, useSelector } from 'react-redux';
import { fetchChats, deleteChat, createChatRecord } from '../../store/chat/chat.thunks';
2025-03-13 09:14:25 +08:00
import { showNotification } from '../../store/notification.slice';
2025-03-05 03:46:45 +08:00
import ChatSidebar from './ChatSidebar';
import NewChat from './NewChat';
import ChatWindow from './ChatWindow';
export default function Chat() {
const { knowledgeBaseId, chatId } = useParams();
const navigate = useNavigate();
2025-03-13 09:14:25 +08:00
const dispatch = useDispatch();
// 从 Redux store 获取聊天记录列表
const {
items: chatHistory,
status,
error,
} = useSelector((state) => state.chat.history || { items: [], status: 'idle', error: null });
const operationStatus = useSelector((state) => state.chat.createSession?.status);
const operationError = useSelector((state) => state.chat.createSession?.error);
2025-03-13 09:14:25 +08:00
// 获取聊天记录列表
useEffect(() => {
dispatch(fetchChats({ page: 1, page_size: 20 }));
2025-03-13 09:14:25 +08:00
}, [dispatch]);
// 监听操作状态,显示通知
useEffect(() => {
if (operationStatus === 'succeeded') {
dispatch(
showNotification({
message: '操作成功',
type: 'success',
})
);
} else if (operationStatus === 'failed' && operationError) {
dispatch(
showNotification({
message: `操作失败: ${operationError}`,
type: 'danger',
})
);
}
}, [operationStatus, operationError, dispatch]);
2025-03-05 03:46:45 +08:00
// If we have a knowledgeBaseId but no chatId, check if we have an existing chat or create a new one
2025-03-05 03:46:45 +08:00
useEffect(() => {
if (knowledgeBaseId && !chatId) {
// 检查是否存在包含此知识库的聊天记录
const existingChat = chatHistory.find((chat) => {
// 检查知识库ID是否匹配
if (chat.datasets && Array.isArray(chat.datasets)) {
return chat.datasets.some((ds) => ds.id === knowledgeBaseId);
}
// 兼容旧格式
if (chat.dataset_id_list && Array.isArray(chat.dataset_id_list)) {
return chat.dataset_id_list.includes(knowledgeBaseId.replace(/-/g, ''));
}
return false;
});
console.log('existingChat', existingChat);
if (existingChat) {
// 找到现有聊天记录,导航到该聊天页面
navigate(`/chat/${knowledgeBaseId}/${existingChat.conversation_id}`);
} else {
// 创建新聊天
dispatch(
createChatRecord({
dataset_id_list: [knowledgeBaseId.replace(/-/g, '')],
question: '选择当前知识库,创建聊天',
})
)
.unwrap()
.then((response) => {
// 创建成功使用返回的conversation_id导航
if (response && response.conversation_id) {
navigate(`/chat/${knowledgeBaseId}/${response.conversation_id}`);
} else {
// 错误处理
dispatch(
showNotification({
message: '创建聊天失败未能获取会话ID',
type: 'danger',
})
);
}
})
.catch((error) => {
dispatch(
showNotification({
message: `创建聊天失败: ${error}`,
type: 'danger',
})
);
});
}
2025-03-05 03:46:45 +08:00
}
}, [knowledgeBaseId, chatId, chatHistory, navigate, dispatch]);
2025-03-05 03:46:45 +08:00
const handleDeleteChat = (id) => {
2025-03-13 09:14:25 +08:00
// 调用 Redux action 删除聊天
dispatch(deleteChat(id))
.unwrap()
.then(() => {
// 删除成功后显示通知
dispatch(
showNotification({
message: '聊天记录已删除',
type: 'success',
})
);
2025-03-05 03:46:45 +08:00
// If the deleted chat is the current one, navigate to the chat list
if (chatId === id) {
navigate('/chat');
}
})
.catch((error) => {
// 删除失败显示错误通知
dispatch(
showNotification({
message: `删除失败: ${error}`,
type: 'danger',
})
);
});
2025-03-05 03:46:45 +08:00
};
return (
<div className='chat-container container-fluid h-100'>
<div className='row h-100'>
{/* Sidebar */}
<div
className='col-md-3 col-lg-2 p-0 border-end'
style={{ height: 'calc(100vh - 73px)', overflowY: 'auto' }}
>
2025-03-13 09:14:25 +08:00
<ChatSidebar
chatHistory={chatHistory}
onDeleteChat={handleDeleteChat}
isLoading={status === 'loading'}
hasError={status === 'failed'}
/>
2025-03-05 03:46:45 +08:00
</div>
{/* Main Content */}
<div
className='chat-main col-md-9 col-lg-10 p-0'
style={{ height: 'calc(100vh - 73px)', overflowY: 'auto' }}
>
{!chatId ? <NewChat /> : <ChatWindow chatId={chatId} knowledgeBaseId={knowledgeBaseId} />}
</div>
</div>
</div>
);
}