from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List, Optional from pydantic import BaseModel, ConfigDict from datetime import datetime from ..database import get_db from ..models import PromptConfig from .auth import get_current_admin router = APIRouter(prefix="/api/admin/prompt-configs", tags=["admin"]) class PromptConfigBase(BaseModel): key: str module_id: Optional[str] = None category: str = "prompt" version: str = "v1" content: str variables: List[dict] = [] description: Optional[str] = None enabled: bool = True temperature: Optional[float] = None max_tokens: Optional[int] = None created_by: Optional[str] = None class PromptConfigCreate(PromptConfigBase): pass class PromptConfigUpdate(BaseModel): content: Optional[str] = None variables: Optional[List[dict]] = None description: Optional[str] = None enabled: Optional[bool] = None temperature: Optional[float] = None max_tokens: Optional[int] = None class PromptConfigResponse(PromptConfigBase): id: int created_at: Optional[datetime] = None updated_at: Optional[datetime] = None model_config = ConfigDict(from_attributes=True) @router.get("", response_model=List[PromptConfigResponse]) def list_prompts( module_id: Optional[str] = None, category: Optional[str] = None, db: Session = Depends(get_db), admin_user=Depends(get_current_admin), ): q = db.query(PromptConfig) if module_id: q = q.filter(PromptConfig.module_id.in_([module_id, "all"])) if category: q = q.filter(PromptConfig.category == category) prompts = q.order_by(PromptConfig.module_id, PromptConfig.key).all() if not prompts: _ensure_defaults(db) prompts = q.order_by(PromptConfig.module_id, PromptConfig.key).all() return [PromptConfigResponse.model_validate(p) for p in prompts] @router.get("/{prompt_id}", response_model=PromptConfigResponse) def get_prompt(prompt_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): prompt = db.query(PromptConfig).filter(PromptConfig.id == prompt_id).first() if not prompt: raise HTTPException(status_code=404, detail="未找到该配置") return prompt @router.post("", response_model=PromptConfigResponse) def create_prompt(data: PromptConfigCreate, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): existing = db.query(PromptConfig).filter(PromptConfig.key == data.key).first() if existing: raise HTTPException(status_code=400, detail=f"key '{data.key}' 已存在") prompt = PromptConfig(**data.model_dump()) db.add(prompt) db.commit() db.refresh(prompt) return prompt @router.put("/{prompt_id}", response_model=PromptConfigResponse) def update_prompt(prompt_id: int, data: PromptConfigUpdate, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): prompt = db.query(PromptConfig).filter(PromptConfig.id == prompt_id).first() if not prompt: raise HTTPException(status_code=404, detail="未找到该配置") for field, value in data.model_dump(exclude_unset=True).items(): if value is not None: setattr(prompt, field, value) db.commit() db.refresh(prompt) return prompt @router.delete("/{prompt_id}") def delete_prompt(prompt_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)): prompt = db.query(PromptConfig).filter(PromptConfig.id == prompt_id).first() if not prompt: raise HTTPException(status_code=404, detail="未找到该配置") db.delete(prompt) db.commit() return {"message": "删除成功"} def _ensure_defaults(db: Session): existing_keys = {p.key for p in db.query(PromptConfig).all()} from .task_configs import DEFAULT_PROMPTS for p in DEFAULT_PROMPTS: if p["key"] not in existing_keys: db.add(PromptConfig(**p)) db.commit()