"""用户数据 JSON API — 收藏、阅读状态、笔记。""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Request from fastapi.responses import HTMLResponse from pydantic import BaseModel from sqlalchemy.orm import Session from app.database import get_db from app.services.user_data import ( get_note, save_note, set_reading_status, toggle_bookmark, ) router = APIRouter(prefix="/api", tags=["user-data"]) # ── 请求模型 ────────────────────────────────────────────────────────── class ReadingStatusRequest(BaseModel): status: str class NoteRequest(BaseModel): content: str # ── 收藏 ────────────────────────────────────────────────────────────── @router.post("/bookmark/{arxiv_id}") def bookmark_toggle(arxiv_id: str, request: Request, db: Session = Depends(get_db)): """切换收藏状态。支持 HTMX 局部刷新和 JSON 响应。""" result = toggle_bookmark(db, arxiv_id) if "error" in result: raise HTTPException(status_code=404, detail=result["error"]) # HTMX 请求 → 返回 HTML 片段 if request.headers.get("HX-Request"): star = "★" if result["bookmarked"] else "☆" active_class = " active" if result["bookmarked"] else "" html = ( f'" ) return HTMLResponse(content=html) return result # ── 阅读状态 ────────────────────────────────────────────────────────── @router.post("/reading-status/{arxiv_id}") def reading_status_update( arxiv_id: str, body: ReadingStatusRequest, db: Session = Depends(get_db), ): """更新阅读状态。""" result = set_reading_status(db, arxiv_id, body.status) if "error" in result: if result["error"] == "not_found": raise HTTPException(status_code=404, detail="Paper not found") elif result["error"] == "invalid_status": raise HTTPException( status_code=422, detail=f"Invalid status. Valid: {result['valid']}", ) return result # ── 笔记 ────────────────────────────────────────────────────────────── @router.get("/note/{arxiv_id}") def note_get(arxiv_id: str, db: Session = Depends(get_db)): """获取笔记。""" result = get_note(db, arxiv_id) if result is None: raise HTTPException(status_code=404, detail="Paper not found") return result @router.post("/note/{arxiv_id}") def note_save(arxiv_id: str, body: NoteRequest, db: Session = Depends(get_db)): """保存笔记。""" result = save_note(db, arxiv_id, body.content) if "error" in result: raise HTTPException(status_code=404, detail=result["error"]) return result