57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.user import User
|
|
|
|
DEFAULT_PAGE_SIZE = 20
|
|
MAX_PAGE_SIZE = 200
|
|
|
|
|
|
class AgentUserError(Exception):
|
|
def __init__(self, message: str) -> None:
|
|
self.message = message
|
|
super().__init__(message)
|
|
|
|
|
|
def _list_users_filters(
|
|
*,
|
|
agent_id: int,
|
|
username: str | None = None,
|
|
role_id: int | None = None,
|
|
) -> list:
|
|
conditions = [User.agent_id == agent_id]
|
|
if username and username.strip():
|
|
conditions.append(User.username.ilike(f"%{username.strip()}%"))
|
|
if role_id is not None:
|
|
conditions.append(User.role_id == role_id)
|
|
return conditions
|
|
|
|
|
|
async def list_users(
|
|
db: AsyncSession,
|
|
*,
|
|
agent_id: int,
|
|
page: int = 1,
|
|
page_size: int = DEFAULT_PAGE_SIZE,
|
|
username: str | None = None,
|
|
role_id: int | None = None,
|
|
) -> tuple[list[User], int]:
|
|
page_size = min(max(page_size, 1), MAX_PAGE_SIZE)
|
|
page = max(page, 1)
|
|
offset = (page - 1) * page_size
|
|
conditions = _list_users_filters(
|
|
agent_id=agent_id,
|
|
username=username,
|
|
role_id=role_id,
|
|
)
|
|
|
|
count_stmt = select(func.count()).select_from(User)
|
|
list_stmt = select(User).order_by(User.id.desc())
|
|
if conditions:
|
|
count_stmt = count_stmt.where(*conditions)
|
|
list_stmt = list_stmt.where(*conditions)
|
|
|
|
total = await db.scalar(count_stmt) or 0
|
|
result = await db.scalars(list_stmt.offset(offset).limit(page_size))
|
|
return list(result.all()), total
|