agent功能开发增加MCP后端
This commit is contained in:
149
src/components/ChatBot/MessageBubble.js
Normal file
149
src/components/ChatBot/MessageBubble.js
Normal file
@@ -0,0 +1,149 @@
|
||||
// src/components/ChatBot/MessageBubble.js
|
||||
// 聊天消息气泡组件
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Text,
|
||||
Avatar,
|
||||
useColorModeValue,
|
||||
IconButton,
|
||||
HStack,
|
||||
Code,
|
||||
Badge,
|
||||
VStack,
|
||||
} from '@chakra-ui/react';
|
||||
import { FiCopy, FiThumbsUp, FiThumbsDown } from 'react-icons/fi';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
||||
/**
|
||||
* 消息气泡组件
|
||||
* @param {Object} props
|
||||
* @param {Object} props.message - 消息对象
|
||||
* @param {boolean} props.isUser - 是否是用户消息
|
||||
* @param {Function} props.onCopy - 复制消息回调
|
||||
* @param {Function} props.onFeedback - 反馈回调
|
||||
*/
|
||||
export const MessageBubble = ({ message, isUser, onCopy, onFeedback }) => {
|
||||
const userBg = useColorModeValue('blue.500', 'blue.600');
|
||||
const botBg = useColorModeValue('gray.100', 'gray.700');
|
||||
const userColor = 'white';
|
||||
const botColor = useColorModeValue('gray.800', 'white');
|
||||
|
||||
const handleCopy = () => {
|
||||
navigator.clipboard.writeText(message.content);
|
||||
onCopy?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex
|
||||
w="100%"
|
||||
justify={isUser ? 'flex-end' : 'flex-start'}
|
||||
mb={4}
|
||||
>
|
||||
<Flex
|
||||
maxW="75%"
|
||||
flexDirection={isUser ? 'row-reverse' : 'row'}
|
||||
align="flex-start"
|
||||
>
|
||||
{/* 头像 */}
|
||||
<Avatar
|
||||
size="sm"
|
||||
name={isUser ? '用户' : 'AI助手'}
|
||||
bg={isUser ? 'blue.500' : 'green.500'}
|
||||
color="white"
|
||||
mx={3}
|
||||
/>
|
||||
|
||||
{/* 消息内容 */}
|
||||
<Box>
|
||||
<Box
|
||||
bg={isUser ? userBg : botBg}
|
||||
color={isUser ? userColor : botColor}
|
||||
px={4}
|
||||
py={3}
|
||||
borderRadius="lg"
|
||||
boxShadow="sm"
|
||||
>
|
||||
{message.type === 'text' ? (
|
||||
<Text fontSize="sm" whiteSpace="pre-wrap">
|
||||
{message.content}
|
||||
</Text>
|
||||
) : message.type === 'markdown' ? (
|
||||
<Box fontSize="sm" className="markdown-content">
|
||||
<ReactMarkdown>{message.content}</ReactMarkdown>
|
||||
</Box>
|
||||
) : message.type === 'data' ? (
|
||||
<VStack align="stretch" spacing={2}>
|
||||
{message.data && Array.isArray(message.data) && message.data.slice(0, 5).map((item, idx) => (
|
||||
<Box
|
||||
key={idx}
|
||||
p={3}
|
||||
bg={useColorModeValue('white', 'gray.600')}
|
||||
borderRadius="md"
|
||||
fontSize="xs"
|
||||
>
|
||||
{Object.entries(item).map(([key, value]) => (
|
||||
<Flex key={key} justify="space-between" mb={1}>
|
||||
<Text fontWeight="bold" mr={2}>{key}:</Text>
|
||||
<Text>{String(value)}</Text>
|
||||
</Flex>
|
||||
))}
|
||||
</Box>
|
||||
))}
|
||||
{message.data && message.data.length > 5 && (
|
||||
<Badge colorScheme="blue" alignSelf="center">
|
||||
+{message.data.length - 5} 更多结果
|
||||
</Badge>
|
||||
)}
|
||||
</VStack>
|
||||
) : null}
|
||||
</Box>
|
||||
|
||||
{/* 消息操作按钮(仅AI消息) */}
|
||||
{!isUser && (
|
||||
<HStack mt={2} spacing={2}>
|
||||
<IconButton
|
||||
icon={<FiCopy />}
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
aria-label="复制"
|
||||
onClick={handleCopy}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<FiThumbsUp />}
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
aria-label="赞"
|
||||
onClick={() => onFeedback?.('positive')}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<FiThumbsDown />}
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
aria-label="踩"
|
||||
onClick={() => onFeedback?.('negative')}
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
{/* 时间戳 */}
|
||||
<Text
|
||||
fontSize="xs"
|
||||
color="gray.500"
|
||||
mt={1}
|
||||
textAlign={isUser ? 'right' : 'left'}
|
||||
>
|
||||
{message.timestamp ? new Date(message.timestamp).toLocaleTimeString('zh-CN', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
}) : ''}
|
||||
</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default MessageBubble;
|
||||
Reference in New Issue
Block a user