from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.models.desktopConfig import DesktopConfig from app.schemas.admin_desktop_config import DesktopConfigCreate, DesktopConfigUpdate DEFAULT_PAGE_SIZE = 20 MAX_PAGE_SIZE = 200 class AdminDesktopConfigError(Exception): def __init__(self, message: str) -> None: self.message = message super().__init__(message) async def list_configs( db: AsyncSession, *, page: int = 1, page_size: int = DEFAULT_PAGE_SIZE, keyword: str | None = None, ) -> tuple[list[DesktopConfig], int]: page_size = min(max(page_size, 1), MAX_PAGE_SIZE) page = max(page, 1) offset = (page - 1) * page_size filters = [] if keyword: like = f"%{keyword.strip()}%" filters.append(DesktopConfig.name.ilike(like)) count_stmt = select(func.count()).select_from(DesktopConfig) list_stmt = select(DesktopConfig) for clause in filters: count_stmt = count_stmt.where(clause) list_stmt = list_stmt.where(clause) total = await db.scalar(count_stmt) or 0 result = await db.scalars( list_stmt.order_by(DesktopConfig.name.asc()).offset(offset).limit(page_size) ) return list(result.all()), total async def create_config(db: AsyncSession, body: DesktopConfigCreate) -> DesktopConfig: existing = await db.scalar( select(DesktopConfig).where( DesktopConfig.name == body.name, DesktopConfig.oem_id == body.oem_id, ) ) if existing is not None: raise AdminDesktopConfigError("该 OEM 下配置键名已存在") row = DesktopConfig( name=body.name, value=body.value, mark=body.mark, oem_id=body.oem_id, ) db.add(row) await db.flush() await db.refresh(row) return row async def update_config( db: AsyncSession, config_id: int, body: DesktopConfigUpdate, ) -> DesktopConfig: row = await db.get(DesktopConfig, config_id) if row is None: raise AdminDesktopConfigError("配置不存在") if body.name is not None and body.name != row.name: taken = await db.scalar( select(DesktopConfig).where( DesktopConfig.name == body.name, DesktopConfig.oem_id == row.oem_id, DesktopConfig.id != config_id, ) ) if taken is not None: raise AdminDesktopConfigError("该 OEM 下配置键名已存在") row.name = body.name if body.value is not None: row.value = body.value if body.mark is not None: row.mark = body.mark await db.flush() await db.refresh(row) return row async def delete_config(db: AsyncSession, config_id: int) -> None: row = await db.get(DesktopConfig, config_id) if row is None: raise AdminDesktopConfigError("配置不存在") await db.delete(row)