Files
shanxia2.0/backend/app/services/pl_plan_list_attachments.py
T
2026-08-23 18:42:27 +08:00

134 lines
3.8 KiB
Python

"""运输计划列表:聚合司机/现场/出入库现场等单据附件。"""
from __future__ import annotations
import json
from typing import Optional
from sqlalchemy.orm import Session
from app.models.pl_models import (
PlInboundOrder,
PlOutboundOrder,
PlPlan,
PlTransport,
PlTransportSiteLink,
)
def _parse_image_urls(raw: Optional[str]) -> list[str]:
if not raw:
return []
text = str(raw).strip()
if not text:
return []
try:
parsed = json.loads(text)
if isinstance(parsed, list):
return [str(item).strip() for item in parsed if str(item).strip()]
except json.JSONDecodeError:
pass
return [item.strip() for item in text.split(",") if item.strip()]
def _short_label(text: str, max_len: int = 8) -> str:
value = (text or "").strip()
if not value:
return "现场"
if len(value) <= max_len:
return value
return f"{value[: max_len - 1]}…"
def load_plan_document_attachments_by_plan_ids(
db: Session,
*,
tenant_no: str,
plan_ids: list[str],
) -> dict[str, list[dict[str, str]]]:
if not plan_ids:
return {}
result: dict[str, list[dict[str, str]]] = {plan_id: [] for plan_id in plan_ids}
seen: dict[str, set[str]] = {plan_id: set() for plan_id in plan_ids}
def add(plan_id: str, label: str, urls: list[str]) -> None:
bucket = result.get(plan_id)
if bucket is None:
return
for url in urls:
if not url or url in seen[plan_id]:
continue
seen[plan_id].add(url)
bucket.append({"url": url, "label": label})
plan_rows = (
db.query(PlPlan.id, PlPlan.transport_id)
.filter(
PlPlan.id.in_(plan_ids),
PlPlan.tenant_no == tenant_no,
PlPlan.del_flag == 0,
)
.all()
)
transport_ids = [transport_id for _, transport_id in plan_rows if transport_id]
plan_by_transport = {
transport_id: plan_id for plan_id, transport_id in plan_rows if transport_id
}
if transport_ids:
transports = (
db.query(PlTransport)
.filter(
PlTransport.id.in_(transport_ids),
PlTransport.tenant_no == tenant_no,
PlTransport.del_flag == 0,
)
.all()
)
for transport in transports:
plan_id = plan_by_transport.get(transport.id)
if not plan_id:
continue
add(plan_id, "司机", _parse_image_urls(transport.feedback_images))
site_rows = (
db.query(PlTransportSiteLink)
.filter(
PlTransportSiteLink.plan_id.in_(plan_ids),
PlTransportSiteLink.tenant_no == tenant_no,
PlTransportSiteLink.del_flag == 0,
)
.order_by(PlTransportSiteLink.order_num, PlTransportSiteLink.create_time)
.all()
)
for row in site_rows:
product = (row.product or "").strip()
label = f"现场·{_short_label(product)}" if product else "现场"
add(row.plan_id, label, _parse_image_urls(row.site_feedback_images))
inbound_rows = (
db.query(PlInboundOrder)
.filter(
PlInboundOrder.plan_id.in_(plan_ids),
PlInboundOrder.tenant_no == tenant_no,
PlInboundOrder.del_flag == 0,
)
.all()
)
for row in inbound_rows:
add(row.plan_id, "入库现场", _parse_image_urls(row.site_feedback_images))
outbound_rows = (
db.query(PlOutboundOrder)
.filter(
PlOutboundOrder.plan_id.in_(plan_ids),
PlOutboundOrder.tenant_no == tenant_no,
PlOutboundOrder.del_flag == 0,
)
.all()
)
for row in outbound_rows:
add(row.plan_id, "出库现场", _parse_image_urls(row.site_feedback_images))
return result