""" 管理员本地模型管理API路由 """ from typing import Optional from fastapi import APIRouter, Depends, HTTPException, status, Query, Request from sqlalchemy.orm import Session from sqlalchemy import or_, desc from app.database import get_db from app.models.model import ModelNew from app.models.user import User from app.schemas.admin_schema import LocalModelListItem, LocalModelVisibilityRequest from app.schemas.model_schema import PaginatedResponse from app.services.operation_log_service import OperationLogService from app.dependencies.admin_auth import get_current_admin from app.models.admin import AdminUser router = APIRouter(prefix="/api/admin/local-models", tags=["本地模型管理"]) @router.get("", response_model=PaginatedResponse) def list_local_models( keyword: Optional[str] = Query(None), user_id: Optional[str] = Query(None), visibility: Optional[str] = Query(None), page: int = Query(1, ge=1), size: int = Query(20, ge=1, le=100), current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db), ): query = db.query(ModelNew).filter(ModelNew.is_local == True) mapped_user_id = None try: if getattr(current_admin, "username", None): mapped_user = db.query(User).filter(User.username == current_admin.username).first() if mapped_user: mapped_user_id = mapped_user.id except Exception: pass if keyword: kw = f"%{keyword}%" query = query.filter( or_(ModelNew.model_code.ilike(kw), ModelNew.display_name.ilike(kw)) ) if visibility: if visibility == "user" and not user_id: uid = mapped_user_id or str(getattr(current_admin, "id", "")) query = query.filter(ModelNew.visibility == "user", ModelNew.user_id == uid) else: query = query.filter(ModelNew.visibility == visibility) if user_id: query = query.filter(ModelNew.user_id == user_id) total = query.count() models = query.order_by(desc(ModelNew.created_at)).offset((page - 1) * size).limit(size).all() user_ids = list(set(m.user_id for m in models if m.user_id)) users = db.query(User).filter(User.id.in_(user_ids)).all() if user_ids else [] user_map = {u.id: u.username or u.nickname for u in users} result = [ LocalModelListItem( id=m.id, title=m.model_code, name=m.display_name or m.model_code, supplier=m.supplier or "Custom", user_id=m.user_id or "", username=user_map.get(m.user_id, ""), base_url=(m.base_url[:30] + "...") if m.base_url and len(m.base_url) > 30 else (m.base_url or ""), visibility=m.visibility or "user", category=m.category or 0, created_at=m.created_at, updated_at=m.updated_at, ) for m in models ] return PaginatedResponse(items=[r.model_dump() for r in result], total=total, page=page, page_size=size) @router.put("/{model_id}/visibility") def update_local_model_visibility( model_id: int, data: LocalModelVisibilityRequest, request: Request, current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db), ): model = db.query(ModelNew).filter(ModelNew.id == model_id, ModelNew.is_local == True).first() if not model: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="本地模型不存在") old_visibility = model.visibility model.visibility = data.visibility db.commit() OperationLogService(db).create_log( admin_id=current_admin.id, operation_type="update", module="local_model", target_id=str(model_id), detail={"action": "update_visibility", "old": old_visibility, "new": data.visibility}, ip_address=request.client.host if request.client else None, ) return {"message": "可见性更新成功", "model_id": model_id, "visibility": data.visibility} @router.delete("/{model_id}") def delete_local_model( model_id: int, request: Request, current_admin: AdminUser = Depends(get_current_admin), db: Session = Depends(get_db), ): model = db.query(ModelNew).filter(ModelNew.id == model_id, ModelNew.is_local == True).first() if not model: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="本地模型不存在") model_code = model.model_code db.delete(model) db.commit() OperationLogService(db).create_log( admin_id=current_admin.id, operation_type="delete", module="local_model", target_id=str(model_id), detail={"model_code": model_code}, ip_address=request.client.host if request.client else None, ) return {"message": "本地模型已删除", "model_id": model_id}