|
|
@@ -727,7 +727,11 @@ class PlanExportBody(BaseModel):
|
|
|
hazard_cert_ready: Optional[int] = Field(default=None, alias="hazardCertReady")
|
|
|
ids: Optional[List[str]] = None
|
|
|
columns: Optional[List[str]] = None
|
|
|
- export_format: Optional[str] = Field(default=None, alias="exportFormat", description="archive=运输计划归档专用导出")
|
|
|
+ export_format: Optional[str] = Field(
|
|
|
+ default=None,
|
|
|
+ alias="exportFormat",
|
|
|
+ description="archive=运输计划归档 Excel;archive_zip=归档数据及附件 ZIP",
|
|
|
+ )
|
|
|
|
|
|
model_config = {"populate_by_name": True, "extra": "allow"}
|
|
|
|
|
|
@@ -779,8 +783,14 @@ def export_plans(
|
|
|
.all()
|
|
|
)
|
|
|
date_str = datetime.now().strftime("%Y%m%d")
|
|
|
- is_archive_export = (body.export_format or "").strip().lower() == "archive"
|
|
|
- if is_archive_export:
|
|
|
+ export_format = (body.export_format or "").strip().lower()
|
|
|
+ is_archive_export = export_format == "archive"
|
|
|
+ is_archive_zip = export_format == "archive_zip"
|
|
|
+ if len(plans) > EXPORT_MAX_ROWS:
|
|
|
+ raise ExportValidationError(f"导出超过 {EXPORT_MAX_ROWS} 条,请缩小筛选范围")
|
|
|
+ if is_archive_export or is_archive_zip:
|
|
|
+ if not plans:
|
|
|
+ raise ExportValidationError("没有可导出的数据")
|
|
|
transport_ids = [plan.transport_id for plan in plans if plan.transport_id]
|
|
|
transports_by_id = _load_transports_by_id(db, tenant_no, transport_ids)
|
|
|
items = build_plan_archive_export_rows(
|
|
|
@@ -799,6 +809,37 @@ def export_plans(
|
|
|
cols = filter_export_columns(PLAN_ARCHIVE_EXPORT_COLUMNS, body.columns)
|
|
|
if not user_can_view_archive_prices(db, user):
|
|
|
cols = [c for c in cols if c.field not in ARCHIVE_PRICE_EXPORT_FIELDS]
|
|
|
+ if is_archive_zip:
|
|
|
+ from app.services.pl_plan_archive_zip_export import (
|
|
|
+ build_archive_zip_streaming_response,
|
|
|
+ collect_hazard_cert_items,
|
|
|
+ load_plan_products_by_plan_ids,
|
|
|
+ merge_plan_attachment_items,
|
|
|
+ )
|
|
|
+
|
|
|
+ plan_ids = [p.id for p in plans]
|
|
|
+ docs = load_plan_document_attachments_by_plan_ids(
|
|
|
+ db, tenant_no=tenant_no, plan_ids=plan_ids
|
|
|
+ )
|
|
|
+ products_by_plan = load_plan_products_by_plan_ids(
|
|
|
+ db, tenant_no=tenant_no, plan_ids=plan_ids
|
|
|
+ )
|
|
|
+ attachments_by_plan = {
|
|
|
+ pid: merge_plan_attachment_items(
|
|
|
+ docs.get(pid, []),
|
|
|
+ collect_hazard_cert_items(products_by_plan.get(pid, [])),
|
|
|
+ )
|
|
|
+ for pid in plan_ids
|
|
|
+ }
|
|
|
+ stamp = datetime.now().strftime("%Y%m%d%H%M")
|
|
|
+ return build_archive_zip_streaming_response(
|
|
|
+ db=db,
|
|
|
+ tenant_no=tenant_no,
|
|
|
+ columns=cols,
|
|
|
+ rows=items,
|
|
|
+ attachments_by_plan=attachments_by_plan,
|
|
|
+ stamp=stamp,
|
|
|
+ )
|
|
|
sheet_title = "计划归档"
|
|
|
filename_stem = f"计划归档_{date_str}"
|
|
|
else:
|