import React from 'react'; import { Input, Upload, message, Button, Spin, Tag } from 'antd'; import type { UploadFile, RcFile } from 'antd/es/upload/interface'; import { PictureOutlined, SendOutlined, LoadingOutlined, SearchOutlined } from '@ant-design/icons'; import { postInput, postInputImage, getPeoples } from '../apis'; import './InputPanel.css'; const { TextArea } = Input; interface InputPanelProps { onResult?: (data: unknown) => void; showUpload?: boolean; // 是否显示图片上传按钮,默认显示 mode?: 'input' | 'search' | 'batch-image'; // 输入面板工作模式,新增批量图片模式 } const InputPanel: React.FC = ({ onResult, showUpload = true, mode = 'input' }) => { const [value, setValue] = React.useState(''); const [fileList, setFileList] = React.useState([]); const [loading, setLoading] = React.useState(false); // 批量模式不保留文本内容 // 不需要扩展名重命名,展示 image-序号 const send = async () => { const trimmed = value.trim(); const hasText = trimmed.length > 0; const hasImage = showUpload && fileList.length > 0; // 搜索模式:仅以文本触发检索,忽略图片 if (mode === 'search') { if (!hasText) { message.info('请输入内容'); return; } setLoading(true); try { console.log('检索文本:', trimmed); const response = await getPeoples({ search: trimmed, top_k: 10 }); console.log('检索响应:', response); if (response.error_code === 0) { message.success('已获取检索结果'); onResult?.(response.data || []); // 清空输入 setValue(''); setFileList([]); } else { message.error(response.error_info || '检索失败,请重试'); } } catch (error) { console.error('检索调用失败:', error); message.error('网络错误,请检查连接后重试'); } finally { setLoading(false); } return; } // 批量图片模式:循环调用图片识别 API if (mode === 'batch-image') { if (!hasImage) { message.info('请添加至少一张图片'); return; } setLoading(true); try { const results: unknown[] = []; for (let i = 0; i < fileList.length; i++) { const f = fileList[i].originFileObj as RcFile | undefined; if (!f) continue; const resp = await postInputImage(f); if (resp && resp.error_code === 0 && resp.data) { results.push(resp.data); } } if (results.length > 0) { message.success(`已识别 ${results.length} 张图片`); onResult?.(results); } else { message.error('识别失败,请检查图片后重试'); } setValue(''); setFileList([]); } catch (error) { console.error('批量识别失败:', error); message.error('网络错误,请稍后重试'); } finally { setLoading(false); } return; } setLoading(true); try { let response; // 如果有图片,优先处理图片上传 if (hasImage) { const file = fileList[0].originFileObj as RcFile | undefined; if (!file) { message.error('图片文件无效,请重新选择'); return; } console.log('上传图片:', file.name); response = await postInputImage(file); } else { // 只有文本时,调用文本处理 API console.log('处理文本:', trimmed); response = await postInput(trimmed); } console.log('API响应:', response); if (response.error_code === 0 && response.data) { message.success('处理完成!已自动填充表单'); // 将结果传递给父组件 onResult?.(response.data); message.info('输入已清空'); // 清空输入 setValue(''); setFileList([]); } else { message.error(response.error_info || '处理失败,请重试'); } } catch (error) { console.error('API调用失败:', error); message.error('网络错误,请检查连接后重试'); } finally { setLoading(false); } }; const onKeyDown = (e: React.KeyboardEvent) => { if (loading) return; // 加载中时禁用快捷键 if (e.key === 'Enter') { if (e.shiftKey) { // Shift+Enter 换行(保持默认行为) return; } // Enter 发送 e.preventDefault(); send(); } }; // 处理剪贴板粘贴图片:将图片加入上传列表,复用现有上传流程 const onPaste = (e: React.ClipboardEvent) => { if (!showUpload || loading) return; const items = e.clipboardData?.items; if (!items || items.length === 0) return; if (mode === 'batch-image') { const newEntries: UploadFile[] = []; for (let i = 0; i < items.length; i++) { const item = items[i]; if (item.kind === 'file') { const file = item.getAsFile(); if (file && file.type.startsWith('image/')) { const entry: UploadFile = { uid: `${Date.now()}-${Math.random()}`, name: 'image', status: 'done', originFileObj: file as unknown as RcFile, }; newEntries.push(entry); } } } if (newEntries.length > 0) { e.preventDefault(); setValue(''); setFileList([...fileList, ...newEntries]); message.success(`已添加 ${newEntries.length} 张剪贴板图片`); } } else { // 单图模式:仅添加第一张并替换已有 let firstImage: File | null = null; for (let i = 0; i < items.length; i++) { const item = items[i]; if (item.kind === 'file') { const file = item.getAsFile(); if (file && file.type.startsWith('image/')) { firstImage = file; break; } } } if (firstImage) { e.preventDefault(); setValue(''); const item: UploadFile = { uid: `${Date.now()}-${Math.random()}`, name: 'image', status: 'done', originFileObj: firstImage as unknown as RcFile, }; setFileList([item]); message.success('已添加剪贴板图片'); } } }; return (
} > {/** 根据禁用状态动态占位符文案 */} {(() => { return null; })()}