KnowledgeBase_frontend/src/pages/Chat/ChatWindow.jsx
2025-03-04 14:46:45 -05:00

162 lines
5.9 KiB
JavaScript

import React, { useState, useEffect, useRef } from 'react';
import SvgIcon from '../../components/SvgIcon';
export default function ChatWindow({ chatId, knowledgeBaseId }) {
const [messages, setMessages] = useState([]);
const [inputMessage, setInputMessage] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [knowledgeBase, setKnowledgeBase] = useState(null);
const messagesEndRef = useRef(null);
// Fetch knowledge base details
useEffect(() => {
// In a real app, you would fetch the knowledge base details from the API
const mockKnowledgeBases = [
{
id: '1',
title: '产品开发知识库',
description: '产品开发流程及规范说明文档',
},
{
id: '2',
title: '市场分析知识库',
description: '2025年Q1市场分析总结',
},
{
id: '3',
title: '财务知识库',
description: '月度财务分析报告',
},
{
id: '4',
title: '技术架构知识库',
description: '系统架构设计文档',
},
{
id: '5',
title: '用户研究知识库',
description: '用户调研和反馈分析',
},
];
const kb = mockKnowledgeBases.find((kb) => kb.id === knowledgeBaseId);
setKnowledgeBase(kb);
// In a real app, you would fetch the chat messages from the API
// For now, we'll just add a welcome message
if (kb) {
setMessages([
{
id: '1',
sender: 'bot',
content: `欢迎使用 ${kb.title},有什么可以帮助您的?`,
timestamp: new Date().toISOString(),
},
]);
}
}, [chatId, knowledgeBaseId]);
// Scroll to bottom when messages change
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
const handleSendMessage = (e) => {
e.preventDefault();
if (!inputMessage.trim()) return;
// Add user message
const userMessage = {
id: Date.now().toString(),
sender: 'user',
content: inputMessage,
timestamp: new Date().toISOString(),
};
setMessages((prev) => [...prev, userMessage]);
setInputMessage('');
setIsLoading(true);
// Simulate bot response after a delay
setTimeout(() => {
const botMessage = {
id: (Date.now() + 1).toString(),
sender: 'bot',
content: `这是来自 ${knowledgeBase?.title} 的回复:${inputMessage}`,
timestamp: new Date().toISOString(),
};
setMessages((prev) => [...prev, botMessage]);
setIsLoading(false);
}, 1000);
};
return (
<div className='chat-window d-flex flex-column h-100'>
{/* Chat header */}
<div className='p-3 border-bottom'>
<h5 className='mb-0'>{knowledgeBase?.title || 'Loading...'}</h5>
<small className='text-muted'>{knowledgeBase?.description}</small>
</div>
{/* Chat messages */}
<div className='flex-grow-1 p-3 overflow-auto' >
<div className='container'>
{messages.map((message) => (
<div
key={message.id}
className={`d-flex ${
message.sender === 'user' ? 'justify-content-end' : 'justify-content-start'
} mb-3`}
>
<div
className={`p-3 rounded-3 ${
message.sender === 'user' ? 'bg-primary text-white' : 'bg-white border'
}`}
style={{ maxWidth: '75%' }}
>
{message.content}
</div>
</div>
))}
{isLoading && (
<div className='d-flex justify-content-start mb-3'>
<div className='p-3 rounded-3 bg-white border'>
<div className='spinner-border spinner-border-sm text-secondary' role='status'>
<span className='visually-hidden'>Loading...</span>
</div>
</div>
</div>
)}
<div ref={messagesEndRef} />
</div>
</div>
{/* Chat input */}
<div className='p-3 border-top'>
<form onSubmit={handleSendMessage} className='d-flex gap-2'>
<input
type='text'
className='form-control'
placeholder='输入你的问题...'
value={inputMessage}
onChange={(e) => setInputMessage(e.target.value)}
disabled={isLoading}
/>
<button
type='submit'
className='btn btn-dark d-flex align-items-center justify-content-center gap-2'
disabled={isLoading || !inputMessage.trim()}
>
<SvgIcon className='send' color='#ffffff' />
<span className='ms-1' style={{ minWidth: 'fit-content' }}>发送</span>
</button>
</form>
</div>
</div>
);
}