补充运行说明并实现基础导出能力
This commit is contained in:
@@ -1,14 +1,74 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import PlainTextResponse
|
||||
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):
|
||||
return PlainTextResponse(
|
||||
f"文档 {document_id} 的 Word 导出功能正在开发中,当前版本请先使用预览页查看结果。",
|
||||
media_type="text/plain; charset=utf-8",
|
||||
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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user