лучшения в приложении: 1. обавлены реальные ссылки на политику конфиденциальности и пользовательское соглашение 2. лучшена логика проверки перед генерацией стикеров: добавлены проверки выбора пресета и ввода текста, запрет на повторную генерацию одной и той же комбинации параметров подряд, отладочное логирование
This commit is contained in:
parent
0e586e693a
commit
a3c9717f9e
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
API предоставляет функциональность для работы со стикерами в Telegram, включая генерацию изображений, создание стикерпаков и управление ими. Также API поддерживает отслеживание позиций задач в очереди.
|
API предоставляет функциональность для работы со стикерами в Telegram, включая генерацию изображений, создание стикерпаков и управление ими. Также API поддерживает отслеживание позиций задач в очереди.
|
||||||
|
|
||||||
Базовый URL: `http://localhost:8001`
|
Базовый URL: `https://stickerserver.gymnasticstuff.uk`
|
||||||
|
|
||||||
## Эндпоинты
|
## Эндпоинты
|
||||||
|
|
||||||
@ -14,11 +14,9 @@ API предоставляет функциональность для рабо
|
|||||||
|
|
||||||
Проверяет работоспособность API.
|
Проверяет работоспособность API.
|
||||||
|
|
||||||
**Ответ:**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"status": "ok"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Управление пользователями
|
### Управление пользователями
|
||||||
@ -54,7 +52,7 @@ API предоставляет функциональность для рабо
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 400 Bad Request: Пользователь с таким chat_id уже существует
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### GET /users/{user_id}
|
#### GET /users/{user_id}
|
||||||
|
|
||||||
@ -75,6 +73,7 @@ API предоставляет функциональность для рабо
|
|||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Пользователь не найден
|
- 404 Not Found: Пользователь не найден
|
||||||
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
### Генерация изображений и управление очередью
|
### Генерация изображений и управление очередью
|
||||||
|
|
||||||
@ -85,32 +84,26 @@ API предоставляет функциональность для рабо
|
|||||||
**Тело запроса:**
|
**Тело запроса:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"tag": "image_generation",
|
||||||
"user_id": 123456789,
|
"user_id": 123456789,
|
||||||
"workflow": {
|
"workflow": {
|
||||||
// Объект workflow для ComfyUI
|
// Объект workflow для ComfyUI
|
||||||
},
|
}
|
||||||
"tag": "image_generation"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
- `tag` (string, обязательный): Тег для типа задачи (допустимое значение: "image_generation")
|
||||||
- `user_id` (integer, обязательный): ID пользователя
|
- `user_id` (integer, обязательный): ID пользователя
|
||||||
- `workflow` (object, обязательный): Объект workflow для ComfyUI
|
- `workflow` (object, обязательный): Объект workflow для ComfyUI
|
||||||
- `tag` (string, обязательный): Тег для типа задачи (допустимое значение: "image_generation")
|
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Ваше изображение генерируется, пожалуйста подождите, готовое изображение будет у вас в галереи",
|
|
||||||
"Task_ID": "123",
|
|
||||||
"queue_position": 5
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 400 Bad Request: Недопустимый тег
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 404 Not Found: Пользователь не найден
|
|
||||||
- 500 Internal Server Error: Ошибка при создании задачи или отправке сообщения
|
|
||||||
|
|
||||||
#### GET /user_pending_tasks/{user_id}
|
#### GET /user_pending_tasks/{user_id}
|
||||||
|
|
||||||
@ -120,30 +113,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `user_id` (integer, обязательный): ID пользователя
|
- `user_id` (integer, обязательный): ID пользователя
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
[
|
"string"
|
||||||
{
|
|
||||||
"task_id": 123,
|
|
||||||
"prompt_id": "prompt_id_from_comfyui",
|
|
||||||
"status": "PENDING",
|
|
||||||
"created_at": "2025-03-13T11:15:00",
|
|
||||||
"queue_position": 3,
|
|
||||||
"updated_at": "2025-03-13T11:20:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"task_id": 124,
|
|
||||||
"prompt_id": "prompt_id_from_comfyui_2",
|
|
||||||
"status": "STARTED",
|
|
||||||
"created_at": "2025-03-13T11:10:00",
|
|
||||||
"queue_position": null,
|
|
||||||
"updated_at": "2025-03-13T11:20:00"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Пользователь не найден
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 500 Internal Server Error: Внутренняя ошибка сервера
|
|
||||||
|
|
||||||
#### GET /task_position/{task_id}
|
#### GET /task_position/{task_id}
|
||||||
|
|
||||||
@ -153,17 +128,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `task_id` (integer, обязательный): ID задачи
|
- `task_id` (integer, обязательный): ID задачи
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"task_id": 123,
|
|
||||||
"status": "PENDING",
|
|
||||||
"queue_position": 3
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Задача не найдена
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 500 Internal Server Error: Внутренняя ошибка сервера
|
|
||||||
|
|
||||||
#### GET /images_links/{user_id}
|
#### GET /images_links/{user_id}
|
||||||
|
|
||||||
@ -188,6 +158,7 @@ API предоставляет функциональность для рабо
|
|||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Пользователь не найден
|
- 404 Not Found: Пользователь не найден
|
||||||
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
### Управление стикерами
|
### Управление стикерами
|
||||||
|
|
||||||
@ -209,13 +180,11 @@ API предоставляет функциональность для рабо
|
|||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```json
|
||||||
{
|
{}
|
||||||
"file_id": "file_id_from_telegram"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при загрузке файла на сервер Telegram
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /create_sticker_set
|
#### POST /create_sticker_set
|
||||||
|
|
||||||
@ -244,15 +213,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `is_video` (boolean, опциональный, по умолчанию false): Флаг видео-стикера
|
- `is_video` (boolean, опциональный, по умолчанию false): Флаг видео-стикера
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Новый набор стикеров успешно создан!",
|
|
||||||
"name": "example_set_by_bot_name"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при создании набора стикеров
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /add_sticker_to_set
|
#### POST /add_sticker_to_set
|
||||||
|
|
||||||
@ -263,6 +229,7 @@ API предоставляет функциональность для рабо
|
|||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 123456789,
|
||||||
"sticker_set_name": "example_set",
|
"sticker_set_name": "example_set",
|
||||||
|
"title": "Example Sticker Set",
|
||||||
"file_id": "file_id_from_telegram",
|
"file_id": "file_id_from_telegram",
|
||||||
"emojis": "😀",
|
"emojis": "😀",
|
||||||
"is_animated": false,
|
"is_animated": false,
|
||||||
@ -273,20 +240,19 @@ API предоставляет функциональность для рабо
|
|||||||
**Параметры:**
|
**Параметры:**
|
||||||
- `user_id` (integer, обязательный): ID пользователя
|
- `user_id` (integer, обязательный): ID пользователя
|
||||||
- `sticker_set_name` (string, обязательный): Название набора стикеров (без суффикса _by_bot)
|
- `sticker_set_name` (string, обязательный): Название набора стикеров (без суффикса _by_bot)
|
||||||
|
- `title` (string, обязательный): Заголовок набора стикеров
|
||||||
- `file_id` (string, обязательный): File_id загруженного стикера
|
- `file_id` (string, обязательный): File_id загруженного стикера
|
||||||
- `emojis` (string, обязательный): Список эмодзи для стикера
|
- `emojis` (string, обязательный): Список эмодзи для стикера
|
||||||
- `is_animated` (boolean, опциональный, по умолчанию false): Флаг анимированного стикера
|
- `is_animated` (boolean, опциональный, по умолчанию false): Флаг анимированного стикера
|
||||||
- `is_video` (boolean, опциональный, по умолчанию false): Флаг видео-стикера
|
- `is_video` (boolean, опциональный, по умолчанию false): Флаг видео-стикера
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Стикер успешно добавлен в набор!"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при добавлении стикера в набор
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### GET /check_sticker_set_name/{sticker_set_name}
|
#### GET /check_sticker_set_name/{sticker_set_name}
|
||||||
|
|
||||||
@ -296,14 +262,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `sticker_set_name` (string, обязательный): Название набора стикеров
|
- `sticker_set_name` (string, обязательный): Название набора стикеров
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"exists": true
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при проверке существования набора стикеров
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /delete_sticker_from_set
|
#### POST /delete_sticker_from_set
|
||||||
|
|
||||||
@ -320,14 +284,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `file_id` (string, обязательный): File_id стикера
|
- `file_id` (string, обязательный): File_id стикера
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Стикер успешно удален из набора!"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при удалении стикера из набора
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /set_sticker_position_in_set
|
#### POST /set_sticker_position_in_set
|
||||||
|
|
||||||
@ -336,24 +298,22 @@ API предоставляет функциональность для рабо
|
|||||||
**Тело запроса:**
|
**Тело запроса:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"sticker_file_id": "file_id_from_telegram",
|
"file_id": "file_id_from_telegram",
|
||||||
"position": 0
|
"position": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
- `sticker_file_id` (string, обязательный): File_id стикера
|
- `file_id` (string, обязательный): File_id стикера
|
||||||
- `position` (integer, обязательный): Новая позиция стикера (0 - первая позиция)
|
- `position` (integer, обязательный): Новая позиция стикера (0 - первая позиция)
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Позиция стикера успешно изменена!"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при изменении позиции стикера
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /delete_sticker_set
|
#### POST /delete_sticker_set
|
||||||
|
|
||||||
@ -370,14 +330,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `sticker_set_name` (string, обязательный): Полное название набора стикеров (включая суффикс _by_bot)
|
- `sticker_set_name` (string, обязательный): Полное название набора стикеров (включая суффикс _by_bot)
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"message": "Набор стикеров успешно удален!"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при удалении набора стикеров
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### POST /create_sticker_set_db
|
#### POST /create_sticker_set_db
|
||||||
|
|
||||||
@ -405,9 +363,7 @@ API предоставляет функциональность для рабо
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Пользователь не найден
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 400 Bad Request: Ошибка валидации
|
|
||||||
- 500 Internal Server Error: Внутренняя ошибка сервера
|
|
||||||
|
|
||||||
#### GET /user_sticker_sets/{user_id}
|
#### GET /user_sticker_sets/{user_id}
|
||||||
|
|
||||||
@ -428,8 +384,7 @@ API предоставляет функциональность для рабо
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Пользователь не найден
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 500 Internal Server Error: Внутренняя ошибка сервера
|
|
||||||
|
|
||||||
### Прокси для Telegram API
|
### Прокси для Telegram API
|
||||||
|
|
||||||
@ -442,23 +397,12 @@ API предоставляет функциональность для рабо
|
|||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```json
|
||||||
{
|
{}
|
||||||
"name": "example_set_by_bot_name",
|
|
||||||
"title": "Example Sticker Set",
|
|
||||||
"sticker_type": "regular",
|
|
||||||
"thumbnail_url": "http://localhost:8001/stickers/proxy/sticker/file_id_from_telegram",
|
|
||||||
"share_url": "https://t.me/addstickers/example_set_by_bot_name",
|
|
||||||
"stickers": [
|
|
||||||
{
|
|
||||||
"file_id": "file_id_from_telegram",
|
|
||||||
"emoji": "😀",
|
|
||||||
"position": 0,
|
|
||||||
"file_url": "http://localhost:8001/stickers/proxy/sticker/file_id_from_telegram"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Ошибки:**
|
||||||
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
#### GET /stickers/proxy/sticker/{file_id}
|
#### GET /stickers/proxy/sticker/{file_id}
|
||||||
|
|
||||||
Прокси для получения изображения стикера без раскрытия токена бота.
|
Прокси для получения изображения стикера без раскрытия токена бота.
|
||||||
@ -467,14 +411,12 @@ API предоставляет функциональность для рабо
|
|||||||
- `file_id` (string, обязательный): File ID стикера
|
- `file_id` (string, обязательный): File ID стикера
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
Изображение стикера в формате WebP с заголовками:
|
```
|
||||||
- Content-Type: image/webp
|
"string"
|
||||||
- Content-Disposition: inline
|
```
|
||||||
- Cache-Control: public, max-age=86400
|
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 404 Not Found: Стикер не найден
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
- 500 Internal Server Error: Ошибка при получении стикера
|
|
||||||
|
|
||||||
#### POST /stickers/test/upload
|
#### POST /stickers/test/upload
|
||||||
|
|
||||||
@ -485,67 +427,63 @@ API предоставляет функциональность для рабо
|
|||||||
- `image_url` (string, обязательный): URL изображения для загрузки
|
- `image_url` (string, обязательный): URL изображения для загрузки
|
||||||
|
|
||||||
**Ответ (200 OK):**
|
**Ответ (200 OK):**
|
||||||
```json
|
```
|
||||||
{
|
"string"
|
||||||
"success": true,
|
|
||||||
"file_id": "file_id_from_telegram",
|
|
||||||
"file_url": "http://localhost:8001/stickers/proxy/sticker/file_id_from_telegram"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ошибки:**
|
**Ошибки:**
|
||||||
- 500 Internal Server Error: Ошибка при загрузке изображения
|
- 422 Validation Error: Ошибка валидации данных
|
||||||
|
|
||||||
## Модели данных
|
## Модели данных
|
||||||
|
|
||||||
### UserBase
|
### UserBase
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 1,
|
||||||
"username": "example_user",
|
"username": "john_doe",
|
||||||
"chat_id": 123456789,
|
"chat_id": 123456789,
|
||||||
"balance": 0
|
"balance": 100
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### UserCreate
|
### UserCreate
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 1,
|
||||||
"username": "example_user",
|
"username": "john_doe",
|
||||||
"chat_id": 123456789,
|
"chat_id": 123456789,
|
||||||
"balance": 0
|
"balance": 100
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### ImageBase
|
### ImageBase
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 0,
|
||||||
"link": "file_id_from_telegram",
|
"link": "string",
|
||||||
"prompt_id": "prompt_id_from_comfyui",
|
"prompt_id": "string",
|
||||||
"status": "COMPLETED",
|
"status": "string",
|
||||||
"created_at": "2025-03-12T12:00:00",
|
"created_at": "2025-03-19T12:15:53.248Z",
|
||||||
"sticker_set_id": null
|
"sticker_set_id": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### StickerUploadRequest
|
### StickerUploadRequest
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 0,
|
||||||
"link": "https://example.com/image.png"
|
"link": "string"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### StickerSetRequest
|
### StickerSetRequest
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 0,
|
||||||
"sticker_set_name": "example_set",
|
"sticker_set_name": "string",
|
||||||
"title": "Example Sticker Set",
|
"title": "string",
|
||||||
"file_id": "file_id_from_telegram",
|
"file_id": "string",
|
||||||
"emojis": "😀",
|
"emojis": "string",
|
||||||
"is_animated": false,
|
"is_animated": false,
|
||||||
"is_video": false
|
"is_video": false
|
||||||
}
|
}
|
||||||
@ -554,14 +492,14 @@ API предоставляет функциональность для рабо
|
|||||||
### StickerFileID
|
### StickerFileID
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"file_id": "file_id_from_telegram"
|
"file_id": "string"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### StickerSetPosition
|
### StickerSetPosition
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"sticker_file_id": "file_id_from_telegram",
|
"file_id": "string",
|
||||||
"position": 0
|
"position": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -569,7 +507,7 @@ API предоставляет функциональность для рабо
|
|||||||
### StickerSetName
|
### StickerSetName
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"sticker_set_name": "example_set_by_bot_name"
|
"sticker_set_name": "string"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -577,46 +515,51 @@ API предоставляет функциональность для рабо
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"tag": "image_generation",
|
"tag": "image_generation",
|
||||||
"user_id": 123456789,
|
"user_id": 0,
|
||||||
"workflow": {
|
"workflow": {}
|
||||||
// Объект workflow для ComfyUI
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### CreateStickerSetDBRequest
|
### CreateStickerSetDBRequest
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"user_id": 123456789,
|
"user_id": 0,
|
||||||
"sticker_set_name": "example_set_by_bot_name"
|
"sticker_set_name": "string"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### StickerSetResponse
|
### StickerSetResponse
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 0,
|
||||||
"set_name": "example_set_by_bot_name",
|
"set_name": "string",
|
||||||
"user_id": 123456789
|
"user_id": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### TaskPosition
|
### HTTPValidationError
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"task_id": 123,
|
"detail": [
|
||||||
"status": "PENDING",
|
{
|
||||||
"queue_position": 3
|
"loc": [
|
||||||
|
"string",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"msg": "string",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### PendingTask
|
### ValidationError
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"task_id": 123,
|
"loc": [
|
||||||
"prompt_id": "prompt_id_from_comfyui",
|
"string",
|
||||||
"status": "PENDING",
|
0
|
||||||
"created_at": "2025-03-13T11:15:00",
|
],
|
||||||
"queue_position": 3,
|
"msg": "string",
|
||||||
"updated_at": "2025-03-13T11:20:00"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import umbrella from './umbrella250x.png';
|
|||||||
import defaultAvatar from './default-avatar.svg';
|
import defaultAvatar from './default-avatar.svg';
|
||||||
import shieldIcon from './shield-icon.png';
|
import shieldIcon from './shield-icon.png';
|
||||||
import reactLogo from './react.svg';
|
import reactLogo from './react.svg';
|
||||||
|
import tokenIcon from './token_ico.png';
|
||||||
|
|
||||||
export const images = {
|
export const images = {
|
||||||
ahareBot,
|
ahareBot,
|
||||||
@ -67,5 +68,6 @@ export const images = {
|
|||||||
umbrella,
|
umbrella,
|
||||||
defaultAvatar,
|
defaultAvatar,
|
||||||
shieldIcon,
|
shieldIcon,
|
||||||
reactLogo
|
reactLogo,
|
||||||
|
tokenIcon
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
src/assets/token_ico.png
Normal file
BIN
src/assets/token_ico.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
@ -1,6 +1,6 @@
|
|||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 calc(-1 * var(--spacing-medium));
|
margin: 0 calc(-1 * var(--spacing-medium));
|
||||||
padding: var(--spacing-medium);
|
padding: var(--spacing-medium);
|
||||||
@ -16,6 +16,7 @@
|
|||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
scroll-snap-type: x mandatory;
|
scroll-snap-type: x mandatory;
|
||||||
gap: calc(var(--spacing-medium) * 0.75);
|
gap: calc(var(--spacing-medium) * 0.75);
|
||||||
|
padding-left: 3px; /* Отступ для обводки первых кнопок */
|
||||||
padding-bottom: var(--spacing-small); /* Для градиента */
|
padding-bottom: var(--spacing-small); /* Для градиента */
|
||||||
padding-right: var(--spacing-medium); /* Отступ для последнего элемента */
|
padding-right: var(--spacing-medium); /* Отступ для последнего элемента */
|
||||||
margin-right: calc(-1 * var(--spacing-medium)); /* Компенсация отступа контейнера */
|
margin-right: calc(-1 * var(--spacing-medium)); /* Компенсация отступа контейнера */
|
||||||
@ -32,7 +33,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 120px; /* Фиксированная ширина для кнопок */
|
width: 120px; /* Уменьшенная ширина для кнопок */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Добавляем градиент-индикатор скролла справа */
|
/* Добавляем градиент-индикатор скролла справа */
|
||||||
|
|||||||
@ -35,7 +35,6 @@
|
|||||||
.selected {
|
.selected {
|
||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
border-width: 3px; /* Увеличиваем толщину с 2px до 3px */
|
border-width: 3px; /* Увеличиваем толщину с 2px до 3px */
|
||||||
transform: translateY(-2px); /* Добавляем эффект приподнятия */
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); /* Добавляем тень как при hover */
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); /* Добавляем тень как при hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +50,6 @@
|
|||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
border-width: 3px;
|
border-width: 3px;
|
||||||
box-shadow: 0 0 0 3px var(--color-primary), 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 0 3px var(--color-primary), 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,9 +59,9 @@
|
|||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Предотвращаем двойное приподнятие при наведении на выбранную кнопку */
|
/* Стиль для наведения на выбранную кнопку */
|
||||||
.selected:hover {
|
.selected:hover {
|
||||||
transform: translateY(-2px); /* Оставляем то же приподнятие */
|
transform: none; /* Убираем эффект приподнятия */
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:active {
|
.button:active {
|
||||||
|
|||||||
@ -102,6 +102,15 @@
|
|||||||
.balanceIcon {
|
.balanceIcon {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tokenImage {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balanceValue {
|
.balanceValue {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { MOCK_USER } from '../../constants/mock';
|
import { MOCK_USER } from '../../constants/mock';
|
||||||
import { getUserInfo, isTelegramWebAppAvailable } from '../../constants/user';
|
import { getUserInfo, isTelegramWebAppAvailable } from '../../constants/user';
|
||||||
|
import { images } from '../../assets';
|
||||||
import styles from './Header.module.css';
|
import styles from './Header.module.css';
|
||||||
|
|
||||||
const Header: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
@ -50,7 +51,9 @@ const Header: React.FC = () => {
|
|||||||
onClick={() => alert('Пополнить баланс')}
|
onClick={() => alert('Пополнить баланс')}
|
||||||
title="Нажмите чтобы пополнить баланс"
|
title="Нажмите чтобы пополнить баланс"
|
||||||
>
|
>
|
||||||
<span className={styles.balanceIcon}>💎</span>
|
<span className={styles.balanceIcon}>
|
||||||
|
<img src={images.tokenIcon} alt="Токены" className={styles.tokenImage} />
|
||||||
|
</span>
|
||||||
<span className={styles.balanceValue}>
|
<span className={styles.balanceValue}>
|
||||||
{user.balance}
|
{user.balance}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
export const baseWorkflow = {
|
export const baseWorkflow = {
|
||||||
"305": {
|
"305": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"ckpt_name": "SDXL\\dreamshaperXL_lightningDPMSDE.safetensors"
|
"ckpt_name": "dreamshaperXL_lightningDPMSDE.safetensors"
|
||||||
},
|
},
|
||||||
"class_type": "CheckpointLoaderSimple",
|
"class_type": "CheckpointLoaderSimple",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
|
|||||||
@ -8,6 +8,14 @@ import { stylePresets } from '../config/stylePresets';
|
|||||||
import apiService from '../services/api';
|
import apiService from '../services/api';
|
||||||
import NotificationModal from '../components/shared/NotificationModal';
|
import NotificationModal from '../components/shared/NotificationModal';
|
||||||
|
|
||||||
|
// Интерфейс для хранения данных о последней генерации
|
||||||
|
interface LastGenerationData {
|
||||||
|
imageData?: string;
|
||||||
|
style?: string;
|
||||||
|
presetId?: string;
|
||||||
|
customPrompt?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const Home: React.FC = () => {
|
const Home: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -35,6 +43,9 @@ const Home: React.FC = () => {
|
|||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [promptText, setPromptText] = useState('');
|
const [promptText, setPromptText] = useState('');
|
||||||
|
|
||||||
|
// Состояние для хранения данных о последней успешной генерации
|
||||||
|
const [lastGenerationData, setLastGenerationData] = useState<LastGenerationData>({});
|
||||||
|
|
||||||
// Обработчики для модального окна
|
// Обработчики для модального окна
|
||||||
const handleGalleryClick = useCallback(() => {
|
const handleGalleryClick = useCallback(() => {
|
||||||
setIsNotificationVisible(false);
|
setIsNotificationVisible(false);
|
||||||
@ -63,8 +74,63 @@ const Home: React.FC = () => {
|
|||||||
|
|
||||||
if (actionType === 'function') {
|
if (actionType === 'function') {
|
||||||
if (actionValue === 'startGeneration') {
|
if (actionValue === 'startGeneration') {
|
||||||
|
// Проверка наличия изображения
|
||||||
if (!imageData) {
|
if (!imageData) {
|
||||||
alert('Сначала загрузите изображение');
|
setNotificationTitle('Внимание');
|
||||||
|
setNotificationMessage('Сначала загрузите изображение');
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsNotificationVisible(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка выбора пресета промпта
|
||||||
|
if (!selectedPresetId) {
|
||||||
|
setNotificationTitle('Внимание');
|
||||||
|
setNotificationMessage('Выберите образ для генерации');
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsNotificationVisible(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка ввода текста, если выбран "Свой промпт"
|
||||||
|
if (selectedPresetId === 'customPrompt' && !customPrompt.trim()) {
|
||||||
|
setNotificationTitle('Внимание');
|
||||||
|
setNotificationMessage('Введите текст промпта');
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsNotificationVisible(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем логирование для отладки
|
||||||
|
console.log('Comparing generations:', {
|
||||||
|
current: {
|
||||||
|
imageDataLength: imageData?.length,
|
||||||
|
style: selectedStyle,
|
||||||
|
presetId: selectedPresetId,
|
||||||
|
customPrompt
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
imageDataLength: lastGenerationData.imageData?.length,
|
||||||
|
style: lastGenerationData.style,
|
||||||
|
presetId: lastGenerationData.presetId,
|
||||||
|
customPrompt: lastGenerationData.customPrompt
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Проверка на повторную генерацию той же комбинации
|
||||||
|
const isSameGeneration =
|
||||||
|
lastGenerationData.imageData === imageData &&
|
||||||
|
lastGenerationData.style === selectedStyle &&
|
||||||
|
lastGenerationData.presetId === selectedPresetId &&
|
||||||
|
(selectedPresetId !== 'customPrompt' || lastGenerationData.customPrompt === customPrompt);
|
||||||
|
|
||||||
|
console.log('Is same generation:', isSameGeneration);
|
||||||
|
|
||||||
|
if (isSameGeneration) {
|
||||||
|
setNotificationTitle('Внимание');
|
||||||
|
setNotificationMessage('Нельзя отправить одну и ту же комбинацию изображения и образа подряд. Пожалуйста, измените изображение или выберите другой образ.');
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsNotificationVisible(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +149,14 @@ const Home: React.FC = () => {
|
|||||||
const response = await apiService.generateImage(imageData, selectedStyle, selectedPresetId, userPrompt);
|
const response = await apiService.generateImage(imageData, selectedStyle, selectedPresetId, userPrompt);
|
||||||
console.log('Generation response:', response);
|
console.log('Generation response:', response);
|
||||||
|
|
||||||
|
// Сохраняем данные о текущей генерации
|
||||||
|
setLastGenerationData({
|
||||||
|
imageData,
|
||||||
|
style: selectedStyle,
|
||||||
|
presetId: selectedPresetId,
|
||||||
|
customPrompt: userPrompt
|
||||||
|
});
|
||||||
|
|
||||||
// Проверяем, была ли ошибка перевода
|
// Проверяем, была ли ошибка перевода
|
||||||
if (response.translationFailed) {
|
if (response.translationFailed) {
|
||||||
setNotificationTitle('Недопустимый промпт');
|
setNotificationTitle('Недопустимый промпт');
|
||||||
@ -157,7 +231,7 @@ const Home: React.FC = () => {
|
|||||||
|
|
||||||
// Если выбрана любая другая кнопка, скрываем поле ввода
|
// Если выбрана любая другая кнопка, скрываем поле ввода
|
||||||
setIsInputVisible(false);
|
setIsInputVisible(false);
|
||||||
}, [navigate, imageData, selectedStyle, selectedPresetId, customPrompt]);
|
}, [navigate, imageData, selectedStyle, selectedPresetId, customPrompt, lastGenerationData]);
|
||||||
|
|
||||||
// Эффект для обновления window.history.state при загрузке из localStorage
|
// Эффект для обновления window.history.state при загрузке из localStorage
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -34,8 +34,22 @@ const TermsAndConditions: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className={styles.links}>
|
<div className={styles.links}>
|
||||||
<a href="#" className={styles.link}>Условия использования</a>
|
<a
|
||||||
<a href="#" className={styles.link}>Политика конфиденциальности</a>
|
href="https://telegra.ph/Polzovatelskoe-soglashenie-03-19-13"
|
||||||
|
className={styles.link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Условия использования
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://telegra.ph/Politika-konfidencialnosti-03-19-10"
|
||||||
|
className={styles.link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Политика конфиденциальности
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.buttonsContainer}>
|
<div className={styles.buttonsContainer}>
|
||||||
|
|||||||
@ -90,7 +90,8 @@ export class StickerService {
|
|||||||
file_id: firstSticker,
|
file_id: firstSticker,
|
||||||
emojis: firstEmoji,
|
emojis: firstEmoji,
|
||||||
is_animated: false,
|
is_animated: false,
|
||||||
is_video: false
|
is_video: false,
|
||||||
|
format: "static" // Добавляем поле format для соответствия требованиям API
|
||||||
};
|
};
|
||||||
|
|
||||||
// Логируем данные запроса
|
// Логируем данные запроса
|
||||||
@ -203,7 +204,8 @@ export class StickerService {
|
|||||||
file_id: fileId,
|
file_id: fileId,
|
||||||
emojis: emoji,
|
emojis: emoji,
|
||||||
is_animated: false,
|
is_animated: false,
|
||||||
is_video: false
|
is_video: false,
|
||||||
|
format: "static" // Добавляем поле format для соответствия требованиям API
|
||||||
};
|
};
|
||||||
|
|
||||||
// Логируем данные запроса
|
// Логируем данные запроса
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"305": {
|
"305": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"ckpt_name": "SDXL\\dreamshaperXL_lightningDPMSDE.safetensors"
|
"ckpt_name": "dreamshaperXL_lightningDPMSDE.safetensors"
|
||||||
},
|
},
|
||||||
"class_type": "CheckpointLoaderSimple",
|
"class_type": "CheckpointLoaderSimple",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user