import { API_CONFIG, DEFAULT_REQUEST_CONFIG } from '@/config/api.js'; class ReportService { constructor() { this.baseURL = API_CONFIG.BASE_URL; this.endpoints = { GENERATE: '/api/parser/report/generate', HISTORY: '/api/parser/report/history', DOWNLOAD: '/api/parser/report/history' }; } /** * Генерирует новый отчёт * @param {Object} reportData - Данные для генерации отчёта * @param {string} reportData.reportTitle - Заголовок отчёта * @param {string} reportData.authorName - Имя автора * @param {string} reportData.companyName - Название компании * @param {string} reportData.startDate - Дата начала периода (ISO 8601) * @param {string} reportData.endDate - Дата окончания периода (ISO 8601) * @param {string} reportData.format - Формат файла (PDF или DOCX) * @returns {Promise} - Файл отчёта */ async generateReport(reportData) { try { const response = await fetch(`${this.baseURL}${this.endpoints.GENERATE}`, { method: 'POST', headers: { ...DEFAULT_REQUEST_CONFIG.headers, Authorization: `Bearer ${this.getAuthToken()}` }, body: JSON.stringify(reportData) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`); } return await response.blob(); } catch (error) { console.error('Ошибка при генерации отчёта:', error); throw error; } } /** * Получает историю отчётов с пагинацией * @param {number} page - Номер страницы (начиная с 0) * @param {number} size - Количество элементов на странице * @param {string} sort - Поле и направление сортировки * @returns {Promise} - Объект с данными пагинации и списком отчётов */ async getReportHistory(page = 0, size = 20, sort = 'createdAt,desc') { try { const params = new URLSearchParams({ page: page.toString(), size: size.toString(), sort: sort }); const response = await fetch(`${this.baseURL}${this.endpoints.HISTORY}?${params}`, { method: 'GET', headers: { ...DEFAULT_REQUEST_CONFIG.headers, Authorization: `Bearer ${this.getAuthToken()}` } }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`); } return await response.json(); } catch (error) { console.error('Ошибка при получении истории отчётов:', error); throw error; } } /** * Скачивает отчёт по ID * @param {string} reportId - ID отчёта * @returns {Promise} - Файл отчёта */ async downloadReport(reportId) { try { const response = await fetch(`${this.baseURL}${this.endpoints.DOWNLOAD}/${reportId}`, { method: 'GET', headers: { Authorization: `Bearer ${this.getAuthToken()}` } }); if (response.status === 404) { throw new Error('Отчёт не найден'); } if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`); } return await response.blob(); } catch (error) { console.error('Ошибка при скачивании отчёта:', error); throw error; } } /** * Скачивает файл в браузере * @param {Blob} blob - Файл для скачивания * @param {string} filename - Имя файла */ downloadFile(blob, filename) { const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); } /** * Извлекает имя файла из заголовка Content-Disposition * @param {Response} response - HTTP ответ * @returns {string} - Имя файла */ getFilenameFromResponse(response) { const contentDisposition = response.headers.get('Content-Disposition'); if (contentDisposition) { const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/); return filenameMatch ? filenameMatch[1] : 'report.pdf'; } return 'report.pdf'; } /** * Форматирует размер файла в читаемый вид * @param {number} bytes - Размер в байтах * @returns {string} - Отформатированный размер */ formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } /** * Получает токен авторизации из localStorage * @returns {string|null} - Токен авторизации */ getAuthToken() { return localStorage.getItem('access_token'); } /** * Обрабатывает ошибки API * @param {Error} error - Ошибка * @returns {string} - Сообщение об ошибке для пользователя */ handleError(error) { if (error.message.includes('404')) { return 'Отчёт не найден'; } else if (error.message.includes('400')) { return 'Неверные данные запроса'; } else if (error.message.includes('401')) { return 'Необходима авторизация'; } else if (error.message.includes('403')) { return 'Доступ запрещён'; } else if (error.message.includes('500')) { return 'Внутренняя ошибка сервера'; } else { return 'Произошла ошибка: ' + error.message; } } } export default new ReportService();