81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
import asyncio
|
|
import json
|
|
import os
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from fastapi.responses import PlainTextResponse, RedirectResponse
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from config import settings
|
|
from database import get_db
|
|
from models.document import Document
|
|
from models.generation_log import GenerationLog
|
|
from models.paragraph import Paragraph
|
|
from models.template import Template
|
|
from services.document_export import export_document_bytes
|
|
from services.minio_client import (
|
|
download_object_bytes,
|
|
get_presigned_url,
|
|
split_bucket_path,
|
|
upload_bytes,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/{document_id}/docx")
|
|
async def export_docx(document_id: int, db: AsyncSession = Depends(get_db)):
|
|
document = await db.get(Document, document_id)
|
|
if document is None:
|
|
raise HTTPException(status_code=404, detail="生成记录不存在")
|
|
|
|
template = await db.get(Template, document.template_id)
|
|
if template is None:
|
|
raise HTTPException(status_code=404, detail="模板不存在")
|
|
|
|
template_bucket, template_object = split_bucket_path(template.file_path)
|
|
template_bytes = await asyncio.to_thread(download_object_bytes, template_bucket, template_object)
|
|
|
|
result = await db.execute(
|
|
select(GenerationLog, Paragraph)
|
|
.join(Paragraph, Paragraph.id == GenerationLog.paragraph_id)
|
|
.where(GenerationLog.document_id == document_id)
|
|
.order_by(Paragraph.sort_index.asc(), Paragraph.id.asc())
|
|
)
|
|
logs = []
|
|
for log, paragraph in result.all():
|
|
logs.append(
|
|
{
|
|
"title": paragraph.title,
|
|
"content": json.loads(log.content) if log.content else {"content": []},
|
|
}
|
|
)
|
|
|
|
exported_bytes = await asyncio.to_thread(export_document_bytes, template_bytes, logs)
|
|
object_name = f"{datetime.now().strftime('%Y%m%d')}/{uuid.uuid4().hex}.docx"
|
|
await asyncio.to_thread(
|
|
upload_bytes,
|
|
settings.MINIO_BUCKET_OUTPUTS,
|
|
object_name,
|
|
exported_bytes,
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
)
|
|
|
|
document.file_path = f"{settings.MINIO_BUCKET_OUTPUTS}/{object_name}"
|
|
await db.commit()
|
|
return RedirectResponse(
|
|
url=get_presigned_url(settings.MINIO_BUCKET_OUTPUTS, object_name),
|
|
status_code=307,
|
|
)
|
|
|
|
|
|
@router.get("/{document_id}/pdf")
|
|
async def export_pdf(document_id: int):
|
|
return PlainTextResponse(
|
|
f"文档 {document_id} 的 PDF 导出功能正在开发中,当前版本请先使用预览页查看结果。",
|
|
media_type="text/plain; charset=utf-8",
|
|
)
|