// background.js console.log('✅ Medods N3.Health service worker started'); let isProcessing = false; // Таблица статусов const statuses = { 201: { name: "Создан", description: "Документ создан через API, готов к обработке", category: "processing" }, 202: { name: "Отправлен на подписание", description: "Документ отправлен получателю", category: "processing" }, 203: { name: "Просмотрел", description: "Документ просмотрен получателем", category: "processing" }, 204: { name: "Подписал", description: "Документ подписан получателем", category: "completed" }, 205: { name: "Отказался", description: "Получатель отказался от подписания", category: "error" }, 206: { name: "Срок для подписания истек", description: "Срок действия ссылки истек до момента проставления подписи или отказа", category: "error" }, 207: { name: "Ожидание действий", description: "Ожидание действий от всех получателей", category: "processing" }, 208: { name: "Успешно. Подписан всеми — обработка", description: "Все получатели подписали, документ обрабатывается", category: "processing" }, 209: { name: "Успешно. Подписан не всеми — обработка", description: "Не все получатели подписали, документ обрабатывается", category: "processing" }, 210: { name: "Завершено. Подписано всеми", description: "Все получатели подписали, документ сохранен", category: "completed" }, 211: { name: "Завершено. Подписано не всеми", description: "Не все получатели подписали, документ сохранен", category: "completed" }, 212: { name: "Отменен для получателя", description: "Подписание отменено для конкретного получателя", category: "error" }, 213: { name: "Завершено. Отменено для всех", description: "Подписание отменено для всех получателей", category: "completed" }, 214: { name: "Успешно. Требуется подписание УКЭП", description: "Требуется подписание УКЭП медицинского работника", category: "processing" }, 498: { name: "Завершено. Отклонено всеми", description: "Все получатели отказались от подписания", category: "error" }, 499: { name: "Завершено. Истекло для всех", description: "Срок ссылки истек для всех получателей", category: "error" }, 500: { name: "Ошибка обработки", description: "Ошибка во время обработки документа", category: "error" }, 501: { name: "Ошибка доставки получателю", description: "Произошла ошибка при доставке конкретному получателю", category: "error" } }; function enrichStatuses(data) { if (!Array.isArray(data)) return data; data.forEach(singing => { if (Array.isArray(singing.statuses)) { singing.statuses.forEach(status => { const statusInfo = statuses[status.status] || { name: "Неизвестный статус", description: `Статус ${status.status}`, category: "error" }; status.category = statusInfo.category; status.description = statusInfo.description; status.name = statusInfo.name; }); } }); return data; } async function sendDataToServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/singing`; console.log('🌐 Отправка данных на сервер:', url); const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(30000) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error: ${response.status} - ${errorText}`); } const result = await response.json(); return result; } catch (error) { console.error('❌ Ошибка отправки на сервер:', error); throw error; } } async function processAndSendDocuments(data, sender) { if (isProcessing) { throw new Error('Already processing documents'); } isProcessing = true; try { const serverResponse = await sendDataToServer(data); const isSuccess = serverResponse && serverResponse.status === 'SUCCESS'; return { success: isSuccess, message: serverResponse.message || 'Неизвестная ошибка', sentCount: data.docs?.length || 0 }; } catch (error) { console.error('❌ Ошибка обработки документов:', error); return { success: false, message: error.message || 'Ошибка обработки документов', error: error.toString() }; } finally { isProcessing = false; } } chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === 'processAndSendDocuments') { setTimeout(async () => { try { const result = await processAndSendDocuments(message.data, sender); sendResponse({ success: result.success, message: result.message, sentCount: result.sentCount, }); } catch (error) { sendResponse({ success: false, message: error.message || 'Неизвестная ошибка', error: error.toString() }); } }, 0); return true; } if (message.action === 'bgLog') { try { console.log(`[EXT][${message.sender}]`, ...message.payload); } catch (e) { } } if (message.action === 'preSingingCheck') { setTimeout(async () => { try { const result = await preSingingCheck(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Неизвестная ошибка', error: error.toString() }); } }, 0); return true; } if (message.action === 'getDocuments') { setTimeout(async () => { try { const result = await getDocumentsFromServer(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка получения документов', error: error.toString() }); } }, 0); return true; } if (message.action === 'getDocument') { setTimeout(async () => { try { const result = await getDocumentFromServer(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка получения документа' }); } }, 0); return true; } if (message.action === 'revokeDocuments') { setTimeout(async () => { try { const result = await revokeDocumentsOnServer(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка отзыва документов' }); } }, 0); return true; } if (message.action === 'resendDocuments') { setTimeout(async () => { try { const result = await resendDocumentsOnServer(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка повторной отправки документов' }); } }, 0); return true; } // Новый обработчик для получения статусов из popup if (message.action === 'getStatuses') { setTimeout(async () => { try { const result = await getStatusesFromServer(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка получения статусов', error: error.toString() }); } }, 0); return true; } // Обработчик расширенного поиска if (message.action === 'advancedSearch') { setTimeout(async () => { try { const result = await advancedSearch(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка расширенного поиска', error: error.toString() }); } }, 0); return true; } if (message.action === 'searchRecipients') { setTimeout(async () => { try { const result = await searchRecipients(message.data); sendResponse(result); } catch (error) { sendResponse({ success: false, message: error.message || 'Ошибка поиска получателей', error: error.toString(), data: [] }); } }, 0); return true; } }); // Функция расширенного поиска async function advancedSearch(data) { if (isProcessing) { throw new Error('Already processing documents'); } isProcessing = true; try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/advanced-search`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(30000) }); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } let result = await response.json(); result = result.data || []; // Обогащаем статусы если есть данные if (Array.isArray(result)) { result = enrichStatuses(result); } return { success: true, data: result || [] }; } catch (error) { console.error('Advanced search error:', error); return { success: false, message: error.message || 'Ошибка расширенного поиска', error: error.toString() }; } finally { isProcessing = false; } } async function preSingingCheck(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/pre_singing`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(15000) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error: ${response.status} - ${errorText}`); } const result = await response.json(); return { success: true, data: result }; } catch (error) { return { success: false, message: error.message || 'Ошибка предварительной проверки', error: error.toString() }; } } async function getDocumentsFromServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/documents`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ idPatientMis: data.idPatientMis }), signal: AbortSignal.timeout(30000) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error: ${response.status} - ${errorText}`); } const result = await response.json(); if (result.status === 'SUCCESS' && Array.isArray(result.data.singings)) { result.data.singings = enrichStatuses(result.data.singings); } return { success: result.status === 'SUCCESS', data: result.data || [], message: result.message || 'Документы получены успешно' }; } catch (error) { return { success: false, message: error.message || 'Ошибка получения документов', error: error.toString() }; } } // Новая функция для получения статусов async function getStatusesFromServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/statuses`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data || {}), signal: AbortSignal.timeout(30000) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error: ${response.status} - ${errorText}`); } let result = await response.json(); if (Array.isArray(result)) { result = enrichStatuses(result); } return { success: true, data: result || [] }; } catch (error) { return { success: false, message: error.message || 'Ошибка получения статусов', error: error.toString() }; } } chrome.runtime.onInstalled.addListener((details) => { if (details.reason === 'install') { chrome.storage.local.set({ esiaAuth: false, trackingIds: [], serverIp: '', serverPort: 8000, processingStatus: 'idle' }); } }); async function getDocumentFromServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/document`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(30000) }); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } const result = await response.json(); return { success: true, data: result.data }; } catch (error) { return { success: false, message: error.message }; } } async function revokeDocumentsOnServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/revoke`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(30000) }); const result = await response.json(); return { success: result.status === 'SUCCESS', message: result.message }; } catch (error) { return { success: false, message: error.message }; } } async function resendDocumentsOnServer(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/resend`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(30000) }); const result = await response.json(); return { success: result.status === 'SUCCESS', message: result.message }; } catch (error) { return { success: false, message: error.message }; } } async function searchRecipients(data) { try { const settings = await chrome.storage.local.get(['serverIp', 'serverPort']); if (!settings.serverIp || !settings.serverPort) { throw new Error('Server IP or port not configured'); } const url = `http://${settings.serverIp}:${settings.serverPort}/api/search-recipients`; console.log('[background] Поиск получателей:', url, data); const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data), signal: AbortSignal.timeout(15000) // 15 секунд таймаут }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error: ${response.status} - ${errorText}`); } const result = await response.json(); let recipients = result; if (result.data && Array.isArray(result.data)) { recipients = result.data; } else if (!Array.isArray(result)) { recipients = []; } return { success: true, data: recipients }; } catch (error) { console.error('[background] Ошибка поиска получателей:', error); return { success: false, message: error.message || 'Ошибка поиска получателей', error: error.toString(), data: [] }; } } console.log('✅ Background script loaded');