| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- """文档处理相关 API 路由。"""
- import logging
- from fastapi import APIRouter, File, HTTPException, UploadFile
- from fastapi.responses import StreamingResponse
- from ..models.schemas import AnalysisRequest, FileUploadResponse, WordExportRequest
- from ..services.file_service import FileService
- from ..services.analysis_service import AnalysisService
- from ..services.word_export_service import WordExportService
- from ..utils.errors import AppError
- from ..utils.sse import sse_chunk, sse_done, sse_error, sse_response
- logger = logging.getLogger(__name__)
- router = APIRouter(prefix="/api/document", tags=["文档处理"])
- @router.post("/upload", response_model=FileUploadResponse)
- async def upload_file(file: UploadFile = File(...)):
- """上传文档文件并提取文本内容。"""
- try:
- if not FileService.is_supported_document(file.content_type):
- return FileUploadResponse(
- success=False, message="不支持的文件类型,请上传PDF或Word文档"
- )
- file_content = await FileService.process_uploaded_file(file)
- return FileUploadResponse(
- success=True,
- message=f"文件 {file.filename} 上传成功",
- file_content=file_content,
- )
- except Exception as exc:
- logger.exception("文件上传失败")
- return FileUploadResponse(success=False, message=f"文件处理失败: {exc}")
- @router.post("/analyze-stream")
- async def analyze_document_stream(request: AnalysisRequest):
- """流式分析文档内容。"""
- try:
- analysis_service = AnalysisService()
- except AppError as exc:
- raise HTTPException(status_code=exc.status_code, detail=exc.message) from exc
- async def generate():
- try:
- async for chunk in analysis_service.stream_document_analysis(
- file_content=request.file_content,
- analysis_type=request.analysis_type.value,
- ):
- yield sse_chunk(chunk)
- except AppError as exc:
- yield sse_error(exc.message)
- except Exception:
- logger.exception("文档分析失败")
- yield sse_error("文档分析失败,请稍后重试")
- finally:
- yield sse_done()
- return sse_response(generate())
- @router.post("/export-word")
- async def export_word(request: WordExportRequest):
- """根据目录数据导出 Word 文档。"""
- try:
- buffer, headers = WordExportService.export_outline(request)
- return StreamingResponse(
- buffer,
- media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- headers=headers,
- )
- except Exception as exc:
- logger.exception("导出 Word 失败")
- raise HTTPException(status_code=500, detail=f"导出Word失败: {exc}") from exc
|