import React, { useState, useRef } from 'react'; import { UploadCloud, X, Image as ImageIcon, Loader2, Sparkles, FileText } from 'lucide-react'; import { useStore } from '../../store/useStore'; import { useToastStore } from '../layout/Toast'; const parsedData = { id: `node-ai-${Date.now()}`, text: '推理服务', children: [ { id: `node-ai-${Date.now()}-1`, text: '创建推理服务', children: [ { id: `node-ai-${Date.now()}-1-1`, text: '点击创建推理服务按钮', steps: [{ action: '点击创建推理服务按钮', expected: '进入创建推理服务页面' }] }, { id: `node-ai-${Date.now()}-1-2`, text: '查看页面显示', children: [ { id: `node-ai-${Date.now()}-1-2-1`, text: '预期: 左上角显示返回按钮,显示创建推理服务标题' }, { id: `node-ai-${Date.now()}-1-2-2`, text: '预期: 下方显示基本信息、推理类型、规格信息等' }, { id: `node-ai-${Date.now()}-1-2-3`, text: '预期: 右下角显示取消、确认按钮' } ] }, { id: `node-ai-${Date.now()}-1-3`, text: '基本信息', children: [ { id: `node-ai-${Date.now()}-1-3-1`, text: '名称', children: [ { id: `node-ai-${Date.now()}-1-3-1-1`, text: '备注: 为必填项,不允许重复,不允许为空,支持1-64字符' }, { id: `node-ai-${Date.now()}-1-3-1-2`, text: '不输入名称', steps: [{ action: '不输入名称,其他配置合法点击确认', expected: '提示名称不能为空' }] }, { id: `node-ai-${Date.now()}-1-3-1-3`, text: '名称重复', steps: [{ action: '输入重复名称', expected: '提示名称已存在' }] }, { id: `node-ai-${Date.now()}-1-3-1-4`, text: '名称合法', steps: [{ action: '输入合法名称', expected: '推理服务创建成功' }] }, { id: `node-ai-${Date.now()}-1-3-1-5`, text: '输入65位字符', steps: [{ action: '输入65位字符', expected: '第65位字符不允许输入' }] } ] }, { id: `node-ai-${Date.now()}-1-3-2`, text: '描述', children: [ { id: `node-ai-${Date.now()}-1-3-2-1`, text: '备注: 非必填项,200字符以内' }, { id: `node-ai-${Date.now()}-1-3-2-2`, text: '输入为空', steps: [{ action: '输入为空', expected: '创建成功,描述为空' }] }, { id: `node-ai-${Date.now()}-1-3-2-3`, text: '输入201字符', steps: [{ action: '输入201字符', expected: '第201位字符不允许输入' }] } ] }, { id: `node-ai-${Date.now()}-1-3-3`, text: '标签', children: [ { id: `node-ai-${Date.now()}-1-3-3-1`, text: '备注: 最多支持创建20个标签' }, { id: `node-ai-${Date.now()}-1-3-3-2`, text: '不输入标签键,输入标签值', steps: [{ action: '点击确认', expected: '给出提示,标签键不能为空' }] } ] } ] }, { id: `node-ai-${Date.now()}-1-4`, text: '推理类型', children: [ { id: `node-ai-${Date.now()}-1-4-1`, text: '查看类型显示', steps: [{ action: '查看显示', expected: '显示推理服务、分布式推理服务' }] }, { id: `node-ai-${Date.now()}-1-4-2`, text: '多次切换选项', steps: [{ action: '多次切换', expected: '仅支持单选,下方规格随之切换' }] } ] }, { id: `node-ai-${Date.now()}-1-5`, text: '规格信息' }, { id: `node-ai-${Date.now()}-1-6`, text: '基础配置' }, { id: `node-ai-${Date.now()}-1-7`, text: '存储配置' } ] }, { id: `node-ai-${Date.now()}-2`, text: '搜索推理服务' }, { id: `node-ai-${Date.now()}-3`, text: '推理服务列表' } ] }; interface ImportModalProps { onClose: () => void; } export const ImportModal: React.FC = ({ onClose }) => { const [isDragging, setIsDragging] = useState(false); const [isAnalyzing, setIsAnalyzing] = useState(false); const [progress, setProgress] = useState(0); const fileInputRef = useRef(null); const { currentSpaceId, spaceData, importNodes } = useStore(); const { addToast } = useToastStore(); const handleSimulateAI = () => { setIsAnalyzing(true); let current = 0; const interval = setInterval(() => { current += 15; if (current >= 100) { clearInterval(interval); setProgress(100); setTimeout(async () => { // Add parsed data to the tree and persist to backend await importNodes([parsedData]); addToast('AI 识别完毕!已成功导入推理服务用例脑图', 'success'); onClose(); }, 500); } else { setProgress(current); } }, 400); }; const onFileDrop = (e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { handleSimulateAI(); } }; return (
e.stopPropagation()}>

AI 智能导入

{!isAnalyzing ? (
{ e.preventDefault(); setIsDragging(true); }} onDragLeave={() => setIsDragging(false)} onDrop={onFileDrop} onClick={() => fileInputRef.current?.click()} >

点击或将图片拖拽到这里

支持解析 XMind 截图、手绘脑图、Excel 截图

{ if (e.target.files && e.target.files.length > 0) { handleSimulateAI(); } }} />
) : (

AI 正在解析图片逻辑树...

已识别到「推理服务」等 28 个节点

)}
); };