import React from 'react'; import { CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined } from '@ant-design/icons'; import { CodeHighlighter, Think } from '@ant-design/x'; import XMarkdown from '@ant-design/x-markdown'; import type { ComponentProps } from '@ant-design/x-markdown'; import { Alert, Space, Tag, Typography } from 'antd'; import type { AiChatMessage, AiChatMessageStatus, AiToolRun } from './types'; const toolLabels: Record = { search_students: '查询学生', get_student_basic: '读取学生信息', search_classes: '查询班级', get_attendance_summary: '统计考勤', search_rooms: '查询房间', get_room_occupancy_summary: '统计入住', search_bills: '查询账单', get_dashboard_stats: '读取经营概览', }; const markdownComponents = { code: ({ children, lang, block }: ComponentProps) => { const content = String(children ?? '').replace(/\n$/, ''); if (!block) return {content}; return {content}; }, }; const markdownSanitizerConfig = { ALLOW_UNKNOWN_PROTOCOLS: false, FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'form'], FORBID_ATTR: ['style'], }; function ToolStatus({ tool }: { tool: AiToolRun }) { const isRunning = tool.status === 'running'; const isSuccess = tool.status === 'success'; const icon = isRunning ? ( ) : isSuccess ? ( ) : ( ); const color = isRunning ? 'processing' : isSuccess ? 'success' : 'error'; const statusText = isRunning ? '查询中' : isSuccess ? '查询完成' : tool.summary || '查询失败'; return (
{toolLabels[tool.toolName] || tool.toolName} {statusText}
); } export const AiMessageContent: React.FC<{ message: AiChatMessage; status?: AiChatMessageStatus; }> = ({ message, status }) => { if (message.role === 'user') return
{message.content}
; const streaming = status === 'loading' || status === 'updating'; return ( {message.reasoningContent && ( )} {message.toolRuns.length > 0 && (
{message.toolRuns.map((tool) => ( ))}
)} {message.content && ( )} {message.error && } {message.cancelled && 回答已停止}
); };