mirror of
https://github.com/Funkoala14/KnowledgeBase_OOIN.git
synced 2025-06-08 05:09:44 +08:00
[dev]add loading, fix api multi triggers
This commit is contained in:
parent
8f92e25258
commit
a85154fbe1
@ -47,7 +47,10 @@ export default function Chat() {
|
||||
|
||||
// If we have a knowledgeBaseId but no chatId, check if we have an existing chat or create a new one
|
||||
useEffect(() => {
|
||||
if (knowledgeBaseId && !chatId) {
|
||||
// 只有当 knowledgeBaseId 存在但 chatId 不存在,且聊天历史已加载完成时才执行
|
||||
if (knowledgeBaseId && !chatId && status === 'succeeded' && !status.includes('loading')) {
|
||||
console.log('Chat.jsx: 检查是否需要创建聊天...');
|
||||
|
||||
// 检查是否存在包含此知识库的聊天记录
|
||||
const existingChat = chatHistory.find((chat) => {
|
||||
// 检查知识库ID是否匹配
|
||||
@ -60,12 +63,16 @@ export default function Chat() {
|
||||
}
|
||||
return false;
|
||||
});
|
||||
console.log('existingChat', existingChat);
|
||||
console.log('Chat.jsx: existingChat', existingChat);
|
||||
|
||||
if (existingChat) {
|
||||
console.log(
|
||||
`Chat.jsx: 找到现有聊天记录,导航到 /chat/${knowledgeBaseId}/${existingChat.conversation_id}`
|
||||
);
|
||||
// 找到现有聊天记录,导航到该聊天页面
|
||||
navigate(`/chat/${knowledgeBaseId}/${existingChat.conversation_id}`);
|
||||
} else {
|
||||
console.log('Chat.jsx: 创建新聊天...');
|
||||
// 创建新聊天
|
||||
dispatch(
|
||||
createChatRecord({
|
||||
@ -77,9 +84,13 @@ export default function Chat() {
|
||||
.then((response) => {
|
||||
// 创建成功,使用返回的conversation_id导航
|
||||
if (response && response.conversation_id) {
|
||||
console.log(
|
||||
`Chat.jsx: 创建成功,导航到 /chat/${knowledgeBaseId}/${response.conversation_id}`
|
||||
);
|
||||
navigate(`/chat/${knowledgeBaseId}/${response.conversation_id}`);
|
||||
} else {
|
||||
// 错误处理
|
||||
console.error('Chat.jsx: 创建失败,未能获取会话ID');
|
||||
dispatch(
|
||||
showNotification({
|
||||
message: '创建聊天失败:未能获取会话ID',
|
||||
@ -89,6 +100,7 @@ export default function Chat() {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Chat.jsx: 创建失败', error);
|
||||
dispatch(
|
||||
showNotification({
|
||||
message: `创建聊天失败: ${error}`,
|
||||
@ -98,7 +110,7 @@ export default function Chat() {
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [knowledgeBaseId, chatId, chatHistory, navigate, dispatch]);
|
||||
}, [knowledgeBaseId, chatId, chatHistory, status, navigate, dispatch]);
|
||||
|
||||
const handleDeleteChat = (id) => {
|
||||
// 调用 Redux action 删除聊天
|
||||
|
@ -97,16 +97,6 @@ export default function ChatSidebar({ chatHistory = [], onDeleteChat, isLoading
|
||||
<div className='text-truncate fw-medium'>
|
||||
{chat.datasets?.map((ds) => ds.name).join(', ') || '未命名知识库'}
|
||||
</div>
|
||||
<div className='small text-muted text-truncate' style={{ maxWidth: '160px' }}>
|
||||
{chat.last_message
|
||||
? chat.last_message.length > 30
|
||||
? chat.last_message.substring(0, 30) + '...'
|
||||
: chat.last_message
|
||||
: '新对话'}
|
||||
</div>
|
||||
<div className='x-small text-muted mt-1'>
|
||||
{chat.last_time && new Date(chat.last_time).toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div
|
||||
|
@ -235,7 +235,7 @@ export default function ChatWindow({ chatId, knowledgeBaseId }) {
|
||||
<div
|
||||
key={message.id}
|
||||
className={`d-flex ${
|
||||
message.role === 'user' ? 'align-item-end' : 'align-item-start'
|
||||
message.role === 'user' ? 'align-items-end' : 'align-items-start'
|
||||
} mb-3 flex-column`}
|
||||
>
|
||||
<div
|
||||
|
@ -8,6 +8,8 @@ import SvgIcon from '../../components/SvgIcon';
|
||||
export default function NewChat() {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [selectedDatasetId, setSelectedDatasetId] = useState(null);
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
|
||||
// 从 Redux store 获取可用知识库数据
|
||||
const datasets = useSelector((state) => state.chat.availableDatasets.items || []);
|
||||
@ -17,6 +19,7 @@ export default function NewChat() {
|
||||
// 获取聊天历史记录
|
||||
const chatHistory = useSelector((state) => state.chat.history.items || []);
|
||||
const chatHistoryLoading = useSelector((state) => state.chat.history.status === 'loading');
|
||||
const chatCreationStatus = useSelector((state) => state.chat.sendMessage?.status);
|
||||
|
||||
// 获取可用知识库列表和聊天历史
|
||||
useEffect(() => {
|
||||
@ -37,7 +40,13 @@ export default function NewChat() {
|
||||
}, [error, dispatch]);
|
||||
|
||||
// 处理知识库选择
|
||||
const handleSelectKnowledgeBase = (dataset) => {
|
||||
const handleSelectKnowledgeBase = async (dataset) => {
|
||||
if (isNavigating) return; // 如果正在导航中,阻止重复点击
|
||||
|
||||
try {
|
||||
setSelectedDatasetId(dataset.id);
|
||||
setIsNavigating(true);
|
||||
|
||||
// 判断聊天历史中是否已存在该知识库的聊天记录
|
||||
const existingChat = chatHistory.find((chat) => {
|
||||
// 检查知识库ID是否匹配
|
||||
@ -53,10 +62,37 @@ export default function NewChat() {
|
||||
|
||||
if (existingChat) {
|
||||
// 找到现有聊天记录,导航到该聊天页面
|
||||
console.log(`找到现有聊天记录,直接导航到 /chat/${dataset.id}/${existingChat.conversation_id}`);
|
||||
navigate(`/chat/${dataset.id}/${existingChat.conversation_id}`);
|
||||
} else {
|
||||
// 没有找到现有聊天记录,创建新的聊天
|
||||
navigate(`/chat/${dataset.id}`);
|
||||
// 没有找到现有聊天记录,直接创建新的聊天(而不是导航到 /chat/${dataset.id})
|
||||
console.log(`未找到现有聊天记录,直接创建新的聊天,知识库ID: ${dataset.id}`);
|
||||
|
||||
// 直接在这里创建聊天记录,避免在 Chat.jsx 中再次创建
|
||||
const response = await dispatch(
|
||||
createChatRecord({
|
||||
dataset_id_list: [dataset.id.replace(/-/g, '')],
|
||||
question: '选择当前知识库,创建聊天',
|
||||
})
|
||||
).unwrap();
|
||||
|
||||
if (response && response.conversation_id) {
|
||||
console.log(`创建成功,导航到 /chat/${dataset.id}/${response.conversation_id}`);
|
||||
navigate(`/chat/${dataset.id}/${response.conversation_id}`);
|
||||
} else {
|
||||
throw new Error('未能获取会话ID');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('导航或创建聊天失败:', error);
|
||||
dispatch(
|
||||
showNotification({
|
||||
message: `创建聊天失败: ${error.message || '请重试'}`,
|
||||
type: 'danger',
|
||||
})
|
||||
);
|
||||
setIsNavigating(false);
|
||||
setSelectedDatasetId(null);
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,17 +109,48 @@ export default function NewChat() {
|
||||
|
||||
return (
|
||||
<div className='container-fluid px-4 py-5'>
|
||||
{/* 导航中的遮罩层 */}
|
||||
{isNavigating && (
|
||||
<div
|
||||
className='position-fixed top-0 start-0 w-100 h-100 d-flex justify-content-center align-items-center'
|
||||
style={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.7)',
|
||||
zIndex: 1050,
|
||||
}}
|
||||
>
|
||||
<div className='text-center'>
|
||||
<div className='spinner-border mb-2' role='status'>
|
||||
<span className='visually-hidden'>加载中...</span>
|
||||
</div>
|
||||
<div>正在加载聊天界面...</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h4 className='mb-4'>选择知识库开始聊天</h4>
|
||||
<div className='row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 justify-content-center'>
|
||||
{datasets.length > 0 ? (
|
||||
datasets.map((dataset) => (
|
||||
<div key={dataset.id} className='col'>
|
||||
<div
|
||||
className='card h-100 shadow-sm border-0 cursor-pointer'
|
||||
className={`card h-100 shadow-sm border-0 ${!isNavigating ? 'cursor-pointer' : ''} ${
|
||||
selectedDatasetId === dataset.id ? 'border-primary' : ''
|
||||
}`}
|
||||
onClick={() => handleSelectKnowledgeBase(dataset)}
|
||||
style={{ opacity: isNavigating && selectedDatasetId !== dataset.id ? 0.6 : 1 }}
|
||||
>
|
||||
<div className='card-body'>
|
||||
<h5 className='card-title'>{dataset.name}</h5>
|
||||
<h5 className='card-title d-flex justify-content-between align-items-center'>
|
||||
{dataset.name}
|
||||
{selectedDatasetId === dataset.id && isNavigating && (
|
||||
<div
|
||||
className='spinner-border spinner-border-sm text-primary'
|
||||
role='status'
|
||||
>
|
||||
<span className='visually-hidden'>加载中...</span>
|
||||
</div>
|
||||
)}
|
||||
</h5>
|
||||
<p className='card-text text-muted'>{dataset.desc || dataset.description || ''}</p>
|
||||
<div className='text-muted small d-flex align-items-center gap-2'>
|
||||
<span className='d-flex align-items-center gap-1'>
|
||||
|
Loading…
Reference in New Issue
Block a user