186 lines
7.0 KiB
JavaScript
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();
|