✅ Регистрация и верификация жильцов ✅ Рейтинг активности (уровни) ✅ Детект шпионов (Score 0-100) ✅ Анти-мат система (3 предупреждения → бан) ✅ Админ-панель с рассылкой ✅ Учёт квартир (несколько жильцов) ✅ Телефоны экстренных служб и мастеров ✅ Еженедельный экспорт JSON ✅ Прокси (socks5) для обхода РКН Бекап: backups/versions/v1.0_mvp_2026-02-26/ Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
200 lines
7.1 KiB
Python
200 lines
7.1 KiB
Python
"""
|
||
Achievements — достижения пользователей
|
||
"""
|
||
import logging
|
||
from aiogram import Router, F
|
||
from aiogram.types import Message
|
||
from aiogram.filters import Command
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from database.db import AsyncSessionLocal
|
||
from services.achievements import AchievementsService
|
||
from utils.decorators import admin_only
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
router = Router()
|
||
|
||
|
||
# =============================================================================
|
||
# МОИ ДОСТИЖЕНИЯ
|
||
# =============================================================================
|
||
|
||
@router.message(Command('achievements'))
|
||
@router.message(Command('достижения'))
|
||
async def cmd_achievements(message: Message):
|
||
"""Показать свои достижения"""
|
||
user_id = message.from_user.id
|
||
|
||
async with AsyncSessionLocal() as session:
|
||
service = AchievementsService(session)
|
||
achievements = await service.get_user_achievements(user_id)
|
||
|
||
if not achievements:
|
||
await message.answer(
|
||
'🏆 <b>Ваши достижения</b>\n\n'
|
||
'Пока нет достижений.\n\n'
|
||
'Получайте достижения за:\n'
|
||
'• Активность в чате\n'
|
||
'• Верификацию\n'
|
||
'• Высокий рейтинг\n'
|
||
'• Участие в опросах\n'
|
||
'• Публикацию объявлений',
|
||
parse_mode='HTML'
|
||
)
|
||
return
|
||
|
||
# Группируем по категориям
|
||
by_category = {}
|
||
for ach in achievements:
|
||
cat = ach['category']
|
||
if cat not in by_category:
|
||
by_category[cat] = []
|
||
by_category[cat].append(ach)
|
||
|
||
text = '🏆 <b>Ваши достижения</b>\n\n'
|
||
text += f'Всего: {len(achievements)}\n\n'
|
||
|
||
category_names = {
|
||
'activity': '📝 Активность',
|
||
'verification': '✅ Верификация',
|
||
'rating': '⭐ Рейтинг',
|
||
'time': '⏰ Время',
|
||
'social': '🤝 Социальные',
|
||
'security': '🔒 Безопасность',
|
||
'streak': '📅 Серии',
|
||
'polls': '📊 Опросы',
|
||
'ads': '📢 Объявления'
|
||
}
|
||
|
||
for cat, cats_achievements in by_category.items():
|
||
cat_name = category_names.get(cat, cat.capitalize())
|
||
text += f'<b>{cat_name}</b>\n'
|
||
|
||
for ach in cats_achievements:
|
||
text += f" {ach['emoji']} {ach['name']}\n"
|
||
|
||
text += '\n'
|
||
|
||
await message.answer(text, parse_mode='HTML')
|
||
|
||
|
||
# =============================================================================
|
||
# ТОП ПО ДОСТИЖЕНИЯМ
|
||
# =============================================================================
|
||
|
||
@router.message(Command('achievements_top'))
|
||
@router.message(Command('топ_достижений'))
|
||
@admin_only
|
||
async def cmd_achievements_top(message: Message):
|
||
"""Топ пользователей по достижениям"""
|
||
async with AsyncSessionLocal() as session:
|
||
service = AchievementsService(session)
|
||
leaderboard = await service.get_leaderboard(10)
|
||
|
||
if not leaderboard:
|
||
await message.answer('ℹ️ Пока нет достижений у пользователей')
|
||
return
|
||
|
||
text = '🏆 <b>Топ по достижениям</b>\n\n'
|
||
|
||
medals = ['🥇', '🥈', '🥉']
|
||
|
||
for i, user in enumerate(leaderboard):
|
||
medal = medals[i] if i < 3 else f'{i+1}.'
|
||
text += f'{medal} {user["name"]} (кв. {user["apartment"]}) — {user["achievements"]} достиж.\n'
|
||
|
||
await message.answer(text, parse_mode='HTML')
|
||
|
||
|
||
# =============================================================================
|
||
# СПИСОК ВСЕХ ДОСТИЖЕНИЙ
|
||
# =============================================================================
|
||
|
||
@router.message(Command('all_achievements'))
|
||
@router.message(Command('все_достижения'))
|
||
@admin_only
|
||
async def cmd_all_achievements(message: Message):
|
||
"""Список всех доступных достижений"""
|
||
async with AsyncSessionLocal() as session:
|
||
service = AchievementsService(session)
|
||
all_achievements = await service.get_all_achievements()
|
||
|
||
text = '🏆 <b>Все достижения</b>\n\n'
|
||
text += f'Всего: {len(all_achievements)}\n\n'
|
||
|
||
# Группируем по категориям
|
||
by_category = {}
|
||
for ach_type, ach_data in all_achievements.items():
|
||
cat = ach_data.get('category', 'other')
|
||
if cat not in by_category:
|
||
by_category[cat] = []
|
||
by_category[cat].append((ach_type, ach_data))
|
||
|
||
category_names = {
|
||
'activity': '📝 Активность',
|
||
'verification': '✅ Верификация',
|
||
'rating': '⭐ Рейтинг',
|
||
'time': '⏰ Время',
|
||
'social': '🤝 Социальные',
|
||
'security': '🔒 Безопасность',
|
||
'streak': '📅 Серии',
|
||
'polls': '📊 Опросы',
|
||
'ads': '📢 Объявления'
|
||
}
|
||
|
||
for cat, cats_achievements in sorted(by_category.items()):
|
||
cat_name = category_names.get(cat, cat.capitalize())
|
||
text += f'<b>{cat_name}</b>\n'
|
||
|
||
for ach_type, ach_data in cats_achievements:
|
||
text += f" {ach_data.get('emoji', '🏆')} {ach_data.get('name', ach_type)}\n"
|
||
text += f" └─ {ach_data.get('description', '')}\n"
|
||
|
||
text += '\n'
|
||
|
||
await message.answer(text, parse_mode='HTML')
|
||
|
||
|
||
# =============================================================================
|
||
# ДОСТИЖЕНИЯ ПОЛЬЗОВАТЕЛЯ
|
||
# =============================================================================
|
||
|
||
@router.message(Command('user_achievements'))
|
||
@router.message(Command('достижения_пользователя'))
|
||
@admin_only
|
||
async def cmd_user_achievements(message: Message):
|
||
"""
|
||
Показать достижения пользователя
|
||
Использование: /user_achievements <user_id>
|
||
"""
|
||
args = message.text.split()
|
||
if len(args) < 2:
|
||
await message.answer(
|
||
'❌ <b>Использование:</b>\n'
|
||
'<code>/user_achievements <user_id></code>',
|
||
parse_mode='HTML'
|
||
)
|
||
return
|
||
|
||
try:
|
||
user_id = int(args[1])
|
||
except ValueError:
|
||
await message.answer('❌ Неверный ID пользователя')
|
||
return
|
||
|
||
async with AsyncSessionLocal() as session:
|
||
service = AchievementsService(session)
|
||
achievements = await service.get_user_achievements(user_id)
|
||
|
||
if not achievements:
|
||
await message.answer(f'ℹ️ У пользователя {user_id} нет достижений')
|
||
return
|
||
|
||
text = f'🏆 <b>Достижения пользователя {user_id}</b>\n\n'
|
||
text += f'Всего: {len(achievements)}\n\n'
|
||
|
||
for ach in achievements:
|
||
text += f" {ach['emoji']} {ach['name']}\n"
|
||
text += f" └─ {ach['earned_at'][:10]}\n"
|
||
|
||
await message.answer(text, parse_mode='HTML')
|