import json import secrets from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.config import settings from app.database import get_db from app.models import Mindmap from app.schemas import MindmapCreateRequest, MindmapNode, MindmapResponse router = APIRouter(prefix="/mindmaps", tags=["mindmaps"]) def generate_unique_id() -> str: return secrets.token_urlsafe(16) def extract_title_from_json(mindmap_json: dict) -> str: label = mindmap_json.get("label", "") return label.strip() if label else "未命名思维导图" def to_response(mindmap: Mindmap) -> MindmapResponse: tree_data = json.loads(mindmap.raw_json) tree = MindmapNode.model_validate(tree_data) url = f"{settings.frontend_base_url}/mindmap/{mindmap.unique_id}" return MindmapResponse( id=mindmap.id, unique_id=mindmap.unique_id, session_id=mindmap.session_id, title=mindmap.title, raw_json=mindmap.raw_json, tree=tree, url=url, created_at=mindmap.created_at, updated_at=mindmap.updated_at, ) @router.post("", response_model=MindmapResponse, status_code=status.HTTP_201_CREATED) def create_mindmap( payload: MindmapCreateRequest, db: Session = Depends(get_db), ) -> MindmapResponse: title = extract_title_from_json(payload.mindmap_json) raw_json = json.dumps(payload.mindmap_json, ensure_ascii=False) unique_id = generate_unique_id() mindmap = Mindmap( unique_id=unique_id, session_id=payload.session_id, title=title, raw_json=raw_json, ) db.add(mindmap) db.commit() db.refresh(mindmap) return to_response(mindmap) @router.get("/{unique_id}", response_model=MindmapResponse) def get_mindmap( unique_id: str, db: Session = Depends(get_db), ) -> MindmapResponse: mindmap = db.query(Mindmap).filter(Mindmap.unique_id == unique_id).first() if not mindmap: raise HTTPException(status_code=404, detail="脑图不存在") return to_response(mindmap)