'use client'; import React, { useCallback, useState } from 'react'; import { useTusUpload } from '../hooks/useTusUpload'; interface UploadedFile { fileId: string; fileName: string; url: string; } export function FileUpload() { const { uploadProgress, isUploading, uploadError, handleFileUpload, getFileUrlByFileId, serverUrl } = useTusUpload(); const [uploadedFiles, setUploadedFiles] = useState([]); const [dragOver, setDragOver] = useState(false); // 处理文件选择 const handleFileSelect = useCallback( async (files: FileList | null) => { if (!files || files.length === 0) return; for (let i = 0; i < files.length; i++) { const file = files[i]; if (!file) continue; try { const result = await handleFileUpload( file, (result) => { console.log('Upload success:', result); setUploadedFiles((prev) => [ ...prev, { fileId: result.fileId, fileName: result.fileName, url: result.url, }, ]); }, (error) => { console.error('Upload error:', error); }, ); } catch (error) { console.error('Upload failed:', error); } } }, [handleFileUpload], ); // 处理拖拽上传 const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); setDragOver(false); handleFileSelect(e.dataTransfer.files); }, [handleFileSelect], ); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(true); }, []); const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(false); }, []); // 处理文件输入 const handleInputChange = useCallback( (e: React.ChangeEvent) => { handleFileSelect(e.target.files); }, [handleFileSelect], ); // 复制链接到剪贴板 const copyToClipboard = useCallback(async (url: string) => { try { await navigator.clipboard.writeText(url); alert('链接已复制到剪贴板!'); } catch (error) { console.error('Failed to copy:', error); } }, []); return (

文件上传

{/* 服务器信息 */}

服务器地址: {serverUrl}

{/* 拖拽上传区域 */}

拖拽文件到这里,或者

支持多文件上传,TUS 协议支持断点续传

{/* 上传进度 */} {isUploading && (
上传中... {uploadProgress}%
)} {/* 错误信息 */} {uploadError && (

上传失败: {uploadError}

)} {/* 已上传文件列表 */} {uploadedFiles.length > 0 && (

已上传文件

{uploadedFiles.map((file, index) => (

{file.fileName}

文件ID: {file.fileId}

查看
))}
)} {/* 使用说明 */}

使用说明:

  • • 支持拖拽和点击上传
  • • 使用 TUS 协议,支持大文件和断点续传
  • • 上传完成后可以通过链接直接访问文件
  • • 图片和 PDF 会在浏览器中直接显示
  • • 其他文件类型会触发下载
); }