Files
backend/app/routes/support_routes.py

250 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.exc import SQLAlchemyError
from app.services.db_manager import DatabaseManager
from instance.configdb import get_database_manager
from uuid import UUID
from pydantic import BaseModel
from fastapi import Response, status
from enum import Enum
from typing import List, Literal, Optional
from datetime import datetime
import logging
logger = logging.getLogger(__name__)
class UpdateTicketStatusRequest(BaseModel):
new_status: str
class TicketStatus(str, Enum):
OPEN = "open"
PENDING = "pending"
CLOSED = "closed"
class CreateTicketRequest(BaseModel):
subject: str
message: str
class TicketResponse(BaseModel):
id: int
user_id: UUID
subject: str
message: str
status: TicketStatus
created_at: datetime
updated_at: datetime
class TicketMessageRequest(BaseModel):
message: str
class TicketMessageResponse(BaseModel):
ticket_id: int
sender: str
message: str
created_at: datetime
router = APIRouter()
def handle_exception(e: Exception, message: str):
logger.error(f"{message}: {e}")
raise HTTPException(status_code=500, detail=f"{message}: {str(e)}")
@router.post("/support/tickets/{ticket_id}/messages", summary="Добавить сообщение")
async def add_message(
ticket_id: int,
request: TicketMessageRequest,
sender: Literal["user", "support"], # "user" или "support"
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Добавляет сообщение в тикет.
Args:
ticket_id (int): ID тикета.
request (TicketMessageRequest): Данные сообщения.
sender (str): Отправитель ("user" или "support").
database_manager (DatabaseManager): Управление базой данных.
Returns:
TicketMessageResponse: Данные созданного сообщения.
"""
try:
message = await database_manager.add_message_to_ticket(ticket_id=ticket_id, sender=sender, message=request.message)
if not message:
raise HTTPException(status_code=404, detail="Тикет не найден или ошибка добавления сообщения")
if message != "OK":
raise HTTPException(status_code=500, detail="Ошибка добавления сообщения")
return Response(status_code=status.HTTP_200_OK)
except Exception as e:
handle_exception(e,"Ошибка добавления сообщения")
@router.get("/support/tickets/{ticket_id}/messages", response_model=List[TicketMessageResponse], summary="Получить сообщения")
async def get_messages(
ticket_id: int,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Возвращает список сообщений в тикете.
Args:
ticket_id (int): ID тикета, для которого нужно получить сообщения.
database_manager (DatabaseManager): Менеджер базы данных.
Returns:
List[TicketMessageResponse]: Список сообщений, связанных с тикетом.
Raises:
HTTPException: 404, если сообщения для тикета не найдены.
HTTPException: 500, если произошла ошибка на сервере.
"""
try:
messages = await database_manager.get_ticket_messages(ticket_id=ticket_id)
ticket_info = await database_manager.get_ticket(ticket_id)
logger.info(messages)
result_messages = []
if messages:
for message in messages:
correct_response = TicketMessageResponse(
ticket_id=ticket_id,
sender=message.sender,
message=message.message,
created_at=message.created_at
)
result_messages.append(correct_response)
result_messages.insert(0,
TicketMessageResponse(
ticket_id=ticket_id,
sender="user",
message=ticket_info['message'],
created_at=ticket_info["created_at"]
)
)
return result_messages
except Exception as e:
handle_exception(e,"Ошибка получения сообщения")
@router.get("/support/ticket/{ticket_id}", response_model=TicketResponse, summary="Получить информацию о тикете")
async def get_ticket(
ticket_id: int,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Возвращает информацию о тикете.
Args:
ticket_id (int): ID тикета, информацию котрого хочет получить пользователь.
database_manager (DatabaseManager): Менеджер базы данных.
Returns:
TicketResponse: Информация о тикете.
Raises:
HTTPException: 404, если тикет не найден.
HTTPException: 500, если произошла ошибка на сервере.
"""
try:
# Получаем данные о тикете
ticket = await database_manager.get_ticket(ticket_id=ticket_id)
if not ticket:
raise HTTPException(status_code=404, detail="Тикет не найден")
# Возвращаем данные через Pydantic-модель
return TicketResponse(**ticket)
except SQLAlchemyError as e:
handle_exception(e, "Ошибка получения тикета")
except Exception as e:
handle_exception(e, "Неизвестная ошибка при получении тикета")
@router.post("/support/tickets", response_model=TicketResponse, summary="Создать тикет")
async def create_ticket(
request: CreateTicketRequest,
user_id: UUID,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Создаёт новый тикет для пользователя.
Args:
request (CreateTicketRequest): Данные для создания тикета (тема и сообщение).
user_id (UUID): Идентификатор пользователя, создающего тикет.
database_manager (DatabaseManager): Менеджер базы данных.
Returns:
TicketResponse: Данные созданного тикета.
Raises:
HTTPException: 500, если произошла ошибка при создании тикета.
"""
try:
ticket = await database_manager.create_ticket(
user_id=user_id,
subject=request.subject,
message=request.message
)
return ticket
except Exception as e:
handle_exception(e,"Ошибка содания тикета")
@router.get("/support/tickets", response_model=List[TicketResponse], summary="Получить список тикетов")
async def list_tickets(
user_id: UUID,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Возвращает список тикетов пользователя.
Args:
user_id (UUID): Идентификатор пользователя, чьи тикеты нужно получить.
database_manager (DatabaseManager): Менеджер базы данных.
Returns:
List[TicketResponse]: Список тикетов пользователя.
Raises:
HTTPException: 404, если тикеты не найдены.
HTTPException: 500, если произошла ошибка на сервере.
"""
try:
tickets = await database_manager.get_active_tickets(user_id=user_id)
if not tickets:
raise HTTPException(status_code=404, detail="Тикеты не найдены")
return tickets
except Exception as e:
handle_exception(e,"Ошибка получения тикетов")
@router.patch("/support/ticket/{ticket_id}/status", summary="Обновить статус тикета")
async def update_ticket_status(
ticket_id: int,
request: UpdateTicketStatusRequest,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Обновляет статус тикета.
Args:
ticket_id (int): ID тикета.
request (UpdateTicketStatusRequest): Запрос с новым статусом.
database_manager (DatabaseManager): Менеджер базы данных.
Returns:
dict: Подтверждение обновления статуса.
Raises:
HTTPException: Если тикет не найден или произошла ошибка.
"""
try:
result = await database_manager.update_ticket_status(ticket_id, request.new_status)
if result != "OK":
return "ERROR"
return "OK"
except ValueError as e:
logger.error(f"Тикет с ID {ticket_id} не найден: {e}")
raise HTTPException(status_code=404, detail="Тикет не найден.")
except Exception as e:
logger.error(f"Ошибка обновления статуса тикета {ticket_id}: {e}")
raise HTTPException(status_code=500, detail="Не удалось обновить статус тикета.")