import os import tempfile import pypandoc from typing import Optional from fastapi import APIRouter, HTTPException, Depends from fastapi.responses import FileResponse from pydantic import BaseModel from starlette.background import BackgroundTask import auth import db from formula_processor import preprocess_formulas router = APIRouter() class DocRequest(BaseModel): markdown: str def remove_file(path: str): try: os.remove(path) except Exception: pass @router.post("/api/convert") async def convert_md_to_docx(req: DocRequest, current_user: Optional[dict] = Depends(auth.get_optional_user)): try: # 如果带有合法登录 token,则记录历史 if current_user: db.add_history_record(current_user["id"], req.markdown) try: pypandoc.get_pandoc_version() except OSError: pypandoc.download_pandoc() # ====== 公式预处理:统一各种定界符格式 ====== # 将 GPT/AI 生成内容中 \(...\)、\[...\]、缺失反斜杠的 [...] 和 (...) # 全部转换为 Pandoc 可识别的标准 $...$ 和 $$...$$ 格式 processed_markdown = preprocess_formulas(req.markdown) fd, tmp_path = tempfile.mkstemp(suffix=".docx") os.close(fd) md_fd, md_tmp_path = tempfile.mkstemp(suffix=".md") with os.fdopen(md_fd, 'w', encoding='utf-8') as f: f.write(processed_markdown) pypandoc.convert_file( md_tmp_path, 'docx', format='markdown+tex_math_dollars', outputfile=tmp_path ) os.remove(md_tmp_path) return FileResponse( tmp_path, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document', filename='document.docx', background=BackgroundTask(remove_file, tmp_path) ) except Exception as e: print(f"Error during conversion: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/api/history") async def get_history(current_user: dict = Depends(auth.get_current_user)): history = db.get_history_records(current_user["id"]) return {"history": history}