Files
item_bank/app/api/settings.py
T
2026-08-01 16:50:55 +08:00

65 lines
2.0 KiB
Python

"""用户 AI 接口配置。api_key 用 Fernet 加密存储,不回显明文。"""
from fastapi import APIRouter, Depends
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db import get_db
from app.deps import get_current_user
from app.models.user import User, UserSettings
from app.schemas.settings import SettingsOut, SettingsUpdate
from app.services import crypto
router = APIRouter(prefix="/api/settings", tags=["settings"])
async def _get_or_create(db: AsyncSession, user_id: str) -> UserSettings:
row = await db.scalar(
select(UserSettings).where(UserSettings.user_id == user_id)
)
if row is None:
row = UserSettings(user_id=user_id)
db.add(row)
await db.flush()
return row
def _to_out(s: UserSettings) -> SettingsOut:
return SettingsOut(
llm_base_url=s.llm_base_url,
llm_text_model=s.llm_text_model,
llm_vision_model=s.llm_vision_model,
has_api_key=bool(s.llm_api_key_encrypted),
)
@router.get("", response_model=SettingsOut)
async def get_settings(
db: AsyncSession = Depends(get_db),
current: User = Depends(get_current_user),
):
s = await _get_or_create(db, current.id)
await db.commit()
return _to_out(s)
@router.put("", response_model=SettingsOut)
async def update_settings(
payload: SettingsUpdate,
db: AsyncSession = Depends(get_db),
current: User = Depends(get_current_user),
):
s = await _get_or_create(db, current.id)
data = payload.model_dump(exclude_unset=True)
for field in ("llm_base_url", "llm_text_model", "llm_vision_model"):
if field in data:
setattr(s, field, data[field])
# api_key:显式传非空值才更新;传空字符串表示清除
if "api_key" in data:
if payload.api_key:
s.llm_api_key_encrypted = crypto.encrypt(payload.api_key)
elif payload.api_key == "":
s.llm_api_key_encrypted = None
await db.commit()
await db.refresh(s)
return _to_out(s)