fix: исправлена обработка редактирования розыгрышей
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Добавлен обработчик handle_edit_field для admin_edit_field_{id}_{field} callbacks
- Исправлен toggle_lottery_active - теперь передаёт state вместо None
- Правильный парсинг lottery_id из позиции 3, а не с конца строки
- Обработка 'message is not modified' в bot_controller
- Модифицированы обработчики сообщений для поддержки редактирования
- Добавлен метод update_lottery в LotteryService
- Исправлены ошибки ValueError и AttributeError в меню редактирования
This commit is contained in:
1
Makefile
1
Makefile
@@ -138,7 +138,6 @@ clear-db:
|
|||||||
else \
|
else \
|
||||||
echo "❌ Отменено"; \
|
echo "❌ Отменено"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Очистка
|
# Очистка
|
||||||
clean:
|
clean:
|
||||||
@echo "🧹 Очистка временных файлов..."
|
@echo "🧹 Очистка временных файлов..."
|
||||||
|
|||||||
@@ -87,8 +87,21 @@ class BotController(IBotController):
|
|||||||
is_registered=user.is_registered
|
is_registered=user.is_registered
|
||||||
)
|
)
|
||||||
|
|
||||||
await callback.message.edit_text(
|
try:
|
||||||
text,
|
await callback.message.edit_text(
|
||||||
reply_markup=keyboard,
|
text,
|
||||||
parse_mode="Markdown"
|
reply_markup=keyboard,
|
||||||
)
|
parse_mode="Markdown"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
# Если сообщение не изменилось - просто отвечаем на callback
|
||||||
|
if "message is not modified" in str(e):
|
||||||
|
await callback.answer("✅ Уже показаны активные розыгрыши")
|
||||||
|
else:
|
||||||
|
# Другие ошибки - пробуем отправить новое сообщение
|
||||||
|
await callback.answer()
|
||||||
|
await callback.message.answer(
|
||||||
|
text,
|
||||||
|
reply_markup=keyboard,
|
||||||
|
parse_mode="Markdown"
|
||||||
|
)
|
||||||
@@ -227,6 +227,25 @@ class LotteryService:
|
|||||||
|
|
||||||
result = await session.execute(query)
|
result = await session.execute(query)
|
||||||
return result.scalars().all()
|
return result.scalars().all()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def update_lottery(
|
||||||
|
session: AsyncSession,
|
||||||
|
lottery_id: int,
|
||||||
|
**updates
|
||||||
|
) -> bool:
|
||||||
|
"""Обновить данные розыгрыша"""
|
||||||
|
try:
|
||||||
|
await session.execute(
|
||||||
|
update(Lottery)
|
||||||
|
.where(Lottery.id == lottery_id)
|
||||||
|
.values(**updates)
|
||||||
|
)
|
||||||
|
await session.commit()
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
await session.rollback()
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_all_lotteries(session: AsyncSession, limit: Optional[int] = None) -> List[Lottery]:
|
async def get_all_lotteries(session: AsyncSession, limit: Optional[int] = None) -> List[Lottery]:
|
||||||
|
|||||||
@@ -236,11 +236,41 @@ async def start_create_lottery(callback: CallbackQuery, state: FSMContext):
|
|||||||
|
|
||||||
@admin_router.message(StateFilter(AdminStates.lottery_title))
|
@admin_router.message(StateFilter(AdminStates.lottery_title))
|
||||||
async def process_lottery_title(message: Message, state: FSMContext):
|
async def process_lottery_title(message: Message, state: FSMContext):
|
||||||
"""Обработка названия розыгрыша"""
|
"""Обработка названия розыгрыша (создание или редактирование)"""
|
||||||
if not is_admin(message.from_user.id):
|
if not is_admin(message.from_user.id):
|
||||||
await message.answer("❌ Недостаточно прав")
|
await message.answer("❌ Недостаточно прав")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
data = await state.get_data()
|
||||||
|
edit_lottery_id = data.get('edit_lottery_id')
|
||||||
|
|
||||||
|
# Если это редактирование существующего розыгрыша
|
||||||
|
if edit_lottery_id:
|
||||||
|
async with async_session_maker() as session:
|
||||||
|
success = await LotteryService.update_lottery(
|
||||||
|
session,
|
||||||
|
edit_lottery_id,
|
||||||
|
title=message.text
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
await message.answer(f"✅ Название изменено на: {message.text}")
|
||||||
|
await state.clear()
|
||||||
|
# Возвращаемся к выбору полей
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
fake_callback = CallbackQuery(
|
||||||
|
id="fake",
|
||||||
|
from_user=message.from_user,
|
||||||
|
chat_instance="fake",
|
||||||
|
data=f"admin_edit_lottery_select_{edit_lottery_id}",
|
||||||
|
message=message
|
||||||
|
)
|
||||||
|
await choose_edit_field(fake_callback, state)
|
||||||
|
else:
|
||||||
|
await message.answer("❌ Ошибка при изменении названия")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Если это создание нового розыгрыша
|
||||||
await state.update_data(title=message.text)
|
await state.update_data(title=message.text)
|
||||||
|
|
||||||
text = f"📝 Создание нового розыгрыша\n\n"
|
text = f"📝 Создание нового розыгрыша\n\n"
|
||||||
@@ -254,11 +284,42 @@ async def process_lottery_title(message: Message, state: FSMContext):
|
|||||||
|
|
||||||
@admin_router.message(StateFilter(AdminStates.lottery_description))
|
@admin_router.message(StateFilter(AdminStates.lottery_description))
|
||||||
async def process_lottery_description(message: Message, state: FSMContext):
|
async def process_lottery_description(message: Message, state: FSMContext):
|
||||||
"""Обработка описания розыгрыша"""
|
"""Обработка описания розыгрыша (создание или редактирование)"""
|
||||||
if not is_admin(message.from_user.id):
|
if not is_admin(message.from_user.id):
|
||||||
await message.answer("❌ Недостаточно прав")
|
await message.answer("❌ Недостаточно прав")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
data = await state.get_data()
|
||||||
|
edit_lottery_id = data.get('edit_lottery_id')
|
||||||
|
|
||||||
|
# Если это редактирование существующего розыгрыша
|
||||||
|
if edit_lottery_id:
|
||||||
|
description = None if message.text == "-" else message.text
|
||||||
|
async with async_session_maker() as session:
|
||||||
|
success = await LotteryService.update_lottery(
|
||||||
|
session,
|
||||||
|
edit_lottery_id,
|
||||||
|
description=description
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
await message.answer(f"✅ Описание изменено")
|
||||||
|
await state.clear()
|
||||||
|
# Возвращаемся к выбору полей
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
fake_callback = CallbackQuery(
|
||||||
|
id="fake",
|
||||||
|
from_user=message.from_user,
|
||||||
|
chat_instance="fake",
|
||||||
|
data=f"admin_edit_lottery_select_{edit_lottery_id}",
|
||||||
|
message=message
|
||||||
|
)
|
||||||
|
await choose_edit_field(fake_callback, state)
|
||||||
|
else:
|
||||||
|
await message.answer("❌ Ошибка при изменении описания")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Если это создание нового розыгрыша
|
||||||
description = None if message.text == "-" else message.text
|
description = None if message.text == "-" else message.text
|
||||||
await state.update_data(description=description)
|
await state.update_data(description=description)
|
||||||
|
|
||||||
@@ -281,12 +342,43 @@ async def process_lottery_description(message: Message, state: FSMContext):
|
|||||||
|
|
||||||
@admin_router.message(StateFilter(AdminStates.lottery_prizes))
|
@admin_router.message(StateFilter(AdminStates.lottery_prizes))
|
||||||
async def process_lottery_prizes(message: Message, state: FSMContext):
|
async def process_lottery_prizes(message: Message, state: FSMContext):
|
||||||
"""Обработка призов розыгрыша"""
|
"""Обработка призов розыгрыша (создание или редактирование)"""
|
||||||
if not is_admin(message.from_user.id):
|
if not is_admin(message.from_user.id):
|
||||||
await message.answer("❌ Недостаточно прав")
|
await message.answer("❌ Недостаточно прав")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
data = await state.get_data()
|
||||||
|
edit_lottery_id = data.get('edit_lottery_id')
|
||||||
|
|
||||||
prizes = [prize.strip() for prize in message.text.split('\n') if prize.strip()]
|
prizes = [prize.strip() for prize in message.text.split('\n') if prize.strip()]
|
||||||
|
|
||||||
|
# Если это редактирование существующего розыгрыша
|
||||||
|
if edit_lottery_id:
|
||||||
|
async with async_session_maker() as session:
|
||||||
|
success = await LotteryService.update_lottery(
|
||||||
|
session,
|
||||||
|
edit_lottery_id,
|
||||||
|
prizes=prizes
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
await message.answer(f"✅ Призы изменены")
|
||||||
|
await state.clear()
|
||||||
|
# Возвращаемся к выбору полей
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
fake_callback = CallbackQuery(
|
||||||
|
id="fake",
|
||||||
|
from_user=message.from_user,
|
||||||
|
chat_instance="fake",
|
||||||
|
data=f"admin_edit_lottery_select_{edit_lottery_id}",
|
||||||
|
message=message
|
||||||
|
)
|
||||||
|
await choose_edit_field(fake_callback, state)
|
||||||
|
else:
|
||||||
|
await message.answer("❌ Ошибка при изменении призов")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Если это создание нового розыгрыша
|
||||||
await state.update_data(prizes=prizes)
|
await state.update_data(prizes=prizes)
|
||||||
|
|
||||||
data = await state.get_data()
|
data = await state.get_data()
|
||||||
@@ -1775,8 +1867,49 @@ async def choose_edit_field(callback: CallbackQuery, state: FSMContext):
|
|||||||
await callback.message.edit_text(text, reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))
|
await callback.message.edit_text(text, reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))
|
||||||
|
|
||||||
|
|
||||||
|
@admin_router.callback_query(F.data.startswith("admin_edit_field_"))
|
||||||
|
async def handle_edit_field(callback: CallbackQuery, state: FSMContext):
|
||||||
|
"""Обработка выбора поля для редактирования"""
|
||||||
|
if not is_admin(callback.from_user.id):
|
||||||
|
await callback.answer("❌ Недостаточно прав", show_alert=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Парсим callback_data: admin_edit_field_{lottery_id}_{field_name}
|
||||||
|
parts = callback.data.split("_")
|
||||||
|
if len(parts) < 5:
|
||||||
|
await callback.answer("❌ Неверный формат данных", show_alert=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
lottery_id = int(parts[3]) # admin_edit_field_{lottery_id}_...
|
||||||
|
field_name = "_".join(parts[4:]) # Всё после lottery_id это имя поля
|
||||||
|
|
||||||
|
await state.update_data(edit_lottery_id=lottery_id, edit_field=field_name)
|
||||||
|
|
||||||
|
# Определяем, что редактируем
|
||||||
|
if field_name == "title":
|
||||||
|
text = "📝 Введите новое название розыгрыша:"
|
||||||
|
await state.set_state(AdminStates.lottery_title)
|
||||||
|
elif field_name == "description":
|
||||||
|
text = "📄 Введите новое описание розыгрыша:"
|
||||||
|
await state.set_state(AdminStates.lottery_description)
|
||||||
|
elif field_name == "prizes":
|
||||||
|
text = "🎁 Введите новый список призов (каждый приз с новой строки):"
|
||||||
|
await state.set_state(AdminStates.lottery_prizes)
|
||||||
|
else:
|
||||||
|
await callback.answer("❌ Неизвестное поле", show_alert=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
await callback.message.edit_text(
|
||||||
|
text,
|
||||||
|
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||||||
|
[InlineKeyboardButton(text="❌ Отмена", callback_data="admin_lotteries")]
|
||||||
|
])
|
||||||
|
)
|
||||||
|
await callback.answer()
|
||||||
|
|
||||||
|
|
||||||
@admin_router.callback_query(F.data.startswith("admin_toggle_active_"))
|
@admin_router.callback_query(F.data.startswith("admin_toggle_active_"))
|
||||||
async def toggle_lottery_active(callback: CallbackQuery):
|
async def toggle_lottery_active(callback: CallbackQuery, state: FSMContext):
|
||||||
"""Переключить активность розыгрыша"""
|
"""Переключить активность розыгрыша"""
|
||||||
if not is_admin(callback.from_user.id):
|
if not is_admin(callback.from_user.id):
|
||||||
await callback.answer("❌ Недостаточно прав", show_alert=True)
|
await callback.answer("❌ Недостаточно прав", show_alert=True)
|
||||||
@@ -1798,7 +1931,7 @@ async def toggle_lottery_active(callback: CallbackQuery):
|
|||||||
await callback.answer("❌ Ошибка изменения статуса", show_alert=True)
|
await callback.answer("❌ Ошибка изменения статуса", show_alert=True)
|
||||||
|
|
||||||
# Обновляем отображение
|
# Обновляем отображение
|
||||||
await choose_edit_field(callback, None)
|
await choose_edit_field(callback, state)
|
||||||
|
|
||||||
|
|
||||||
@admin_router.callback_query(F.data == "admin_finish_lottery")
|
@admin_router.callback_query(F.data == "admin_finish_lottery")
|
||||||
|
|||||||
Reference in New Issue
Block a user