from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query, Request from sqlalchemy.orm import Session from database import get_db from models.mindmap import MindMap from models.user import User from schemas.mindmap import ( MindMapGenerate, MindMapCreate, MindMapUpdate, MindMapOut, ) from services.credits import credits_payload, spend_credits from services.limiter import limiter from services.auth import get_current_user from services.ai_service import AIService router = APIRouter(prefix="/api/mind-maps", tags=["思维导图管理"]) ai_service = AIService() @limiter.limit("10/minute") @router.post("/ai-generate", response_model=dict) async def ai_generate_mind_map( request: Request, data: MindMapGenerate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): account = spend_credits(db, current_user, "mindmap_generate", f"生成思维导图:{data.topic[:80]}") db.commit() result = await ai_service.generate_mindmap( topic=data.topic, subject=data.subject, grade=data.grade, ) return {"success": True, "data": result, "credits": credits_payload(account, "mindmap_generate")} @router.post("/", response_model=MindMapOut, status_code=201) def create_mind_map( data: MindMapCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = MindMap(user_id=current_user.id, **data.model_dump()) db.add(item) db.commit() db.refresh(item) return item @router.get("/", response_model=list[MindMapOut]) def list_mind_maps( keyword: Optional[str] = None, skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): query = db.query(MindMap).filter(MindMap.user_id == current_user.id) if keyword: query = query.filter(MindMap.title.contains(keyword)) return query.order_by(MindMap.updated_at.desc()).offset(skip).limit(limit).all() @router.get("/{map_id}", response_model=MindMapOut) def get_mind_map( map_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = db.query(MindMap).filter( MindMap.id == map_id, MindMap.user_id == current_user.id, ).first() if not item: raise HTTPException(status_code=404, detail="思维导图不存在") return item @router.put("/{map_id}", response_model=MindMapOut) def update_mind_map( map_id: int, data: MindMapUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = db.query(MindMap).filter( MindMap.id == map_id, MindMap.user_id == current_user.id, ).first() if not item: raise HTTPException(status_code=404, detail="思维导图不存在") for key, value in data.model_dump(exclude_unset=True).items(): setattr(item, key, value) db.commit() db.refresh(item) return item @router.delete("/{map_id}", status_code=204) def delete_mind_map( map_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = db.query(MindMap).filter( MindMap.id == map_id, MindMap.user_id == current_user.id, ).first() if not item: raise HTTPException(status_code=404, detail="思维导图不存在") db.delete(item) db.commit() return None