From 4b436a3d1212bdd355925a8f3f8fea1f143fd7fa Mon Sep 17 00:00:00 2001 From: Zakhar Izmaylov Date: Wed, 15 Jan 2025 02:39:01 +0300 Subject: [PATCH] Add page coupons --- database.py | 39 +++++++++++++++++++++--------- handlers/admin/admin_coupons.py | 43 +++++++++++++++++---------------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/database.py b/database.py index c7caa99e..92db1b6e 100644 --- a/database.py +++ b/database.py @@ -114,35 +114,52 @@ async def create_coupon( raise -async def get_all_coupons(session: Any): +async def get_all_coupons(session: Any, page: int = 1, per_page: int = 10): """ - Получает список всех купонов из базы данных. + Получает список купонов из базы данных с пагинацией. + + Args: + session (Any): Сессия базы данных для выполнения запроса + page (int): Номер страницы (по умолчанию 1) + per_page (int): Количество купонов на странице (по умолчанию 10) Returns: - list: Список словарей с информацией о купонах, каждый словарь содержит: - - code (str): Код купона - - amount (int): Сумма купона - - usage_limit (int): Максимальное количество использований - - usage_count (int): Текущее количество использований купона + dict: Словарь с информацией о купонах и пагинации: + - coupons (list): Список словарей с информацией о купонах + - total (int): Общее количество купонов + - pages (int): Общее количество страниц + - current_page (int): Текущая страница Raises: Exception: В случае ошибки при получении данных из базы """ try: + offset = (page - 1) * per_page coupons = await session.fetch( """ SELECT code, amount, usage_limit, usage_count FROM coupons - """ + ORDER BY id + LIMIT $1 OFFSET $2 + """, + per_page, offset ) - logger.info(f"Успешно получено {len(coupons)} купонов из базы данных") + total_count = await session.fetchval("SELECT COUNT(*) FROM coupons") + total_pages = -(-total_count // per_page) # Округление вверх - return coupons + logger.info(f"Успешно получено {len(coupons)} купонов из базы данных (страница {page})") + + return { + "coupons": coupons, + "total": total_count, + "pages": total_pages, + "current_page": page + } except Exception as e: logger.error(f"Критическая ошибка при получении списка купонов: {e}") logger.exception("Трассировка стека ошибки получения купонов") - return [] + return {"coupons": [], "total": 0, "pages": 0, "current_page": page} async def delete_coupon_from_db(coupon_code: str, session: Any): diff --git a/handlers/admin/admin_coupons.py b/handlers/admin/admin_coupons.py index 27e3071e..f060acb7 100644 --- a/handlers/admin/admin_coupons.py +++ b/handlers/admin/admin_coupons.py @@ -27,31 +27,33 @@ async def show_coupon_management_menu( builder.row( InlineKeyboardButton(text="➕ Создать купон", callback_data="create_coupon") ) - builder.row(InlineKeyboardButton(text="Купоны", callback_data="coupons")) + builder.row(InlineKeyboardButton(text="🎟️ Купоны", callback_data="coupons")) builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="admin")) await callback_query.message.answer( "🛠 Меню управления купонами:", reply_markup=builder.as_markup() ) -@router.callback_query(F.data == "coupons", IsAdminFilter()) +@router.callback_query(F.data.startswith("coupons"), IsAdminFilter()) async def show_coupon_list(callback_query: types.CallbackQuery, session: Any): try: - coupons = await get_all_coupons(session) + page = int(callback_query.data.split(':')[1]) if ':' in callback_query.data else 1 + per_page = 10 + result = await get_all_coupons(session, page, per_page) + coupons = result["coupons"] + total_pages = result["pages"] + current_page = result["current_page"] if not coupons: builder = InlineKeyboardBuilder() - builder.row( - InlineKeyboardButton(text="🔙 Назад", callback_data="coupons_editor") - ) - + builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="coupons_editor")) await callback_query.message.answer( "❌ На данный момент нет доступных купонов. 🚫\nВы можете вернуться в меню управления. 🔙", reply_markup=builder.as_markup(), ) return - coupon_list = "📜 Список всех купонов:\n\n" + coupon_list = f"📜 Список купонов (страница {current_page} из {total_pages}):\n\n" builder = InlineKeyboardBuilder() for coupon in coupons: @@ -61,23 +63,22 @@ async def show_coupon_list(callback_query: types.CallbackQuery, session: Any): f"🔢 Лимит использования: {coupon['usage_limit']} раз\n" f"✅ Использовано: {coupon['usage_count']} раз\n\n" ) + builder.row(InlineKeyboardButton( + text=f"❌ Удалить {coupon['code']}", + callback_data=f"delete_coupon_{coupon['code']}" + )) - builder.row( - InlineKeyboardButton( - text=f"❌ Удалить {coupon['code']}", - callback_data=f"delete_coupon_{coupon['code']}", - ) - ) - - builder.row( - InlineKeyboardButton(text="🔙 Назад", callback_data="coupons_editor") - ) - await callback_query.message.answer( - coupon_list, reply_markup=builder.as_markup() - ) + if current_page > 1: + builder.row(InlineKeyboardButton(text="⬅️ Предыдущая", callback_data=f"coupons:{current_page-1}")) + if current_page < total_pages: + builder.row(InlineKeyboardButton(text="➡️ Следующая", callback_data=f"coupons:{current_page+1}")) + + builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="coupons_editor")) + await callback_query.message.answer(coupon_list, reply_markup=builder.as_markup()) except Exception as e: logger.error(f"Ошибка при получении списка купонов: {e}") + await callback_query.message.answer("Произошла ошибка при получении списка купонов.") @router.callback_query(F.data.startswith("delete_coupon_"), IsAdminFilter())