# Документация для фронтенда: Генерация изображений для постов ## Обзор изменений В систему добавлена автоматическая генерация изображений для постов в социальных сетях. Теперь при создании маркетинговой стратегии для каждого поста автоматически генерируется уникальное изображение с помощью OpenAI DALL-E API. Изображения сохраняются в MinIO и прикрепляются к постам при публикации в Facebook. --- ## Новые поля в API ### 1. PostCalendarItem (Календарь постов) В объекте `PostCalendarItem` добавлены два новых поля для работы с изображениями: | Поле | Тип | Описание | Обязательное | | --------------- | ------ | ------------------------------------------------------------ | ------------ | | `imageUrl` | string | Имя файла изображения (используется для получения через API) | Нет | | `imageFilename` | string | Имя файла изображения | Нет | **Важно:** - Поля могут быть `null`, если генерация изображения не удалась - В этом случае пост публикуется без изображения - Оба поля содержат одинаковое значение (имя файла) - Для получения изображения используйте API эндпоинт `/api/marketing/analysis/images/{imageFilename}` ### 2. PostingTask (Задачи публикации) В объекте `PostingTask` также добавлены поля для изображений: | Поле | Тип | Описание | Обязательное | | --------------- | ------ | ------------------------------------------------------------ | ------------ | | `imageUrl` | string | Имя файла изображения (используется для получения через API) | Нет | | `imageFilename` | string | Имя файла изображения | Нет | --- ## Изменения в API эндпоинтах ### GET `/api/marketing/strategy/{strategyId}` Ответ теперь включает поля изображений в каждом элементе календаря постов. #### Пример ответа ```json { "success": true, "data": { "strategyId": "507f1f77bcf86cd799439011", "analysisId": "507f1f77bcf86cd799439012", "status": "completed", "strategy": { "postCalendar": [ { "publishDate": "2024-01-15T10:00:00", "platform": "Facebook", "contentType": "пост", "theme": "Презентация нового продукта", "postText": "Мы рады представить наш новый продукт...", "hashtags": ["#новинка", "#продукт", "#маркетинг"], "publishTime": "10:00", "imageUrl": "post_image_1705312800000_1234567890.png", "imageFilename": "post_image_1705312800000_1234567890.png" } ] } } } ``` ### GET `/api/marketing/analysis/{analysisId}/strategy` Аналогично, ответ включает поля изображений в календаре постов. --- ## Получение изображений ### Через бэкенд API Все изображения должны получаться через бэкенд API. Прямой доступ к MinIO с фронтенда не предусмотрен. #### Эндпоинт для получения изображения **GET** `/api/marketing/analysis/images/{imageFilename}` Возвращает изображение поста в формате PNG. #### Параметры пути | Параметр | Тип | Описание | | --------------- | ------ | --------------------- | | `imageFilename` | string | Имя файла изображения | #### Заголовки запроса | Заголовок | Тип | Обязательный | Описание | | --------------- | ------ | ------------ | ------------------------------------ | | `Authorization` | string | Да | JWT токен в формате `Bearer {token}` | #### Пример запроса ```javascript const imageUrl = `/api/marketing/analysis/images/${post.imageFilename}`; fetch(imageUrl, { headers: { Authorization: `Bearer ${token}`, }, }) .then((response) => { if (response.ok) { return response.blob(); } throw new Error('Failed to load image'); }) .then((blob) => { const imageObjectUrl = URL.createObjectURL(blob); // Используйте imageObjectUrl для отображения }); ``` #### Пример ответа - **Успешный ответ (200 OK):** - Content-Type: `image/png` - Body: бинарные данные изображения PNG - **Ошибка 401 Unauthorized:** - Токен отсутствует или невалиден - **Ошибка 404 Not Found:** - Изображение не найдено на сервере - **Ошибка 500 Internal Server Error:** - Внутренняя ошибка сервера при загрузке изображения #### Кэширование Сервер возвращает заголовок `Cache-Control: public, max-age=3600`, что позволяет браузеру кэшировать изображения на 1 час. --- ## Рекомендации по отображению ### 1. Проверка наличия изображения Всегда проверяйте наличие изображения перед отображением: ```javascript // Пример на JavaScript/TypeScript const PostCard = ({ post, apiBaseUrl, authToken }) => { const hasImage = post.imageUrl && post.imageFilename; const imageUrl = hasImage ? `${apiBaseUrl}/api/marketing/analysis/images/${post.imageFilename}` : null; return (

{post.theme}

{post.postText}

