"""OEM 桌面配置 CRUD(按当前 OEM 用户的 oem 记录隔离)。""" from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.core.oem_resolve import resolve_oem_id from app.models.desktopConfig import DesktopConfig from app.models.user import User from app.schemas.admin_desktop_config import DesktopConfigCreate, DesktopConfigUpdate DEFAULT_PAGE_SIZE = 20 MAX_PAGE_SIZE = 200 # 新 OEM 首次访问时写入的默认桌面配置(oem_id 由 resolve_oem_id 动态填入) DEFAULT_DESKTOP_CONFIG_SEED: tuple[tuple[str, str], ...] = ( ("BAILIAN_API_KEY", "sk-fc1ae323e01947dc9e054aad121796aa"), ("BAILIAN_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"), ("ASR_MODE", "online"), ("OSS_ACCESS_KEY_ID", "LTAI5tSUJiy9NTBdX5sQeC9f"), ("OSS_ACCESS_KEY_SECRET", "H7D1SjRYy94vCXC7nxIAuZQvaNjBx3"), ("OSS_BUCKET", "jianhualinshi"), ("OSS_REGION", "oss-cn-beijing"), ("LLM_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3/chat/completions"), ("LLM_MODE_ID", "doubao-seed-2-0-mini-260215"), ("LLM_API_KEY", "ebff7c25-d00f-483d-94bb-8d1c18b51ddd"), ("VIDEO_GEN_MODE", "online"), ("INFINITETALK_API_URL", "http://www.baidu.com"), ("RUNNINGHUB_WORKFLOW_ID", "2013514129943826433"), ("RUNNINGHUB_API_KEY", "389cc5f561d742fb9a9cf26f37dda0d3"), ) class OemDesktopConfigError(Exception): def __init__(self, message: str) -> None: self.message = message super().__init__(message) # 路由层沿用 AdminDesktopConfigError 名称 AdminDesktopConfigError = OemDesktopConfigError async def _count_by_oem(db: AsyncSession, oem_id: int) -> int: stmt = select(func.count()).select_from(DesktopConfig).where(DesktopConfig.oem_id == oem_id) return await db.scalar(stmt) or 0 async def ensure_default_desktop_configs(db: AsyncSession, oem_id: int) -> None: """当前 OEM 无任何配置时写入默认键值。""" if await _count_by_oem(db, oem_id) > 0: return for name, value in DEFAULT_DESKTOP_CONFIG_SEED: db.add(DesktopConfig(name=name, value=value, oem_id=oem_id)) await db.flush() async def list_all_as_map(db: AsyncSession, oem_id: int) -> dict[str, str]: await ensure_default_desktop_configs(db, oem_id) result = await db.execute(select(DesktopConfig).where(DesktopConfig.oem_id == oem_id)) rows = result.scalars().all() return {row.name: row.value for row in rows} async def list_configs( db: AsyncSession, *, oem_user: User, page: int = 1, page_size: int = DEFAULT_PAGE_SIZE, keyword: str | None = None, ) -> tuple[list[DesktopConfig], int]: oem_id = await resolve_oem_id(db, oem_user) await ensure_default_desktop_configs(db, oem_id) page_size = min(max(page_size, 1), MAX_PAGE_SIZE) page = max(page, 1) offset = (page - 1) * page_size filters = [DesktopConfig.oem_id == oem_id] if keyword: like = f"%{keyword.strip()}%" filters.append(DesktopConfig.name.ilike(like)) count_stmt = select(func.count()).select_from(DesktopConfig).where(*filters) list_stmt = ( select(DesktopConfig) .where(*filters) .order_by(DesktopConfig.name.asc()) .offset(offset) .limit(page_size) ) total = await db.scalar(count_stmt) or 0 result = await db.scalars(list_stmt) return list(result.all()), total async def create_config( db: AsyncSession, body: DesktopConfigCreate, *, oem_user: User, ) -> DesktopConfig: oem_id = await resolve_oem_id(db, oem_user) existing = await db.scalar( select(DesktopConfig).where( DesktopConfig.name == body.name, DesktopConfig.oem_id == oem_id, ) ) if existing is not None: raise OemDesktopConfigError("配置键名已存在") row = DesktopConfig( name=body.name, value=body.value, mark=body.mark, oem_id=oem_id, ) db.add(row) await db.flush() await db.refresh(row) return row async def _get_owned_config( db: AsyncSession, config_id: int, *, oem_user: User, ) -> DesktopConfig: oem_id = await resolve_oem_id(db, oem_user) row = await db.get(DesktopConfig, config_id) if row is None or row.oem_id != oem_id: raise OemDesktopConfigError("配置不存在") return row async def update_config( db: AsyncSession, config_id: int, body: DesktopConfigUpdate, *, oem_user: User, ) -> DesktopConfig: row = await _get_owned_config(db, config_id, oem_user=oem_user) 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 OemDesktopConfigError("配置键名已存在") 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, *, oem_user: User, ) -> None: row = await _get_owned_config(db, config_id, oem_user=oem_user) await db.delete(row)