From d808b9acffb58b3584e65c313f9c5810e8d29fec Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 Oct 2025 21:06:01 +0500 Subject: [PATCH] . --- src/config/api.js | 2 +- src/service/ReportService.js | 76 +++++-- src/views/reports/ReportGenerator.vue | 191 ++++++------------ src/views/reports/ReportManager.vue | 150 ++++++-------- ...API генерации исследовательских отчётов.md | 188 +++++++++++++++++ 5 files changed, 384 insertions(+), 223 deletions(-) create mode 100644 Руководство по API генерации исследовательских отчётов.md diff --git a/src/config/api.js b/src/config/api.js index 2305e61..fdd5bec 100644 --- a/src/config/api.js +++ b/src/config/api.js @@ -25,7 +25,7 @@ export const API_CONFIG = { PARSERS_HEALTH: '/api/parser/health/parsers', // ReportController - Генерация и управление отчётами - REPORT_GENERATE: '/api/parser/report/generate', + REPORT_GENERATE: '/api/parser/report', REPORT_HISTORY: '/api/parser/report/history', REPORT_DOWNLOAD: '/api/parser/report/history', diff --git a/src/service/ReportService.js b/src/service/ReportService.js index 24f02f6..1ba8125 100644 --- a/src/service/ReportService.js +++ b/src/service/ReportService.js @@ -4,22 +4,21 @@ 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' + GENERATE: API_CONFIG.ENDPOINTS.REPORT_GENERATE, + HISTORY: API_CONFIG.ENDPOINTS.REPORT_HISTORY, + DOWNLOAD: API_CONFIG.ENDPOINTS.REPORT_DOWNLOAD }; } /** * Генерирует новый отчёт * @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} - Файл отчёта + * @param {string} reportData.query - Тема для исследования + * @param {string} reportData.lang - Язык отчёта ("ru", "en") + * @param {number} reportData.depth - Глубина исследования (1-5) + * @param {number} reportData.breadth - Широта исследования (2-10) + * @param {string} reportData.report_type - Тип отчёта ("report", "answer") + * @returns {Promise} - PDF-файл с отчётом */ async generateReport(reportData) { try { @@ -37,7 +36,24 @@ class ReportService { throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`); } - return await response.blob(); + const contentType = response.headers.get('Content-Type') || ''; + + // Если пришёл PDF/бинарный файл — вернуть как blob + if (contentType.includes('application/pdf') || contentType.includes('application/octet-stream')) { + const blob = await response.blob(); + const filename = this.getFilenameFromResponse(response) || 'report.pdf'; + return { type: 'blob', blob, filename }; + } + + // В противном случае — попробовать прочитать текст/JSON сообщение + const text = await response.text(); + try { + const json = JSON.parse(text); + const message = json.message || text || 'Операция выполнена'; + return { type: 'message', message }; + } catch (_) { + return { type: 'message', message: text || 'Операция выполнена' }; + } } catch (error) { console.error('Ошибка при генерации отчёта:', error); throw error; @@ -79,6 +95,40 @@ class ReportService { } } + /** + * Генерирует и скачивает отчёт + * @param {Object} reportData - Данные для генерации отчёта + * @param {string} reportData.query - Тема для исследования + * @param {string} reportData.lang - Язык отчёта ("ru", "en") + * @param {number} reportData.depth - Глубина исследования (1-5) + * @param {number} reportData.breadth - Широта исследования (2-10) + * @param {string} reportData.report_type - Тип отчёта ("report", "answer") + * @returns {Promise} + */ + async generateAndDownloadReport(reportData) { + try { + const result = await this.generateReport(reportData); + + if (result && result.type === 'blob') { + // Имя из ответа или сгенерированное + const filename = result.filename || `research_report_${new Date().toISOString().replace(/[:.]/g, '-')}.pdf`; + this.downloadFile(result.blob, filename); + return { downloaded: true }; + } + + // Если пришло сообщение — вернуть его вызывающей стороне + if (result && result.type === 'message') { + return { downloaded: false, message: result.message }; + } + + // Неожиданный формат + return { downloaded: false, message: 'Неизвестный ответ сервера' }; + } catch (error) { + console.error('Ошибка при генерации и скачивании отчёта:', error); + throw error; + } + } + /** * Скачивает отчёт по ID * @param {string} reportId - ID отчёта @@ -169,13 +219,15 @@ class ReportService { if (error.message.includes('404')) { return 'Отчёт не найден'; } else if (error.message.includes('400')) { - return 'Неверные данные запроса'; + return 'Некорректные параметры запроса'; } else if (error.message.includes('401')) { return 'Необходима авторизация'; } else if (error.message.includes('403')) { return 'Доступ запрещён'; } else if (error.message.includes('500')) { return 'Внутренняя ошибка сервера'; + } else if (error.message.includes('504')) { + return 'Таймаут при обращении к deep-research API. Попробуйте позже'; } else { return 'Произошла ошибка: ' + error.message; } diff --git a/src/views/reports/ReportGenerator.vue b/src/views/reports/ReportGenerator.vue index 1eb33eb..8da5948 100644 --- a/src/views/reports/ReportGenerator.vue +++ b/src/views/reports/ReportGenerator.vue @@ -13,62 +13,39 @@
- - - {{ errors.reportTitle }} + + + {{ errors.query }}
- - - {{ errors.authorName }} + +
- - - {{ errors.companyName }} + +
- - - {{ errors.startDate }} + + + Текущее значение: {{ formData.depth }}
- - - {{ errors.endDate }} -
-
- -
-
- - -
-
- -
-
- - -
-
- -
-
- -