import React, { useState } from 'react'; import { Button, Card, Spin } from 'antd'; import type { ChatItem, Feedbacktype, ThoughtItem, VisionFile } from '../../types/dify_chat'; import { CHAT_CONFIG } from '../../config/chat'; import Markdown from './markdown'; import ThoughtProcess from './thought-process'; import { Dayjs } from 'dayjs'; import '../../styles/components/chat-with-llm/chat-message.css'; interface ChatMessageProps { message: ChatItem; onFeedback?: (messageId: string, feedback: Feedbacktype) => void; isResponding?: boolean; onRegenerate?: (messageId: string) => void; } /** * 聊天消息组件 */ export default function ChatMessage({ message, onFeedback, isResponding = false, onRegenerate }: ChatMessageProps) { const [feedback, setFeedback] = useState<'like' | 'dislike' | null>( message.feedback?.rating || null ); const { id, content, isAnswer, agent_thoughts, message_files, isOpeningStatement, suggestedQuestions, more } = message; const isAgentMode = !!agent_thoughts && agent_thoughts.length > 0; /** * 处理反馈 */ const handleFeedback = async (type: 'like' | 'dislike') => { if (!id || id.startsWith('placeholder-') || id.startsWith('question-') || id.startsWith('opening-')) return; // 如果已经选择了相同的反馈,则取消选择 const newFeedback = feedback === type ? null : type; setFeedback(newFeedback); await onFeedback?.(id, { rating: newFeedback, }); }; /** * 渲染AI回答内容 */ const renderAnswerContent = () => { // console.log('🎨 渲染AI回答内容:', { content, isResponding, isAgentMode }); // 如果正在响应且没有内容 if (isResponding && (isAgentMode ? (!content && (agent_thoughts || []).filter(item => !!item.thought || !!item.tool).length === 0) : !content)) { return (
AI 正在思考...
); } // Agent模式(有思考过程) if (isAgentMode) { return (
{agent_thoughts?.map((thought, index) => (
{thought.thought && (
)} {thought.tool && ( )}
))}
); } // 普通模式 - 恢复Markdown渲染 return (
); }; /** * 渲染建议问题 */ const renderSuggestedQuestions = () => { if (!suggestedQuestions || suggestedQuestions.length === 0) return null; return (
建议问题:
{suggestedQuestions.map((question, index) => ( ))}
); }; /** * 渲染消息元信息 */ const renderMessageMeta = () => { if (!more) return null; return (
{more.time && 时间: {more.time}} {more.tokens && Token: {more.tokens}} {more.latency && 延迟: {more.latency}}
); }; // 如果是开场白,特殊处理 if (isOpeningStatement) { return (
{renderSuggestedQuestions()}
); } return (
{/* 消息内容 */}
{isAnswer ? renderAnswerContent() : (
{/* {renderImages(message_files)} */}
)}
); }