import React, { useState, useCallback } from 'react'; import { useDropzone } from 'react-dropzone'; import Lottie from 'lottie-react'; import uploadAnimation from '../assets/animations/Animation.json'; import uploadProcessingAnimation from '../assets/animations/UploadProcessing.json'; import './FileUploader.css'; import '@mdi/font/css/materialdesignicons.min.css'; import AnalysisResults from './AnalysisResults'; const FileUploader = () => { const [files, setFiles] = useState([]); const [uploading, setUploading] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [error, setError] = useState(''); const [computerCode, setComputerCode] = useState(''); const [isMedicalDocument, setIsMedicalDocument] = useState(false); const [documentType, setDocumentType] = useState(''); const [analysisResults, setAnalysisResults] = useState([]); const [showResults, setShowResults] = useState(false); const [mobileNumber, setMobileNumber] = useState(''); const [verificationCode, setVerificationCode] = useState(''); const [showVerificationCode, setShowVerificationCode] = useState(false); const [timer, setTimer] = useState(0); const [isVerified, setIsVerified] = useState(false); const [verificationError, setVerificationError] = useState(''); const allowedFileTypes = { // فرمت‌های فشرده‌سازی 'application/zip': true, 'application/x-7z-compressed': true, // فرمت‌های آفیس 'application/msword': true, // doc 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': true, // docx 'application/vnd.ms-excel': true, // xls 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': true, // xlsx 'application/vnd.ms-powerpoint': true, // ppt 'application/vnd.openxmlformats-officedocument.presentationml.presentation': true, // pptx // فرمت PDF 'application/pdf': true, // فرمت‌های تصویر 'image/jpeg': true, 'image/png': true, 'image/gif': true, 'image/bmp': true, 'image/webp': true, // فرمت متنی 'text/plain': true, }; const onDrop = useCallback(async (acceptedFiles) => { console.log('Dropped files:', acceptedFiles.map(f => ({ name: f.name, type: f.type }))); const isValidFile = (file) => { // برای فایل‌های ZIP و 7Z فقط برای شماره خاص و در صورت تایید if (file.name.toLowerCase().endsWith('.zip') || file.name.toLowerCase().endsWith('.7z')) { return mobileNumber === '09127169609' && isVerified; } // برای فایل‌های TXT if (file.name.toLowerCase().endsWith('.txt')) { return true; } // برای سایر فایل‌های مجاز return allowedFileTypes[file.type]; }; const invalidFiles = acceptedFiles.filter(file => !isValidFile(file)); if (invalidFiles.length > 0) { if (mobileNumber !== '09127169609' || !isVerified) { setError('فایل‌های ZIP و 7ZIP فقط برای کاربران مجاز قابل آپلود است.'); } else { setError('فقط فایل‌های ZIP، 7ZIP، TXT، اسناد Office و تصاویر مجاز هستند.'); } setTimeout(() => setError(''), 5000); return; } setError(''); setUploading(true); setUploadProgress(0); for (let progress = 0; progress <= 100; progress += 10) { await new Promise(resolve => setTimeout(resolve, 200)); setUploadProgress(progress); } setFiles(prev => [...prev, ...acceptedFiles]); setUploading(false); setUploadProgress(0); }, [mobileNumber, isVerified]); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { 'application/zip': ['.zip'], 'application/x-7z-compressed': ['.7z'], 'application/msword': ['.doc'], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], 'application/vnd.ms-excel': ['.xls'], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'], 'application/vnd.ms-powerpoint': ['.ppt'], 'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx'], 'application/pdf': ['.pdf'], 'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'], 'text/plain': ['.txt'] }, multiple: true }); const getFileIcon = (fileType) => { // فایل‌های فشرده if (fileType === 'application/zip' || fileType === 'application/x-7z-compressed') { return 'mdi mdi-zip-box'; } // فایل‌های Word if (fileType === 'application/msword' || fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { return 'mdi mdi-microsoft-word'; } // فایل‌های Excel if (fileType === 'application/vnd.ms-excel' || fileType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { return 'mdi mdi-microsoft-excel'; } // فایل‌های PowerPoint if (fileType === 'application/vnd.ms-powerpoint' || fileType === 'application/vnd.openxmlformats-officedocument.presentationml.presentation') { return 'mdi mdi-microsoft-powerpoint'; } // فایل PDF if (fileType === 'application/pdf') { return 'mdi mdi-file-pdf-box'; } // فایل‌های تصویری if (fileType.startsWith('image/')) { return 'mdi mdi-file-image'; } // فایل‌های اجرایی if (fileType === 'application/x-msdownload') { return 'mdi mdi-application'; } return 'mdi mdi-file-document'; }; const getFileColor = (fileType) => { // فایل‌های فشرده if (fileType === 'application/zip' || fileType === 'application/x-7z-compressed') { return 'bg-primary'; } // فایل‌های Word if (fileType === 'application/msword' || fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { return 'bg-info'; } // فایل‌های Excel if (fileType === 'application/vnd.ms-excel' || fileType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { return 'bg-success'; } // فایل‌های PowerPoint if (fileType === 'application/vnd.ms-powerpoint' || fileType === 'application/vnd.openxmlformats-officedocument.presentationml.presentation') { return 'bg-warning'; } // فایل PDF if (fileType === 'application/pdf') { return 'bg-danger'; } // فایل‌های تصویری if (fileType.startsWith('image/')) { return 'bg-primary'; } // فایل‌های اجرایی if (fileType === 'application/x-msdownload') { return 'bg-danger'; } return 'bg-secondary'; }; const handleRemoveFile = (indexToRemove) => { setFiles(prevFiles => prevFiles.filter((_, index) => index !== indexToRemove)); }; const handleComputerCodeChange = (e) => { const value = e.target.value.toUpperCase(); // برای اولین کاراکتر فقط S مجاز است if (value.length === 1) { if (value === 'S') { setComputerCode(value); setDocumentType('manual'); } return; } // برای دومین کاراکتر فقط 1 یا 2 مجاز است if (value.length === 2) { if (value.startsWith('S') && ['1', '2'].includes(value[1])) { setComputerCode(value); setDocumentType('manual'); } return; } if (value.length <= 5) { const regex = /^S[12]\d{0,3}$/; if (regex.test(value)) { setComputerCode(value); setDocumentType('manual'); } } }; const uploadFile = async (file) => { console.log('Uploading file:', file.name); const formData = new FormData(); formData.append('files', file); const url = new URL('http://fileshare.ikid.ir:44310/api/FileAnalysis/upload'); url.searchParams.append('computerCode', computerCode); url.searchParams.append('documentType', documentType); url.searchParams.append('phoneNumber', mobileNumber); try { const response = await fetch(url.toString(), { method: 'POST', body: formData, credentials: 'include' }); if (!response.ok) { const errorText = await response.text(); console.error('Server error:', errorText); throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); console.log('Server Response:', result); // بررسی نتیجه اولین آیتم از آرایه پاسخ const scanResult = result[0]; return { ...scanResult, fileName: file.name, status: scanResult.isMalicious ? 'malicious' : scanResult.isClean ? 'clean' : 'error', threatDetails: scanResult.detectedThreats.length > 0 ? { count: scanResult.detectedThreats.length, name: scanResult.threatName } : null }; } catch (error) { console.error('Error in uploadFile:', error); return { fileName: file.name, status: 'error', isSuccess: false, errorMessage: error.message }; } }; const handleSubmit = async (e) => { e.preventDefault(); console.log('Submit button clicked'); if (files.length === 0) { setError('لطفاً حداقل یک فایل انتخاب کنید'); setTimeout(() => setError(''), 5000); return; } if (!computerCode) { setError('لطفاً کد کامپیوتر را وارد کنید'); setTimeout(() => setError(''), 5000); return; } if (!documentType) { setError('نوع سند مشخص نشده است'); setTimeout(() => setError(''), 5000); return; } setUploading(true); setShowResults(true); try { // کپی از آرایه فایل‌ها می‌گیریم تا بتوانیم در حلقه تغییرش دهیم const filesToProcess = [...files]; while (filesToProcess.length > 0) { const file = filesToProcess[0]; // اولین فایل از لیست const result = await uploadFile(file); // اضافه کردن نتیجه به لیست نتایج setAnalysisResults(prevResults => [...prevResults, result]); // حذف فایل از لیست اصلی فایل‌ها setFiles(prevFiles => prevFiles.filter(f => f !== file)); // حذف فایل از لیست موقت filesToProcess.shift(); // آپدیت درصد پیشرفت setUploadProgress(((files.length - filesToProcess.length) / files.length) * 100); } } catch (error) { console.error('Error in handleSubmit:', error); } setUploading(false); setUploadProgress(0); }; const handleMobileNumberChange = (e) => { const value = e.target.value; // فقط اجازه ورود اعداد if (/^\d*$/.test(value)) { if (value === '' || value === '0' || value.startsWith('09')) { setMobileNumber(value); } } }; const handleVerificationCodeChange = (e) => { const value = e.target.value; // فقط اجازه ورود 6 رقم عدد if (/^\d{0,6}$/.test(value)) { setVerificationCode(value); } }; const handleSendSMS = async () => { if (mobileNumber.length === 11) { try { const response = await fetch('http://fileshare.ikid.ir:44310/api/SmsVerification/send', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ phoneNumber: mobileNumber }), credentials: 'include' }); if (!response.ok) { throw new Error('خطا در ارسال پیامک'); } setShowVerificationCode(true); setTimer(60); setVerificationError(''); // Start countdown timer const interval = setInterval(() => { setTimer((prevTimer) => { if (prevTimer <= 1) { clearInterval(interval); return 0; } return prevTimer - 1; }); }, 1000); } catch (error) { setVerificationError('خطا در ارسال پیامک. لطفا مجددا تلاش کنید.'); } } }; const handleVerifyCode = async () => { try { const response = await fetch('http://fileshare.ikid.ir:44310/api/SmsVerification/verify', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ phoneNumber: mobileNumber, code: verificationCode }), credentials: 'include' }); const data = await response.json(); if (!response.ok) { throw new Error(data.message || 'کد تایید نامعتبر است'); } setIsVerified(true); setVerificationError(''); setTimer(0); } catch (error) { setVerificationError(error.message); setIsVerified(false); } }; return (

واحد سیستم‌ها و انفورماتیک

اداره مهندسی سامانه‌های کاربردی

سامانه انتقال امن اشتراک فایل

برای انتخاب فایل روی باکس بالا کلیک کنید یا فایل خود را اینجا رها کنید

{uploading && ( <>
در حال آپلود... {uploadProgress}%
)} {files.length > 0 && (
فایل های پیوست شده
{files.map((file, index) => ( {file.name} ))}
)} {error && (
{error}
)} {!isMedicalDocument && (
)}
{!isVerified && ( )}
{showVerificationCode && (
)} {verificationError && (
{verificationError}
)}
{/* دکمه جدید ارسال */}
{showResults && (
)}
); }; export default FileUploader;