from aiogram import Router, F from aiogram.filters import Command from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup from database.db import async_session_maker from services.user_service import UserService from services.task_service import TaskService from services.ai_service import ai_service router = Router() class TaskStates(StatesGroup): """Состояния для прохождения заданий""" doing_tasks = State() waiting_for_answer = State() @router.message(Command("task")) async def cmd_task(message: Message, state: FSMContext): """Обработчик команды /task""" async with async_session_maker() as session: user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: await message.answer("Сначала запусти бота командой /start") return # Генерируем задания tasks = await TaskService.generate_translation_tasks(session, user.id, count=5) if not tasks: await message.answer( "📚 У тебя пока нет слов для практики!\n\n" "Добавь несколько слов командой /add, а затем возвращайся." ) return # Сохраняем задания в состоянии await state.update_data( tasks=tasks, current_task_index=0, correct_count=0, user_id=user.id ) await state.set_state(TaskStates.doing_tasks) # Показываем первое задание await show_current_task(message, state) async def show_current_task(message: Message, state: FSMContext): """Показать текущее задание""" data = await state.get_data() tasks = data.get('tasks', []) current_index = data.get('current_task_index', 0) if current_index >= len(tasks): # Все задания выполнены await finish_tasks(message, state) return task = tasks[current_index] task_text = ( f"📝 Задание {current_index + 1} из {len(tasks)}\n\n" f"{task['question']}\n" ) if task.get('transcription'): task_text += f"🔊 [{task['transcription']}]\n" task_text += f"\n💡 Напиши свой ответ:" await state.set_state(TaskStates.waiting_for_answer) await message.answer(task_text) @router.message(TaskStates.waiting_for_answer) async def process_answer(message: Message, state: FSMContext): """Обработка ответа пользователя""" user_answer = message.text.strip() data = await state.get_data() tasks = data.get('tasks', []) current_index = data.get('current_task_index', 0) correct_count = data.get('correct_count', 0) user_id = data.get('user_id') task = tasks[current_index] # Показываем индикатор проверки checking_msg = await message.answer("⏳ Проверяю ответ...") # Проверяем ответ через AI check_result = await ai_service.check_answer( question=task['question'], correct_answer=task['correct_answer'], user_answer=user_answer ) await checking_msg.delete() is_correct = check_result.get('is_correct', False) feedback = check_result.get('feedback', '') # Формируем ответ if is_correct: result_text = f"✅ Правильно!\n\n" correct_count += 1 else: result_text = f"❌ Неправильно\n\n" result_text += f"Твой ответ: {user_answer}\n" result_text += f"Правильный ответ: {task['correct_answer']}\n\n" if feedback: result_text += f"💬 {feedback}\n\n" # Сохраняем результат в БД async with async_session_maker() as session: await TaskService.save_task_result( session=session, user_id=user_id, task_type=task['type'], content={ 'question': task['question'], 'word': task['word'] }, user_answer=user_answer, correct_answer=task['correct_answer'], is_correct=is_correct, ai_feedback=feedback ) # Обновляем статистику слова if 'word_id' in task: await TaskService.update_word_statistics( session=session, word_id=task['word_id'], is_correct=is_correct ) # Обновляем счетчик await state.update_data( current_task_index=current_index + 1, correct_count=correct_count ) # Показываем результат и кнопку "Далее" keyboard = InlineKeyboardMarkup(inline_keyboard=[ [InlineKeyboardButton(text="➡️ Следующее задание", callback_data="next_task")] ]) await message.answer(result_text, reply_markup=keyboard) @router.callback_query(F.data == "next_task", TaskStates.doing_tasks) async def next_task(callback: CallbackQuery, state: FSMContext): """Переход к следующему заданию""" await callback.message.delete() await show_current_task(callback.message, state) await callback.answer() async def finish_tasks(message: Message, state: FSMContext): """Завершение всех заданий""" data = await state.get_data() tasks = data.get('tasks', []) correct_count = data.get('correct_count', 0) total_count = len(tasks) accuracy = int((correct_count / total_count) * 100) if total_count > 0 else 0 # Определяем эмодзи на основе результата if accuracy >= 90: emoji = "🏆" comment = "Отличный результат!" elif accuracy >= 70: emoji = "👍" comment = "Хорошая работа!" elif accuracy >= 50: emoji = "📚" comment = "Неплохо, продолжай практиковаться!" else: emoji = "💪" comment = "Повтори эти слова еще раз!" result_text = ( f"{emoji} Задание завершено!\n\n" f"Правильных ответов: {correct_count} из {total_count}\n" f"Точность: {accuracy}%\n\n" f"{comment}\n\n" f"Используй /task для нового задания\n" f"Используй /stats для просмотра статистики" ) await state.clear() await message.answer(result_text) @router.message(Command("stats")) async def cmd_stats(message: Message): """Обработчик команды /stats""" async with async_session_maker() as session: user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: await message.answer("Сначала запусти бота командой /start") return # Получаем статистику stats = await TaskService.get_user_stats(session, user.id) stats_text = ( f"📊 Твоя статистика\n\n" f"📚 Слов в словаре: {stats['total_words']}\n" f"📖 Слов изучено: {stats['reviewed_words']}\n" f"✍️ Заданий выполнено: {stats['total_tasks']}\n" f"✅ Правильных ответов: {stats['correct_tasks']}\n" f"🎯 Точность: {stats['accuracy']}%\n\n" ) if stats['total_words'] == 0: stats_text += "Добавь слова командой /add чтобы начать обучение!" elif stats['total_tasks'] == 0: stats_text += "Выполни первое задание командой /task!" else: stats_text += "Продолжай практиковаться! 💪" await message.answer(stats_text)