{imageUrl ? ( {post.theme} { // Fallback если изображение не загрузилось e.target.style.display = 'none'; }} // Если требуется авторизация, используйте fetch с заголовками /> ) : (
Изображение не сгенерировано
)}
{post.hashtags.map((tag) => ( #{tag} ))}
); }; ``` ### 2. Обработка ошибок загрузки Всегда предусматривайте fallback для случаев, когда: - Изображение не сгенерировано (`imageUrl` = `null`) - Изображение не найдено на сервере - Ошибка при загрузке изображения ```javascript const [imageError, setImageError] = useState(false); const getImageUrl = (imageFilename) => { if (!imageFilename) return null; return `${API_BASE_URL}/api/marketing/analysis/images/${imageFilename}`; }; const handleImageError = () => { setImageError(true); }; return ( <> {post.imageUrl && !imageError ? ( {post.theme} ) : (
Изображение недоступно
)} ); ``` ### 3. Оптимизация загрузки Рекомендуется использовать lazy loading для изображений: ```javascript {post.theme} ``` ### 4. Размеры изображений Изображения генерируются в размере **1024x1024 пикселей** (квадратные). При отображении учитывайте это при настройке CSS: ```css .post-image { width: 100%; max-width: 512px; height: auto; border-radius: 8px; object-fit: cover; } ``` --- ## Примеры использования ### React компонент для отображения поста ```typescript import React, { useState } from 'react'; interface PostCalendarItem { publishDate: string; platform: string; contentType: string; theme: string; postText: string; hashtags: string[]; publishTime: string; imageUrl?: string | null; imageFilename?: string | null; } interface PostCardProps { post: PostCalendarItem; apiBaseUrl: string; } const PostCard: React.FC = ({ post, apiBaseUrl }) => { const [imageError, setImageError] = useState(false); const getImageUrl = (): string | null => { if (!post.imageFilename) return null; return `${apiBaseUrl}/api/marketing/analysis/images/${post.imageFilename}`; }; const imageUrl = getImageUrl(); return (
{post.platform} {post.contentType} {post.publishTime}

{post.theme}

{imageUrl && !imageError ? (
{post.theme} setImageError(true)} />
) : (

Изображение не сгенерировано

)}

{post.postText}

{post.hashtags.map((tag, index) => ( {tag.startsWith('#') ? tag : `#${tag}`} ))}
{new Date(post.publishDate).toLocaleDateString('ru-RU')}
); }; export default PostCard; ``` ### Vue компонент ```vue ``` --- ## Важные замечания ### 1. Генерация изображений - Изображения генерируются **автоматически** при создании стратегии - Процесс генерации может занять время (обычно 10-30 секунд на изображение) - Если генерация не удалась, пост все равно будет создан, но без изображения ### 2. Хранение изображений - Все изображения хранятся на бэкенде - Формат изображений: **PNG** - Размер изображений: **1024x1024 пикселей** - Имя файла уникально для каждого поста - Доступ к изображениям только через API эндпоинт ### 3. Публикация постов - При публикации поста в Facebook изображение автоматически прикрепляется - Если изображение отсутствует, пост публикуется только с текстом - Это не влияет на успешность публикации ### 4. Обратная совместимость - Старые стратегии, созданные до добавления этой функции, не будут иметь изображений - Поля `imageUrl` и `imageFilename` будут `null` для таких постов - Фронтенд должен корректно обрабатывать `null` значения --- ## Конфигурация Для работы с изображениями вам понадобится базовый URL вашего API: ```typescript // config.ts export const API_CONFIG = { baseUrl: 'http://your-backend-url', // URL вашего бэкенда // Например: 'http://localhost:8080' или 'https://api.example.com' }; ``` --- ## Миграция существующего кода Если у вас уже есть компоненты для отображения постов, обновите их следующим образом: 1. **Добавьте проверку наличия изображения:** ```typescript const hasImage = post.imageUrl && post.imageFilename; ``` 2. **Добавьте отображение изображения:** ```jsx { hasImage && ( {post.theme} ); } ``` 3. **Обновите типы/интерфейсы:** ```typescript interface PostCalendarItem { // ... существующие поля imageUrl?: string | null; imageFilename?: string | null; } ``` --- ## Поддержка При возникновении проблем: 1. Проверьте, что `imageUrl` и `imageFilename` не `null` 2. Убедитесь, что используете правильный API эндпоинт: `/api/marketing/analysis/images/{imageFilename}` 3. Проверьте, что JWT токен валиден и передается в заголовке `Authorization` 4. Проверьте консоль браузера на наличие ошибок сети или авторизации 5. Убедитесь, что используете правильный базовый URL API --- ## Пример полного ответа API ```json { "success": true, "data": { "strategyId": "507f1f77bcf86cd799439011", "analysisId": "507f1f77bcf86cd799439012", "status": "completed", "createdAt": "2024-01-15T10:00:00", "completedAt": "2024-01-15T10:05:00", "durationWeeks": 4, "priorityPlatforms": ["Facebook", "Instagram"], "strategy": { "weeklyPlans": [ { "weekNumber": 1, "mainThemes": ["Презентация продукта", "Преимущества"], "contentRecommendations": "Создавайте контент...", "priorityPlatforms": ["Facebook"] } ], "postCalendar": [ { "publishDate": "2024-01-16T10:00:00", "platform": "Facebook", "contentType": "пост", "theme": "Презентация нового продукта", "postText": "Мы рады представить наш новый продукт, который поможет вам...", "hashtags": ["#новинка", "#продукт", "#маркетинг"], "publishTime": "10:00", "imageUrl": "post_image_1705312800000_1234567890.png", "imageFilename": "post_image_1705312800000_1234567890.png" }, { "publishDate": "2024-01-18T14:00:00", "platform": "Instagram", "contentType": "сторис", "theme": "Преимущества продукта", "postText": "Узнайте о главных преимуществах нашего продукта...", "hashtags": ["#преимущества", "#качество"], "publishTime": "14:00", "imageUrl": null, "imageFilename": null } ] } } } ``` Обратите внимание, что второй пост не имеет изображения (`imageUrl` и `imageFilename` равны `null`). Это нормальная ситуация, если генерация изображения не удалась. --- **Дата обновления:** 2024-01-15 **Версия API:** 1.0