Files
marketing/src/service/ReportService.js
T
2025-09-22 16:26:38 +05:00

186 lines
7.0 KiB
JavaScript

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<Blob>} - Файл отчёта
*/
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<Object>} - Объект с данными пагинации и списком отчётов
*/
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<Blob>} - Файл отчёта
*/
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();