""" 本地模型API路由 提供本地模型管理的RESTful API端点 需求: 2.1, 2.8, 4.5, 4.6, 4.7 """ from typing import List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.database import get_db from app.dependencies.auth import get_current_user from app.dependencies.admin_auth import get_current_admin from app.models.user import User from app.models.admin import AdminUser from app.services.local_model_service import LocalModelService from app.services.system_config_manager import get_config_bool from app.schemas.local_model import ( LocalModelCreate, LocalModelUpdate, LocalModelResponse, ConnectionTestRequest, ConnectionTestResponse ) from app.schemas.model_schema import ApiResponse router = APIRouter(prefix="/api/models/local", tags=["本地模型"]) @router.post("", response_model=ApiResponse[LocalModelResponse]) def create_local_model( request: LocalModelCreate, current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """ 添加本地模型 需求 2.1: 管理员可以添加本地部署的OpenAI API兼容模型 """ try: service = LocalModelService(db) model = service.create_local_model( user_id=None, name=request.name, supplier=request.supplier or 'Custom', base_url=request.base_url, api_key=request.api_key, visibility=request.visibility or 'global', categories=request.categories or [0] ) return ApiResponse(code=200, message="success", data=LocalModelResponse.from_model(model)) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=f"Database error: {str(e)}") @router.get("", response_model=ApiResponse[List[LocalModelResponse]]) async def get_local_models( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """ 获取本地模型列表 需求 4.1: 用户可以查看自己添加的本地模型列表 """ service = LocalModelService(db) # 检查本地模型是否启用 if get_config_bool("enable_local_models", True): # 如果本地模型启用,获取所有模型(无论visibility是什么) models = await service.get_all_local_models() else: # 如果本地模型未启用,获取用户有权限的模型 models = await service.get_user_local_models(current_user.id) return ApiResponse( code=200, message="success", data=[LocalModelResponse.from_model(m) for m in models] ) @router.put("/{model_id}", response_model=ApiResponse[LocalModelResponse]) async def update_local_model( model_id: int, request: LocalModelUpdate, current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """ 更新本地模型 需求 4.5: 管理员可以编辑本地模型的配置 """ try: service = LocalModelService(db) model = service.update_local_model( model_id=model_id, user_id=None, name=request.name, supplier=request.supplier, base_url=request.base_url, api_key=request.api_key, visibility=request.visibility, categories=request.categories ) if not model: raise HTTPException(status_code=404, detail="模型不存在或无权限") # 异步清理缓存 from app.services.cache_service import CacheService await CacheService.delete_model(model_id) return ApiResponse(code=200, message="success", data=LocalModelResponse.from_model(model)) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=f"Database error: {str(e)}") @router.delete("/{model_id}", response_model=ApiResponse[dict]) async def delete_local_model( model_id: int, current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db) ): """ 删除本地模型 需求 4.6: 管理员可以删除本地模型 需求 4.7: 删除前需要确认 """ service = LocalModelService(db) success = service.delete_local_model(model_id, None) # 本地模型不关联用户 if not success: raise HTTPException(status_code=404, detail="模型不存在或无权限") # 异步清理缓存 from app.services.cache_service import CacheService await CacheService.delete_model(model_id) return ApiResponse(code=200, message="success", data={"success": True}) @router.post("/test", response_model=ApiResponse[ConnectionTestResponse]) async def test_connection( request: ConnectionTestRequest, db: Session = Depends(get_db), current_admin: AdminUser = Depends(get_current_admin) ): """ 测试本地模型连接(管理员) 需求 2.5: 提供"测试连接"按钮 需求 2.6: 测试成功显示绿色提示 需求 2.7: 测试失败显示红色错误信息 """ service = LocalModelService(db) result = await service.test_connection(request.base_url, request.api_key, request.model_name, (request.categories or [0])[0]) return ApiResponse(code=200, message="success", data=ConnectionTestResponse(**result)) @router.post("/test-public", response_model=ApiResponse[ConnectionTestResponse]) async def test_connection_public( request: ConnectionTestRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """ 测试本地模型连接(普通用户) 需求 2.5: 提供"测试连接"按钮 需求 2.6: 测试成功显示绿色提示 需求 2.7: 测试失败显示红色错误信息 """ # 检查本地模型是否启用 if not get_config_bool("enable_local_models", False): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="本地模型功能已关闭" ) service = LocalModelService(db) result = await service.test_connection(request.base_url, request.api_key, request.model_name, (request.categories or [0])[0]) return ApiResponse(code=200, message="success", data=ConnectionTestResponse(**result))