import math from typing import Literal, Optional from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.api.v1 import ok from app.core.dependencies import get_db from app.schemas.document import ( CreateDocumentRequest, DocumentListItem, DocumentResponse, Pagination, UpdateDocumentRequest, ) from app.services.document_service import DocumentService router = APIRouter(prefix="/documents", tags=["Documents"]) @router.post("", summary="创建文档(下载 Word 转 Markdown)") async def create_document( body: CreateDocumentRequest, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.create_document(body) return ok({ "documentId": doc.id, "format": doc.format, "createdAt": int(doc.created_at.timestamp() * 1000), }) @router.get("", summary="获取文档列表") async def list_documents( userId: str = Query(...), page: int = Query(1, ge=1), pageSize: int = Query(20, ge=1, le=100), sessionId: Optional[str] = Query(None), sortBy: Literal["created_at", "updated_at"] = Query("updated_at"), sortOrder: Literal["asc", "desc"] = Query("desc"), db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) docs, total = await svc.list_documents( user_id=userId, page=page, page_size=pageSize, session_id=sessionId, sort_by=sortBy, sort_order=sortOrder, ) items = [DocumentListItem.model_validate(d).model_dump(by_alias=True) for d in docs] pagination = Pagination( page=page, page_size=pageSize, total=total, total_pages=math.ceil(total / pageSize) if pageSize else 1, ).model_dump(by_alias=True) return ok({"documents": items, "pagination": pagination}) @router.get("/{documentId}", summary="获取文档详情") async def get_document( documentId: str, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.get_document(documentId) data = DocumentResponse.model_validate(doc).model_dump(by_alias=True) # 将 created_by 映射为 userId data["userId"] = data.pop("user_id", None) return ok(data) @router.put("/{documentId}", summary="更新文档") async def update_document( documentId: str, body: UpdateDocumentRequest, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.update_document(documentId, body) return ok({ "documentId": doc.id, "updatedAt": int(doc.updated_at.timestamp() * 1000), }) @router.delete("/{sessionId}", summary="删除会话的所有文档") async def delete_documents_by_session( sessionId: str, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) deleted_count = await svc.delete_documents_by_session(sessionId) return {"code": 0, "message": f"Deleted {deleted_count} document(s) successfully"}