import logging from aiogram import Router from aiogram.filters import Command from aiogram.types import Message from app import config from app.handlers.callbacks import _settings_keyboard from app.models import Settings from app.services import StatsService router = Router() logger = logging.getLogger(__name__) stats_service = StatsService() @router.message(Command("allstat", "stat")) async def cmd_stats(message: Message) -> None: is_all_time = message.text.startswith("/allstat") ozon_stats = ( await stats_service.get_all_time_stats("ozon") if is_all_time else await stats_service.get_daily_stats("ozon") ) wb_stats = ( await stats_service.get_all_time_stats("wb") if is_all_time else await stats_service.get_daily_stats("wb") ) ym_stats = ( await stats_service.get_all_time_stats("ym") if is_all_time else await stats_service.get_daily_stats("ym") ) period_text = "за все время" if is_all_time else "за сегодня" stats_text = f"📊 Статистика {period_text}\n\n" for platform_name, stats in [ ("Ozon", ozon_stats), ("Wildberries", wb_stats), ("Яндекс Маркет", ym_stats), ]: stats_text += ( f"{platform_name}:\n" f"Всего отзывов: {stats['total_reviews']}\n" f"Хороших: {stats['good_reviews']}\n" f"Плохих: {stats['bad_reviews']}\n" f"Доля плохих: {stats['bad_ratio']:.1%}\n" f"Средний рейтинг: {stats['average_rating']:.1f}\n" f"Критичных: {stats['critical_reviews']} ({stats['critical_ratio']:.1%} от всех, {stats['critical_to_bad_ratio']:.1%} от плохих)\n\n" f"Оценки:\n" f"⭐️ 1: {stats['ratings']['1']}\n" f"⭐️ 2: {stats['ratings']['2']}\n" f"⭐️ 3: {stats['ratings']['3']}\n" f"⭐️ 4: {stats['ratings']['4']}\n" f"⭐️ 5: {stats['ratings']['5']}\n\n" f"Тональность:\n" f"😊 Позитивная: {stats['tone']['positive']}\n" f"😐 Нейтральная: {stats['tone']['neutral']}\n" f"😠 Негативная: {stats['tone']['negative']}\n\n" ) await message.answer(stats_text, parse_mode="HTML") @router.message(Command("settings")) async def cmd_settings(message: Message) -> None: settings = await Settings.get_from_context( message_thread_id=message.message_thread_id ) await message.answer( ( f"⚙️ Настройки {'положительных' if settings.is_good else 'отрицательных'} отзывов\n\n" "/show_prompt - просмотр промптов\n" "/change_prompt - изменить промпт для аналитики\n" "/reset_prompt - сбросить промпт для аналитики\n" "/change_answer_prompt - изменить промпт для ответов на отзывы\n" "/reset_answer_prompt - сбросить промпт для ответов на отзывы\n\n" "Шаблоны для отзывов без текста:\n" "/template_low текст — шаблон для 1–3 ★\n" "/template_high текст — шаблон для 4–5 ★\n" "/show_templates — показать текущие шаблоны\n" ), reply_markup=_settings_keyboard(settings), parse_mode="HTML", ) @router.message(Command("show_templates")) async def cmd_show_templates(message: Message) -> None: """Показать текущие шаблоны ответа на отзывы без текста.""" settings = await Settings.get_from_context( message_thread_id=message.message_thread_id ) low = settings.template_empty_low_rating or config.TEMPLATE_EMPTY_LOW_RATING high = settings.template_empty_high_rating or config.TEMPLATE_EMPTY_HIGH_RATING await message.answer( "📝 Шаблоны для отзывов без текста\n\n" f"1–3 ★: {low}\n\n" f"4–5 ★: {high}\n\n" "Изменить: /template_low текст или /template_high текст", parse_mode="HTML", ) @router.message(Command("template_low")) async def cmd_template_low(message: Message) -> None: """Установить шаблон ответа для отзывов без текста с оценкой 1–3 звезды.""" text = (message.text or "").replace("/template_low", "").strip() if not text: await message.answer( "Введите текст шаблона после команды.\n" "Пример: /template_low Спасибо за отзыв, извините за неудобства." ) return for s in await Settings.all(): s.template_empty_low_rating = text await s.save() await message.answer(f"✅ Шаблон для 1–3 ★ сохранён:\n{text}", parse_mode="HTML") @router.message(Command("template_high")) async def cmd_template_high(message: Message) -> None: """Установить шаблон ответа для отзывов без текста с оценкой 4–5 звёзд.""" text = (message.text or "").replace("/template_high", "").strip() if not text: await message.answer( "Введите текст шаблона после команды.\n" "Пример: /template_high Спасибо за отзыв, рады что вам понравилось!" ) return for s in await Settings.all(): s.template_empty_high_rating = text await s.save() await message.answer(f"✅ Шаблон для 4–5 ★ сохранён:\n{text}", parse_mode="HTML") @router.message(Command("max_tokens")) async def cmd_max_tokens(message: Message) -> None: settings = await Settings.get_from_context( message_thread_id=message.message_thread_id ) args = message.text.split() if len(args) > 1 and args[1].isdigit(): value = int(args[1]) settings.max_tokens = value await settings.save() await message.answer(f"Лимит токенов установлен на {value}") return await message.answer( f"Текущий лимит токенов: {settings.max_tokens}\n" "Введите /max_tokens число, чтобы обновить его" )