feat: добавлено управление сообщениями пользователей в админ-панель
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Добавлена кнопка 'Сообщения пользователей' в админ меню - Реализован просмотр последних сообщений с фильтрацией - Возможность просмотра медиа (фото, видео) прямо в боте - Функция удаления сообщений администратором - Удаление происходит как в БД, так и у пользователей в Telegram - Просмотр всех сообщений конкретного пользователя - Добавлены методы в ChatMessageService и UserService - Метод get_user_messages_all для получения всех сообщений - Метод mark_as_deleted для пометки сообщений как удаленных - Метод count_messages для подсчета количества сообщений - Метод get_user_by_id в UserService
This commit is contained in:
@@ -284,6 +284,58 @@ class ChatMessageService:
|
||||
|
||||
result = await session.execute(query)
|
||||
return result.scalars().all()
|
||||
|
||||
@staticmethod
|
||||
async def get_user_messages_all(
|
||||
session: AsyncSession,
|
||||
limit: int = 50,
|
||||
offset: int = 0,
|
||||
include_deleted: bool = False
|
||||
) -> List[ChatMessage]:
|
||||
"""Получить последние сообщения всех пользователей"""
|
||||
query = select(ChatMessage).options(selectinload(ChatMessage.sender))
|
||||
|
||||
if not include_deleted:
|
||||
query = query.where(ChatMessage.is_deleted == False)
|
||||
|
||||
query = query.order_by(ChatMessage.created_at.desc()).limit(limit).offset(offset)
|
||||
|
||||
result = await session.execute(query)
|
||||
return result.scalars().all()
|
||||
|
||||
@staticmethod
|
||||
async def count_messages(
|
||||
session: AsyncSession,
|
||||
include_deleted: bool = False
|
||||
) -> int:
|
||||
"""Подсчитать количество сообщений"""
|
||||
from sqlalchemy import func
|
||||
query = select(func.count(ChatMessage.id))
|
||||
|
||||
if not include_deleted:
|
||||
query = query.where(ChatMessage.is_deleted == False)
|
||||
|
||||
result = await session.execute(query)
|
||||
return result.scalar() or 0
|
||||
|
||||
@staticmethod
|
||||
async def mark_as_deleted(
|
||||
session: AsyncSession,
|
||||
message_id: int,
|
||||
deleted_by: int
|
||||
) -> bool:
|
||||
"""Пометить сообщение как удаленное"""
|
||||
result = await session.execute(
|
||||
update(ChatMessage)
|
||||
.where(ChatMessage.id == message_id)
|
||||
.values(
|
||||
is_deleted=True,
|
||||
deleted_by=deleted_by,
|
||||
deleted_at=datetime.now(timezone.utc)
|
||||
)
|
||||
)
|
||||
await session.commit()
|
||||
return result.rowcount > 0
|
||||
|
||||
|
||||
class ChatPermissionService:
|
||||
|
||||
@@ -49,6 +49,12 @@ class UserService:
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def get_user_by_id(session: AsyncSession, user_id: int) -> Optional[User]:
|
||||
"""Получить пользователя по ID"""
|
||||
result = await session.execute(select(User).where(User.id == user_id))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def get_user_by_username(session: AsyncSession, username: str) -> Optional[User]:
|
||||
"""Получить пользователя по username"""
|
||||
|
||||
Reference in New Issue
Block a user