/** * Barcode Scanner Module * يدعم البحث بماسح الباركود مع الصوت والتحديد التلقائي */ class BarcodeScanner { constructor(options = {}) { this.buffer = ''; this.timeout = null; this.scanDelay = options.scanDelay || 100; // وقت الانتظار بين الأحرف this.onScan = options.onScan || (() => {}); this.playSound = options.playSound !== false; // تشغيل الصوت افتراضياً this.autoSelect = options.autoSelect !== false; // التحديد التلقائي افتراضياً this.selectedItems = new Set(); // إنشاء ملف الصوت this.beepSound = this.createBeepSound(); // بدء الاستماع this.init(); } /** * إنشاء صوت البيب */ createBeepSound() { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); return () => { const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.frequency.value = 1000; // تردد الصوت oscillator.type = 'sine'; gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.1); }; } /** * تشغيل صوت النجاح */ playSuccessSound() { if (this.playSound) { this.beepSound(); } } /** * تشغيل صوت الخطأ */ playErrorSound() { if (this.playSound) { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.frequency.value = 400; // تردد منخفض للخطأ oscillator.type = 'sawtooth'; gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.2); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.2); } } /** * بدء الاستماع لأحداث لوحة المفاتيح */ init() { document.addEventListener('keypress', (e) => { // تجاهل إذا كان المستخدم يكتب في حقل إدخال if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') { return; } // إضافة الحرف للبافر if (e.key === 'Enter') { // عند الضغط على Enter، معالجة الباركود if (this.buffer.length > 0) { this.processScan(this.buffer); this.buffer = ''; } } else { this.buffer += e.key; // إعادة تعيين المؤقت clearTimeout(this.timeout); this.timeout = setTimeout(() => { this.buffer = ''; }, this.scanDelay); } }); } /** * معالجة الباركود الممسوح */ processScan(barcode) { console.log('Barcode scanned:', barcode); // البحث عن العنصر const found = this.onScan(barcode); if (found) { this.playSuccessSound(); // إضافة للعناصر المحددة if (this.autoSelect) { this.selectedItems.add(barcode); } // عرض إشعار النجاح this.showNotification('تم المسح بنجاح', 'success'); } else { this.playErrorSound(); this.showNotification('لم يتم العثور على العنصر', 'error'); } } /** * عرض إشعار */ showNotification(message, type = 'success') { const notification = document.createElement('div'); notification.className = `fixed top-4 left-1/2 transform -translate-x-1/2 z-50 px-6 py-3 rounded-lg shadow-lg transition-all duration-300 ${ type === 'success' ? 'bg-green-500 text-white' : 'bg-red-500 text-white' }`; notification.innerHTML = `