File size: 2,280 Bytes
b4f2238 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | """案件文件模板渲染下载 API"""
from __future__ import annotations
import logging
from typing import Any
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from ninja import Router
from apps.core.exceptions import NotFoundError, ValidationException
from apps.core.infrastructure.throttling import rate_limit_from_settings
from apps.core.security.auth import JWTOrSessionAuth
from .download_response_factory import build_download_response
logger = logging.getLogger("apps.documents.api")
router = Router(auth=JWTOrSessionAuth())
@router.post("/cases/{case_id}/templates/{template_id}/download")
@rate_limit_from_settings("EXPORT", by_user=True)
def download_case_template(request: Any, case_id: int, template_id: int) -> Any:
"""渲染案件文件模板并下载"""
from apps.cases.models import Case
from apps.documents.models import DocumentTemplate
from apps.documents.services.generation.pipeline import DocxRenderer
from apps.documents.services.placeholders import EnhancedContextBuilder
case = Case.objects.filter(pk=case_id).first()
if not case:
raise NotFoundError(message=_("案件不存在"), code="CASE_NOT_FOUND", errors={"case_id": str(case_id)})
template = DocumentTemplate.objects.filter(pk=template_id, is_active=True).first()
if not template:
raise NotFoundError(
message=_("模板不存在"), code="TEMPLATE_NOT_FOUND", errors={"template_id": str(template_id)}
)
file_path = template.get_file_location()
if not file_path:
raise ValidationException(message=_("模板文件路径为空"), code="TEMPLATE_FILE_EMPTY", errors={})
context = EnhancedContextBuilder().build_context({"case": case, "case_id": case.id})
content = DocxRenderer().render(file_path, context)
date_str = timezone.now().strftime("%Y%m%d")
filename = f"{template.name}({case.name or '案件'})V1_{date_str}.docx"
logger.info("案件模板下载成功", extra={"case_id": case_id, "template_id": template_id, "doc_filename": filename})
return build_download_response(
content=content,
filename=filename,
content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
|