diff --git a/app/cabinet/routes/__init__.py b/app/cabinet/routes/__init__.py index 035ca3d2..a26fb6ba 100644 --- a/app/cabinet/routes/__init__.py +++ b/app/cabinet/routes/__init__.py @@ -32,6 +32,9 @@ from .admin_payments import router as admin_payments_router from .admin_promo_offers import router as admin_promo_offers_router from .admin_remnawave import router as admin_remnawave_router from .media import router as media_router +from .websocket import router as websocket_router +from .ticket_notifications import router as ticket_notifications_router +from .ticket_notifications import admin_router as admin_ticket_notifications_router # Main cabinet router router = APIRouter(prefix="/cabinet", tags=["Cabinet"]) @@ -71,5 +74,10 @@ router.include_router(admin_users_router) router.include_router(admin_payments_router) router.include_router(admin_promo_offers_router) router.include_router(admin_remnawave_router) +router.include_router(ticket_notifications_router) +router.include_router(admin_ticket_notifications_router) + +# WebSocket route +router.include_router(websocket_router) __all__ = ["router"] diff --git a/app/cabinet/routes/admin_tickets.py b/app/cabinet/routes/admin_tickets.py index cfef4544..0fcc2dd4 100644 --- a/app/cabinet/routes/admin_tickets.py +++ b/app/cabinet/routes/admin_tickets.py @@ -13,7 +13,9 @@ from pydantic import BaseModel, Field from app.database.models import User, Ticket, TicketMessage from app.database.crud.ticket import TicketCRUD, TicketMessageCRUD +from app.database.crud.ticket_notification import TicketNotificationCRUD from app.config import settings +from app.cabinet.routes.websocket import notify_user_ticket_reply from ..dependencies import get_cabinet_db, get_current_admin_user from ..schemas.tickets import TicketMessageResponse @@ -348,6 +350,16 @@ async def reply_to_ticket( except Exception as e: logger.warning(f"Failed to send Telegram notification: {e}") + # Уведомить пользователя в кабинете (WebSocket) + try: + notification = await TicketNotificationCRUD.create_user_notification_for_admin_reply( + db, ticket, request.message + ) + if notification: + await notify_user_ticket_reply(ticket.user_id, ticket.id, (request.message or "")[:100]) + except Exception as e: + logger.warning(f"Failed to create cabinet notification for admin reply: {e}") + return _message_to_response(message) diff --git a/app/cabinet/routes/tickets.py b/app/cabinet/routes/tickets.py index 448c870f..500f7001 100644 --- a/app/cabinet/routes/tickets.py +++ b/app/cabinet/routes/tickets.py @@ -13,6 +13,8 @@ from sqlalchemy.orm import selectinload from app.database.models import User, Ticket, TicketMessage from app.config import settings from app.handlers.tickets import notify_admins_about_new_ticket, notify_admins_about_ticket_reply +from app.database.crud.ticket_notification import TicketNotificationCRUD +from app.cabinet.routes.websocket import notify_admins_new_ticket, notify_admins_ticket_reply from ..dependencies import get_cabinet_db, get_current_cabinet_user from ..schemas.tickets import ( @@ -162,12 +164,20 @@ async def create_ticket( # Refresh to get relationships await db.refresh(ticket, ["messages"]) - # Уведомить админов о новом тикете + # Уведомить админов о новом тикете (Telegram) try: await notify_admins_about_new_ticket(ticket, db) except Exception as e: logger.error(f"Error notifying admins about new ticket from cabinet: {e}") + # Уведомить админов в кабинете (WebSocket) + try: + notification = await TicketNotificationCRUD.create_admin_notification_for_new_ticket(db, ticket) + if notification: + await notify_admins_new_ticket(ticket.id, ticket.title, user.id) + except Exception as e: + logger.error(f"Error creating cabinet notification for new ticket: {e}") + messages = [_message_to_response(m) for m in ticket.messages] return TicketDetailResponse( @@ -275,10 +285,20 @@ async def add_ticket_message( await db.commit() await db.refresh(message) - # Уведомить админов об ответе пользователя + # Уведомить админов об ответе пользователя (Telegram) try: await notify_admins_about_ticket_reply(ticket, request.message, db) except Exception as e: logger.error(f"Error notifying admins about ticket reply from cabinet: {e}") + # Уведомить админов в кабинете (WebSocket) + try: + notification = await TicketNotificationCRUD.create_admin_notification_for_user_reply( + db, ticket, request.message + ) + if notification: + await notify_admins_ticket_reply(ticket.id, (request.message or "")[:100], user.id) + except Exception as e: + logger.error(f"Error creating cabinet notification for user reply: {e}") + return _message_to_response(message) diff --git a/requirements.txt b/requirements.txt index bc256ffb..579a18bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,7 @@ redis==5.0.1 PyYAML==6.0.2 fastapi==0.115.6 uvicorn==0.32.1 +websockets>=12.0 python-multipart==0.0.9 # YooKassa SDK