baseline: 批次A-D 成果 + membership 半成品(测试红)
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
"""打印中心 async ViewSets。
|
||||
|
||||
- PrintTemplateViewSet:模板 CRUD
|
||||
- PrintSettingsViewSet:抬头读取/更新(单例)
|
||||
- render_document_view:渲染整页打印 HTML(前端 axios 取回后 window.print())
|
||||
"""
|
||||
|
||||
from asgiref.sync import sync_to_async
|
||||
from adrf.decorators import api_view
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.exceptions import ValidationError, NotFound
|
||||
|
||||
from apps.core.viewset import BaseTenantViewSet
|
||||
from .models import PrintSettings, PrintTemplate
|
||||
from .serializers import PrintSettingsSerializer, PrintTemplateSerializer
|
||||
from . import services as printing_services
|
||||
|
||||
|
||||
class PrintTemplateViewSet(BaseTenantViewSet):
|
||||
model = PrintTemplate
|
||||
serializer_class = PrintTemplateSerializer
|
||||
search_fields = ["code", "name", "doc_type"]
|
||||
|
||||
|
||||
@api_view(["GET", "PUT", "PATCH"])
|
||||
async def print_settings_detail(request):
|
||||
"""打印抬头:租户单例。GET 读取 / PUT(整更) / PATCH(部分更)。"""
|
||||
from apps.core.viewset import resolve_tenant
|
||||
|
||||
def _resolve():
|
||||
return resolve_tenant(request.META.get("HTTP_X_TENANT_ID", ""))
|
||||
|
||||
tenant = await sync_to_async(_resolve)()
|
||||
if tenant is None:
|
||||
raise ValidationError({"tenant": "无法识别租户"})
|
||||
obj = await sync_to_async(printing_services.ensure_settings)(tenant)
|
||||
|
||||
if request.method == "GET":
|
||||
serializer = PrintSettingsSerializer(obj)
|
||||
data = await serializer.adata if hasattr(serializer, "adata") else serializer.data
|
||||
return Response(serializer.data)
|
||||
|
||||
partial = request.method == "PATCH"
|
||||
serializer = PrintSettingsSerializer(obj, data=request.data, partial=partial)
|
||||
await sync_to_async(serializer.is_valid)(raise_exception=True)
|
||||
await sync_to_async(serializer.save)(
|
||||
updated_by=request.user if request.user.is_authenticated else None
|
||||
)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
async def render_document_view(request, doc_type, document_id):
|
||||
"""GET /api/v1/printing/render/<doc_type>/<id>/?template=code&autoprint=0
|
||||
|
||||
返回整页 HTML(Content-Type: text/html)。鉴权走 JWT + 租户中间件。
|
||||
"""
|
||||
from django.http import HttpResponse
|
||||
|
||||
from apps.core.viewset import resolve_tenant
|
||||
|
||||
if doc_type not in printing_services.DOC_CONTEXT_BUILDERS:
|
||||
raise ValidationError({"doc_type": f"不支持的文档类型 {doc_type}"})
|
||||
|
||||
def _resolve():
|
||||
code = request.META.get("HTTP_X_TENANT_ID", "")
|
||||
return resolve_tenant(code)
|
||||
|
||||
tenant = await sync_to_async(_resolve)()
|
||||
if tenant is None:
|
||||
raise ValidationError({"tenant": "无法识别租户"})
|
||||
|
||||
module_name, model_name, _ = printing_services.DOC_CONTEXT_BUILDERS[doc_type]
|
||||
model = getattr(__import__(module_name, fromlist=[model_name]), model_name)
|
||||
|
||||
def _load_doc():
|
||||
qs = model.objects.filter(tenant=tenant, pk=document_id)
|
||||
if doc_type == "sales_bill":
|
||||
return qs.select_related(
|
||||
"customer", "warehouse",
|
||||
).prefetch_related(
|
||||
"lines__product__base_unit", "lines__source_unit",
|
||||
).first()
|
||||
return qs.select_related(
|
||||
"supplier", "warehouse",
|
||||
).prefetch_related(
|
||||
"lines__product__base_unit", "lines__source_unit",
|
||||
).first()
|
||||
|
||||
document = await sync_to_async(_load_doc)()
|
||||
if document is None:
|
||||
raise NotFound("document not found")
|
||||
|
||||
template_code = request.GET.get("template", "") or ""
|
||||
autoprint = request.GET.get("autoprint", "1") not in ("0", "false", "False")
|
||||
html_out = await sync_to_async(printing_services.render_document)(
|
||||
tenant=tenant, doc_type=doc_type, document=document,
|
||||
template_code=template_code, autoprint=autoprint,
|
||||
)
|
||||
return HttpResponse(html_out, content_type="text/html; charset=utf-8")
|
||||
Reference in New Issue
Block a user