mirror of
https://github.com/Funkoala14/KnowledgeBase_OOIN.git
synced 2025-06-08 05:38:13 +08:00
162 lines
5.9 KiB
JavaScript
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>
|
|
);
|
|
}
|