141 lines
4.7 KiB
Python
141 lines
4.7 KiB
Python
"""
|
||
Обработчики просмотра заявок.
|
||
|
||
Навигация полностью через callback payload — FSM-состояния не нужны.
|
||
"view_tickets" → список, страница 0
|
||
"tickets_page:{n}" → список, страница n
|
||
"ticket_detail:{id}" → карточка заявки
|
||
"main_menu" → в menu.py
|
||
"""
|
||
from maxapi.context import BaseContext
|
||
from maxapi.dispatcher import Router
|
||
from maxapi.filters import F
|
||
from maxapi.types.updates.message_callback import MessageCallback
|
||
|
||
from bot.filters import PayloadStartsWith
|
||
from bot.keyboards import ticket_detail_kb, tickets_list_kb
|
||
from bot.send_helper import bot_send
|
||
from database.queries.ticket_attachments import get_attachments
|
||
from database.queries.tickets import (
|
||
PAGE_SIZE,
|
||
count_tickets_for_org,
|
||
get_ticket,
|
||
get_tickets_for_org,
|
||
)
|
||
|
||
router = Router(router_id="view_tickets")
|
||
|
||
STATUS_LABELS = {
|
||
"open": "🔴 Открыта",
|
||
"in_progress": "🟡 В работе",
|
||
"closed": "🟢 Закрыта",
|
||
}
|
||
|
||
|
||
async def _send_tickets_page(
|
||
event: MessageCallback, page: int, bot_user: dict
|
||
) -> None:
|
||
org_id = bot_user["org_id"]
|
||
tickets = await get_tickets_for_org(org_id, page=page)
|
||
total = await count_tickets_for_org(org_id)
|
||
|
||
chat_id = event.message.recipient.chat_id if event.message else None
|
||
if chat_id is None:
|
||
return
|
||
|
||
if not tickets:
|
||
await bot_send(
|
||
event.bot,
|
||
chat_id=chat_id,
|
||
user_id=bot_user["max_user_id"],
|
||
text="📭 У вашей организации пока нет заявок.",
|
||
attachments=[ticket_detail_kb(page=0)],
|
||
)
|
||
return
|
||
|
||
await bot_send(
|
||
event.bot,
|
||
chat_id=chat_id,
|
||
user_id=bot_user["max_user_id"],
|
||
text=f"📋 Заявки организации (стр. {page + 1}):",
|
||
attachments=[tickets_list_kb(tickets, page=page, total=total)],
|
||
)
|
||
|
||
|
||
@router.message_callback(F.callback.payload == "view_tickets")
|
||
async def cb_view_tickets(
|
||
event: MessageCallback, context: BaseContext, bot_user: dict
|
||
) -> None:
|
||
await event.answer(notification="")
|
||
await _send_tickets_page(event, page=0, bot_user=bot_user)
|
||
|
||
|
||
@router.message_callback(PayloadStartsWith("tickets_page:"))
|
||
async def cb_tickets_page(
|
||
event: MessageCallback, context: BaseContext, bot_user: dict
|
||
) -> None:
|
||
await event.answer(notification="")
|
||
try:
|
||
page = int(event.callback.payload.split(":")[1])
|
||
except (IndexError, ValueError):
|
||
page = 0
|
||
await _send_tickets_page(event, page=page, bot_user=bot_user)
|
||
|
||
|
||
@router.message_callback(PayloadStartsWith("ticket_detail:"))
|
||
async def cb_ticket_detail(
|
||
event: MessageCallback, context: BaseContext, bot_user: dict
|
||
) -> None:
|
||
try:
|
||
ticket_id = int(event.callback.payload.split(":")[1])
|
||
except (IndexError, ValueError):
|
||
await event.answer(notification="Ошибка")
|
||
return
|
||
|
||
ticket = await get_ticket(ticket_id)
|
||
|
||
chat_id = event.message.recipient.chat_id if event.message else None
|
||
if chat_id is None:
|
||
return
|
||
|
||
# Проверка доступа: заявка должна принадлежать той же организации
|
||
if ticket is None or ticket["org_id"] != bot_user["org_id"]:
|
||
await event.answer(notification="Нет доступа")
|
||
return
|
||
|
||
await event.answer(notification="")
|
||
|
||
status_label = STATUS_LABELS.get(ticket["status"], ticket["status"])
|
||
text = (
|
||
f"📌 Заявка #{ticket['id']}\n"
|
||
f"Статус: {status_label}\n"
|
||
f"Создана: {ticket['created_at'][:16]}\n\n"
|
||
f"📄 Описание:\n{ticket['description']}"
|
||
)
|
||
if ticket.get("last_comment"):
|
||
text += f"\n\n💬 Последний комментарий:\n{ticket['last_comment']}"
|
||
|
||
# Вложения
|
||
attachments = await get_attachments(ticket_id)
|
||
if attachments:
|
||
att_lines = []
|
||
for a in attachments:
|
||
icon = {
|
||
"AttachmentType.IMAGE": "🖼",
|
||
"AttachmentType.VIDEO": "🎬",
|
||
"AttachmentType.AUDIO": "🎙",
|
||
"AttachmentType.FILE": "📎",
|
||
}.get(a["attachment_type"], "📎")
|
||
line = f"{icon} {a['attachment_type'].split('.')[-1].capitalize()}"
|
||
if a.get("attachment_url"):
|
||
line += f": {a['attachment_url']}"
|
||
att_lines.append(line)
|
||
text += "\n\n📎 Вложения:\n" + "\n".join(att_lines)
|
||
|
||
await bot_send(
|
||
event.bot,
|
||
chat_id=chat_id,
|
||
user_id=bot_user["max_user_id"],
|
||
text=text,
|
||
attachments=[ticket_detail_kb(page=0)],
|
||
)
|