186 lines
7.0 KiB
Python
186 lines
7.0 KiB
Python
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 enum import Enum
|
||
from typing import List, Literal, Optional
|
||
from datetime import datetime
|
||
import logging
|
||
logger = logging.getLogger(__name__)
|
||
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):
|
||
id: int
|
||
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", response_model=TicketMessageResponse, 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_ticket_message(ticket_id=ticket_id, sender=sender, message=request.message)
|
||
if not message:
|
||
raise HTTPException(status_code=404, detail="Тикет не найден или ошибка добавления сообщения")
|
||
return message
|
||
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)
|
||
if not messages:
|
||
raise HTTPException(status_code=404, detail="Сообщения для тикета не найдены")
|
||
return messages
|
||
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.list_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/tickets/{ticket_id}", response_model=TicketResponse, summary="Обновить статус тикета")
|
||
async def update_ticket_status(
|
||
ticket_id: int,
|
||
status: TicketStatus,
|
||
database_manager: DatabaseManager = Depends(get_database_manager)
|
||
):
|
||
"""
|
||
Обновляет статус тикета.
|
||
|
||
Args:
|
||
ticket_id (int): ID тикета, статус которого нужно обновить.
|
||
status (TicketStatus): Новый статус тикета (open, pending, closed).
|
||
database_manager (DatabaseManager): Менеджер базы данных.
|
||
|
||
Returns:
|
||
TicketResponse: Обновлённые данные тикета.
|
||
|
||
Raises:
|
||
HTTPException: 404, если тикет не найден.
|
||
HTTPException: 500, если произошла ошибка при обновлении тикета.
|
||
"""
|
||
try:
|
||
ticket = await database_manager.update_ticket_status(ticket_id=ticket_id, status=status)
|
||
if not ticket:
|
||
raise HTTPException(status_code=404, detail="Тикет не найден")
|
||
return ticket
|
||
except Exception as e:
|
||
handle_exception(e,"Ошибка обновления тикета")
|