""" Управление телефонами пользователей """ import logging import re from aiogram import Router, F from aiogram.types import Message from aiogram.filters import Command from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from database.db import AsyncSessionLocal from database.models import User from utils.decorators import admin_only from utils.validators import validate_phone, normalize_phone logger = logging.getLogger(__name__) router = Router() def format_phone_display(phone: str) -> str: """Форматирование телефона для отображения""" if not phone: return 'не указан' # Добавляем кликабельную ссылку tel: cleaned = re.sub(r'[^\d+]', '', phone) return f'{phone}' @router.message(Command('add_phone')) @admin_only async def cmd_add_phone(message: Message): """ Добавить телефон пользователю Использование: /add_phone <телефон> """ args = message.text.split(maxsplit=2) if len(args) < 3: await message.answer( 'Использование: /add_phone <user_id> <телефон>\n\n' 'Пример: /add_phone 123456789 +7 (999) 123-45-67', parse_mode='HTML' ) return try: user_id = int(args[1]) except ValueError: await message.answer('❌ Неверный ID пользователя') return phone = args[2].strip() if not validate_phone(phone): await message.answer('❌ Неверный формат телефона\n\nПример: +7 (999) 123-45-67') return # Нормализуем телефон phone = normalize_phone(phone) async with AsyncSessionLocal() as session: # Находим пользователя stmt = select(User).where(User.user_id == user_id) result = await session.execute(stmt) user = result.scalar_one_or_none() if not user: await message.answer('❌ Пользователь не найден') return # Добавляем телефон user.phone = phone await session.commit() logger.info(f'Добавлен телефон пользователю {user_id}: {phone}') await message.answer( f'✅ Телефон добавлен\n\n' f'Пользователь: {user.full_name}\n' f'ID: {user_id}\n' f'Телефон: {phone}\n\n' f'💡 Теперь можно позвонить кликом!', parse_mode='HTML' ) @router.message(Command('edit_phone')) @admin_only async def cmd_edit_phone(message: Message): """ Изменить телефон пользователю Использование: /edit_phone <телефон> """ args = message.text.split(maxsplit=2) if len(args) < 3: await message.answer( 'Использование: /edit_phone <user_id> <телефон>\n\n' 'Пример: /edit_phone 123456789 +7 (999) 999-99-99', parse_mode='HTML' ) return try: user_id = int(args[1]) except ValueError: await message.answer('❌ Неверный ID пользователя') return phone = args[2].strip() if not validate_phone(phone): await message.answer('❌ Неверный формат телефона') return phone = normalize_phone(phone) async with AsyncSessionLocal() as session: stmt = select(User).where(User.user_id == user_id) result = await session.execute(stmt) user = result.scalar_one_or_none() if not user: await message.answer('❌ Пользователь не найден') return old_phone = user.phone user.phone = phone await session.commit() logger.info(f'Изменён телефон пользователю {user_id}: {old_phone} → {phone}') await message.answer( f'✅ Телефон изменён\n\n' f'Пользователь: {user.full_name}\n' f'ID: {user_id}\n' f'Было: {old_phone or "не указан"}\n' f'Стало: {phone}', parse_mode='HTML' ) @router.message(Command('remove_phone')) @router.message(Command('del_phone')) @admin_only async def cmd_remove_phone(message: Message): """ Удалить телефон у пользователя Использование: /remove_phone """ args = message.text.split() if len(args) < 2: await message.answer( 'Использование: /remove_phone <user_id>\n\n' 'Пример: /remove_phone 123456789', parse_mode='HTML' ) return try: user_id = int(args[1]) except ValueError: await message.answer('❌ Неверный ID пользователя') return async with AsyncSessionLocal() as session: stmt = select(User).where(User.user_id == user_id) result = await session.execute(stmt) user = result.scalar_one_or_none() if not user: await message.answer('❌ Пользователь не найден') return old_phone = user.phone user.phone = None await session.commit() logger.info(f'Удалён телефон пользователю {user_id}: {old_phone}') await message.answer( f'✅ Телефон удалён\n\n' f'Пользователь: {user.full_name}\n' f'ID: {user_id}\n' f'Был: {old_phone or "не указан"}', parse_mode='HTML' ) @router.message(Command('myphone')) async def cmd_myphone(message: Message): """ Добавить/изменить свой телефон (для жильцов) Использование: /myphone +7 (999) 123-45-67 """ args = message.text.split(maxsplit=1) if len(args) < 2: # Показываем текущий телефон async with AsyncSessionLocal() as session: stmt = select(User).where(User.user_id == message.from_user.id) result = await session.execute(stmt) user = result.scalar_one_or_none() if user and user.phone: await message.answer( f'📱 Ваш телефон\n\n' f'{user.phone}\n\n' f'Чтобы изменить: /myphone +7 (999) 123-45-67', parse_mode='HTML' ) else: await message.answer( '📱 Ваш телефон не указан\n\n' 'Добавьте телефон командой:\n' '/myphone +7 (999) 123-45-67\n\n' 'Это поможет соседям связаться с вами!', parse_mode='HTML' ) return phone = args[1].strip() if not validate_phone(phone): await message.answer('❌ Неверный формат телефона\n\nПример: +7 (999) 123-45-67') return phone = normalize_phone(phone) async with AsyncSessionLocal() as session: stmt = select(User).where(User.user_id == message.from_user.id) result = await session.execute(stmt) user = result.scalar_one_or_none() if not user: await message.answer('❌ Вы не зарегистрированы. Нажмите /start') return old_phone = user.phone user.phone = phone await session.commit() logger.info(f'Пользователь {message.from_user.id} установил телефон: {phone}') await message.answer( f'✅ Телефон сохранён\n\n' f'{phone}\n\n' f'Теперь соседи могут связаться с вами!', parse_mode='HTML' ) @router.message(Command('phone')) @admin_only async def cmd_phone_info(message: Message): """ Показать телефон пользователя Использование: /phone """ args = message.text.split() if len(args) < 2: await message.answer( 'Использование: /phone <user_id>\n\n' 'Пример: /phone 123456789', parse_mode='HTML' ) return try: user_id = int(args[1]) except ValueError: await message.answer('❌ Неверный ID пользователя') return async with AsyncSessionLocal() as session: stmt = select(User).where(User.user_id == user_id) result = await session.execute(stmt) user = result.scalar_one_or_none() if not user: await message.answer('❌ Пользователь не найден') return phone_text = format_phone_display(user.phone) await message.answer( f'📱 Телефон\n\n' f'Пользователь: {user.full_name}\n' f'Квартира: {user.apartment or "не указана"}\n' f'Телефон: {phone_text}\n\n' f'💡 Нажмите на номер чтобы позвонить!', parse_mode='HTML' )