177 lines
5.3 KiB
Python
177 lines
5.3 KiB
Python
"""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)
|