// content.js if (isDocumentsPage()) { console.log('[EXT][content] loaded'); } const dataType = 'metaData'; const userDataType = 'userData'; let isProcessing = false; let storageData = {}; function injectScript(file) { console.log('[EXT][content] inject:', file); const script = document.createElement('script'); script.src = chrome.runtime.getURL(file) + '?t=' + Date.now(); script.type = 'text/javascript'; script.async = false; (document.head || document.documentElement).appendChild(script); } window.addEventListener('message', (event) => { if ( event.source !== window || !event.data || event.data.source !== 'medods-extension' || event.data.type !== dataType && event.data.type !== userDataType ) { return; } console.log(`[EXT][content] save ${event.data.type}`); const saveData = { [event.data.type]: event.data.payload, }; chrome.storage.local.set(saveData); }); async function loadStorageData() { storageData = await chrome.storage.local.get(dataType); const userData = await chrome.storage.local.get(userDataType); storageData.userData = userData[userDataType]; } async function updateStorageData() { if (!storageData.metaData || !storageData.userData) { await loadStorageData(); } } async function loadPageData() { console.log(`[EXT][content] renew data for ${dataType}, injecting...`); injectScript(`${dataType}.js`); await loadStorageData(); } function isDocumentsPage() { return ( location.href.includes('/clients/') && location.href.includes('/documents') ); } function isMedodsPage() { return ( document.title === 'MEDODS' ) } // Обработчик сообщений от singing.js window.addEventListener('message', async (event) => { if ( event.source !== window || !event.data || event.data.source !== 'medods-extension' ) { return; } // ОБРАБОТЧИК ПРЕДВАРИТЕЛЬНОЙ ПРОВЕРКИ if (event.data.type === 'preSingingCheck') { // Проверка занятости if (isProcessing) { window.postMessage({ source: 'medods-extension', type: 'preSingingCheckResponse', payload: { success: false, error: 'Система занята, попробуйте позже' } }, '*'); return; } await updateStorageData(); // Получаем данные из storage if (!storageData.metaData) { window.postMessage({ source: 'medods-extension', type: 'preSingingCheckResponse', payload: { success: false, error: 'Данные не загружены' } }, '*'); return; } // Подготавливаем данные для отправки const userData = storageData.userData; const patientId = storageData.metaData.patient.idPatientMis; if (!userData || !patientId) { window.postMessage({ source: 'medods-extension', type: 'preSingingCheckResponse', payload: { success: false, error: 'Не удалось получить данные пользователя или пациента' } }, '*'); return; } const preSingingData = { userId: userData.id, patientId: patientId, docNumbers: event.data.payload.docNumbers }; // Отправляем запрос в background для предварительной проверки chrome.runtime.sendMessage({ action: 'preSingingCheck', data: preSingingData }, (response) => { // Пересылаем результат в singing.js window.postMessage({ source: 'medods-extension', type: 'preSingingCheckResponse', payload: response }, '*'); }); } // ОБРАБОТЧИК ОТПРАВКИ ДОКУМЕНТОВ if (event.data.type === 'sendDocuments') { // Проверка занятости if (isProcessing) { window.postMessage({ source: 'medods-extension', type: 'sendDocumentsResponse', payload: { response: { success: false, status: 'processing', error: 'Система занята, попробуйте позже' } } }, '*'); return; } isProcessing = true; // Немедленный ответ о принятии задачи window.postMessage({ source: 'medods-extension', type: 'sendDocumentsResponse', payload: { response: { success: true, message: 'Документы приняты в обработку', status: 'processing' } } }, '*'); await updateStorageData(); // Фильтруем документы по номерам const filteredDocs = storageData.metaData.docs.filter(doc => event.data.payload.docNumbers.includes(parseInt(doc.number, 10)) ); if (filteredDocs.length === 0) { window.postMessage({ source: 'medods-extension', type: 'sendDocumentsResponse', payload: { response: { success: false, error: 'No matching documents found' } } }, '*'); isProcessing = false; return; } // Собираем все данные для отправки const sendData = { practitioner: storageData.metaData.practitioner, patient: storageData.metaData.patient, recipients: event.data.payload.recipients, docs: filteredDocs, deliveryType: event.data.payload.deliveryType }; // Асинхронная обработка в background setTimeout(() => { chrome.runtime.sendMessage({ action: 'processAndSendDocuments', data: sendData }, (response) => { isProcessing = false; console.log('[EXT][content] Response from background:', response); // Пересылаем результат в singing.js window.postMessage({ source: 'medods-extension', type: 'backgroundProcessingResult', payload: { success: response?.success || false, message: response.message || '', sentCount: response?.sentCount || 0 } }, '*'); }); }, 0); } // ОБРАБОТЧИК ПОДГОТОВКИ ДОКУМЕНТОВ (используем существующие метаданные) if (event.data.type === 'prepareDocuments') { await updateStorageData(); // Проверяем наличие метаданных if (!storageData.metaData) { window.postMessage({ source: 'medods-extension', type: 'prepareDocumentsResponse', payload: { success: false, message: 'Метаданные не загружены' } }, '*'); return; } // Получаем idPatientMis из метаданных const idPatientMis = storageData.metaData.patient.idPatientMis; if (!idPatientMis) { window.postMessage({ source: 'medods-extension', type: 'prepareDocumentsResponse', payload: { success: false, message: 'Не удалось получить idPatientMis из метаданных' } }, '*'); return; } // Отправляем запрос в background для получения документов chrome.runtime.sendMessage({ action: 'getDocuments', data: { idPatientMis: idPatientMis } }, (response) => { // Пересылаем результат в documents.js window.postMessage({ source: 'medods-extension', type: 'prepareDocumentsResponse', payload: response }, '*'); }); } // ОБРАБОТЧИК ПОЛУЧЕНИЯ ДОКУМЕНТА if (event.data.type === 'getDocument') { chrome.runtime.sendMessage({ action: 'getDocument', data: event.data.payload }, (response) => { window.postMessage({ source: 'medods-extension', type: 'getDocumentResponse', payload: response }, '*'); }); } // ОБРАБОТЧИК ПРОВЕРКИ ПРАВ НА ОТЗЫВ if (event.data.type === 'checkRevokePermission') { await updateStorageData(); const hasPermission = String(storageData.userData?.id) === String(event.data.payload.userIdLpu); window.postMessage({ source: 'medods-extension', type: 'checkRevokePermissionResponse', payload: { hasPermission: hasPermission } }, '*'); } // ОБРАБОТЧИК ОТЗЫВА ДОКУМЕНТОВ if (event.data.type === 'revokeDocuments') { chrome.runtime.sendMessage({ action: 'revokeDocuments', data: event.data.payload }, (response) => { window.postMessage({ source: 'medods-extension', type: 'revokeDocumentsResponse', payload: response }, '*'); }); } // ОБРАБОТЧИК ПОВТОРНОЙ ОТПРАВКИ ДОКУМЕНТОВ if (event.data.type === 'resendDocuments') { chrome.runtime.sendMessage({ action: 'resendDocuments', data: event.data.payload }, (response) => { window.postMessage({ source: 'medods-extension', type: 'resendDocumentsResponse', payload: response }, '*'); }); } // ОБРАБОТЧИК ПОИСКА ПОЛУЧАТЕЛЕЙ ПО ТЕЛЕФОНУ if (event.data.type === 'searchRecipients') { await updateStorageData(); const data = { ...event.data.payload, idPatientMis: storageData.metaData.patient.idPatientMis }; // Отправляем запрос в background chrome.runtime.sendMessage({ action: 'searchRecipients', data: data }, (response) => { // Пересылаем результат обратно в singing.js window.postMessage({ source: 'medods-extension', type: 'searchRecipientsResponse', payload: response }, '*'); }); } }); // Основной цикл let documentsActive = false; let medodsActive = false; let lastCheck = 0; function loop(ts) { if (ts - lastCheck > 200) { lastCheck = ts; const now = isDocumentsPage(); if (now && !documentsActive) { console.log('[EXT][content] ENTER documents'); loadPageData() .then(() => { injectScript('documents.js'); injectScript('singing.js'); documentsActive = true; }) .catch(error => { console.error('[EXT][content] Error on enter documents:', error); window.location.reload(); }); } if (!now && documentsActive) { console.log('[EXT][content] LEAVE documents'); documentsActive = false; isProcessing = false; chrome.storage.local.remove(dataType) .then(() => { }) .catch(error => { console.error('[EXT][content] Error on leave documents:', error); window.location.reload(); }); } const medodsNow = isMedodsPage(); if (medodsNow && !medodsActive) { medodsActive = true; injectScript('userData.js'); } } requestAnimationFrame(loop); } // Запуск loop(0);