import logging import time from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.models.user import User from app.routers.auth import get_current_user from app.schemas.settings import ( SettingsOut, ProfileUpdateIn, LLMConfigIn, SchedulerConfigIn, LLMTestIn ) from app.services.log_service import LogService from app.services.settings_service import ( get_user_settings, update_user_profile, update_llm_config, update_scheduler_config, test_llm_connection ) from app.logging_utils import summarize_llm_config logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/settings", tags=["设置"]) @router.get("", response_model=SettingsOut) async def get_settings( request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): request.state.user_id = current_user.id settings = await get_user_settings(current_user.id, db) if not settings: raise HTTPException(status_code=404, detail="用户不存在") await LogService(db).system_log( message="加载用户设置", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=200, operation="settings.get", details={"llm_config": summarize_llm_config(settings.get("llm_config"))}, ) return settings @router.put("/profile") async def update_profile( data: ProfileUpdateIn, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): try: user = await update_user_profile( current_user.id, db, full_name=data.full_name, password=data.password, current_password=data.current_password ) return user except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) @router.put("/llm") async def update_llm( data: LLMConfigIn, request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): request.state.user_id = current_user.id log_service = LogService(db) start = time.perf_counter() payload = data.model_dump(exclude_none=True) try: config = await update_llm_config(current_user.id, payload, db) await log_service.system_log( message="更新 LLM 配置成功", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=200, operation="settings.update_llm", duration_ms=int((time.perf_counter() - start) * 1000), details={ "request": summarize_llm_config(payload), "stored": summarize_llm_config(config), }, ) return {"llm_config": config} except ValueError as e: await log_service.system_log( message="更新 LLM 配置失败", level="warning", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=400, error_type=e.__class__.__name__, operation="settings.update_llm", duration_ms=int((time.perf_counter() - start) * 1000), details={"request": summarize_llm_config(payload), "detail": str(e)}, ) raise HTTPException(status_code=400, detail=str(e)) @router.post("/llm/test") async def test_llm( data: LLMTestIn, request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): request.state.user_id = current_user.id start = time.perf_counter() result = await test_llm_connection( provider=data.provider, model=data.model, base_url=data.base_url, api_key=data.api_key ) await LogService(db).system_log( message="测试 LLM 连接", level="info" if result.get("success") else "warning", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=200, error_type=None if result.get("success") else "llm_test_failed", operation="settings.test_llm", duration_ms=int((time.perf_counter() - start) * 1000), details={ "provider": data.provider, "model": data.model, "has_base_url": bool(data.base_url), "has_api_key": bool(data.api_key), "success": result.get("success"), "error": result.get("error"), }, ) return result @router.put("/scheduler") async def update_scheduler( data: SchedulerConfigIn, request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): request.state.user_id = current_user.id payload = data.model_dump(exclude_none=True) try: config = await update_scheduler_config( current_user.id, payload, db ) await LogService(db).system_log( message="更新调度配置成功", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=200, operation="settings.update_scheduler", details={"request": payload, "stored": config}, ) return {"scheduler_config": config} except ValueError as e: await LogService(db).system_log( message="更新调度配置失败", level="warning", source="settings", user_id=current_user.id, request_id=request.state.request_id, route=request.url.path, method=request.method, status_code=400, error_type=e.__class__.__name__, operation="settings.update_scheduler", details={"request": payload, "detail": str(e)}, ) raise HTTPException(status_code=400, detail=str(e))