This commit is contained in:
zlwu committed 2026-08-22 09:08:05 +08:00
1 parent 833544def3
commit 16be6fa22d
204 files changed
+455089 -46491

No files matched your search

+128 -5
View File
@@ -22,10 +22,12 @@ from app.models.pl_models import (
PlOutboundOrder,
PlOutboundOrderItem,
PlPlan,
PlPlanProduct,
)
from app.schemas.pl.io_order import (
PublicIoOrderFeedback,
PublicIoOrderHistoryPageRead,
PublicIoOrderHistoryProductRead,
PublicIoOrderHistoryRecordRead,
)
from app.services.pl_io_order_service import (
@@ -34,10 +36,24 @@ from app.services.pl_io_order_service import (
order_header_to_dict,
parse_feedback_images,
)
from app.services.pl_product_display import (
load_crm_product_alias_maps,
resolve_product_display_names,
)
from app.utils.excel_export import load_dict_label_maps
inbound_public_router = APIRouter(prefix="/public/pl/inbound", tags=["运输计划-入库单公共"])
outbound_public_router = APIRouter(prefix="/public/pl/outbound", tags=["运输计划-出库单公共"])
CRM_PRODUCT_UNIT = "crm_product_unit"
def _resolve_unit_label(unit_map: dict[str, str], unit_code: Optional[str]) -> str:
code = (unit_code or "").strip()
if not code:
return "吨"
return unit_map.get(code, code)
def _models(kind: str):
if kind == "inbound":
@@ -99,7 +115,7 @@ def _query_kind_history(
keyword: str,
) -> list[tuple]:
"""返回 [(create_time, PublicIoOrderHistoryRecordRead), ...]。"""
header_m, _item_m = _models(kind)
header_m, item_m = _models(kind)
query = (
db.query(header_m, PlPlan)
.outerjoin(
@@ -115,10 +131,19 @@ def _query_kind_history(
kw = (keyword or "").strip()
if kw:
like = f"%{kw}%"
product_match = (
db.query(item_m.id)
.filter(
item_m.order_id == header_m.id,
item_m.del_flag == 0,
item_m.product_name.like(like),
)
.exists()
)
query = query.filter(
or_(
PlPlan.supplier_name.like(like),
PlPlan.customer_name.like(like),
header_m.vehicle_no.like(like),
product_match,
)
)
rows = query.order_by(header_m.create_time.desc()).all()
@@ -140,6 +165,12 @@ def _query_kind_history(
supplier_name=plan.supplier_name if plan else None,
customer_name=plan.customer_name if plan else None,
vehicle_no=header.vehicle_no,
pickup_time=plan.pickup_time if plan else None,
delivery_time=plan.delivery_time if plan else None,
pickup_address=plan.pickup_address if plan else None,
destination_address=(
(plan.destination_address or plan.destination_name) if plan else None
),
site_access_token=tok or None,
site_url=build_io_order_site_url(kind, tok) if tok else None,
status=header.status,
@@ -178,16 +209,108 @@ def _build_history_page(
page_size = min(max(1, int(page_size or 20)), 500)
start = (page - 1) * page_size
page_rows = merged[start : start + page_size]
records = [r for _, r in page_rows]
_attach_history_products(db, tenant_no=header.tenant_no, records=records)
return PublicIoOrderHistoryPageRead(
date=day.isoformat(),
keyword=kw or None,
page=page,
page_size=page_size,
total=total,
records=[r for _, r in page_rows],
records=records,
)
def _attach_history_products(
db: Session,
*,
tenant_no: str,
records: list[PublicIoOrderHistoryRecordRead],
) -> None:
if not records:
return
inbound_ids = [r.order_id for r in records if r.kind == "inbound"]
outbound_ids = [r.order_id for r in records if r.kind == "outbound"]
items_by_order: dict[str, list] = {}
if inbound_ids:
for item in (
db.query(PlInboundOrderItem)
.filter(
PlInboundOrderItem.order_id.in_(inbound_ids),
PlInboundOrderItem.del_flag == 0,
)
.order_by(PlInboundOrderItem.order_num.asc(), PlInboundOrderItem.create_time.asc())
.all()
):
items_by_order.setdefault(item.order_id, []).append(item)
if outbound_ids:
for item in (
db.query(PlOutboundOrderItem)
.filter(
PlOutboundOrderItem.order_id.in_(outbound_ids),
PlOutboundOrderItem.del_flag == 0,
)
.order_by(PlOutboundOrderItem.order_num.asc(), PlOutboundOrderItem.create_time.asc())
.all()
):
items_by_order.setdefault(item.order_id, []).append(item)
all_items = [it for items in items_by_order.values() for it in items]
plan_product_ids = {
(it.plan_product_id or "").strip() for it in all_items if (it.plan_product_id or "").strip()
}
plan_product_by_id: dict[str, PlPlanProduct] = {}
if plan_product_ids:
for prod in (
db.query(PlPlanProduct)
.filter(PlPlanProduct.id.in_(list(plan_product_ids)), PlPlanProduct.del_flag == 0)
.all()
):
plan_product_by_id[prod.id] = prod
crm_product_ids = {
(it.product_id or "").strip() for it in all_items if (it.product_id or "").strip()
}
standard_by_id, alias_options_by_id = load_crm_product_alias_maps(
db, tenant_no=tenant_no, product_ids=crm_product_ids
)
unit_map = load_dict_label_maps(db, [CRM_PRODUCT_UNIT], tenant_no=tenant_no).get(
CRM_PRODUCT_UNIT, {}
)
for record in records:
products: list[PublicIoOrderHistoryProductRead] = []
for item in items_by_order.get(record.order_id) or []:
product_id = (item.product_id or "").strip()
plan_product = plan_product_by_id.get((item.plan_product_id or "").strip())
display_name, _alias = resolve_product_display_names(
saved_product_name=item.product_name,
product_id=product_id,
standard_by_id=standard_by_id,
alias_options_by_id=alias_options_by_id,
)
model = (item.specification or "").strip() or (
(plan_product.model or "").strip() if plan_product else ""
) or None
package_spec = (
(plan_product.package_spec or "").strip() if plan_product else ""
) or None
qty = item.actual_qty if item.actual_qty is not None else item.plan_qty
products.append(
PublicIoOrderHistoryProductRead(
product_name=display_name or item.product_name or "—",
model=model,
package_spec=package_spec,
quantity=qty,
unit=_resolve_unit_label(unit_map, item.unit),
)
)
record.products = products
def _build_page(db: Session, kind: str, header, items) -> dict:
plan = db.query(PlPlan).filter(PlPlan.id == header.plan_id, PlPlan.del_flag == 0).first()
voided, archived = _resolve_io_order_link_flags(plan, header)
@@ -216,7 +339,7 @@ def _make_handlers(kind: str):
def get_history(
token: str,
date: str = Query(..., description="筛选日 YYYY-MM-DD"),
q: Optional[str] = Query(None, description="供方/需方名称模糊"),
q: Optional[str] = Query(None, description="车牌号/产品名称模糊"),
page: int = Query(1, ge=1, description="页码,从 1 开始"),
page_size: int = Query(20, ge=1, le=500, alias="pageSize", description="每页条数"),
db: Session = Depends(get_db),
+46 -1
View File
@@ -30,6 +30,7 @@ from app.schemas.pl.resource_snapshot import parse_resource_snapshot
from app.schemas.pl.transport import (
PublicTransportFeedback,
PublicTransportHistoryPageRead,
PublicTransportHistoryProductRead,
PublicTransportHistoryRecordRead,
PublicTransportPageRead,
PublicTransportPersonnelRead,
@@ -389,11 +390,54 @@ def get_public_transport_history(
)
seen_plan: set[str] = set()
records: list[PublicTransportHistoryRecordRead] = []
plan_rows: list[tuple[PlPlan, PlTransport]] = []
for plan, tr in rows:
if plan.id in seen_plan:
continue
seen_plan.add(plan.id)
plan_rows.append((plan, tr))
products_by_plan: dict[str, list[PublicTransportHistoryProductRead]] = {}
if plan_rows:
plan_ids = [plan.id for plan, _ in plan_rows]
product_rows = (
db.query(PlPlanProduct)
.filter(
PlPlanProduct.plan_id.in_(plan_ids),
PlPlanProduct.del_flag == 0,
)
.order_by(PlPlanProduct.order_num.asc(), PlPlanProduct.create_time.asc())
.all()
)
crm_product_ids = {
(p.product_id or "").strip() for p in product_rows if (p.product_id or "").strip()
}
standard_by_id, alias_options_by_id = load_crm_product_alias_maps(
db, tenant_no=transport.tenant_no, product_ids=crm_product_ids
)
unit_map = load_dict_label_maps(
db, [CRM_PRODUCT_UNIT], tenant_no=transport.tenant_no
).get(CRM_PRODUCT_UNIT, {})
for prod in product_rows:
product_id = (prod.product_id or "").strip()
display_name, _alias_name = resolve_product_display_names(
saved_product_name=prod.product_name,
product_id=product_id,
standard_by_id=standard_by_id,
alias_options_by_id=alias_options_by_id,
)
products_by_plan.setdefault(prod.plan_id, []).append(
PublicTransportHistoryProductRead(
product_name=display_name or prod.product_name or "—",
model=prod.model,
package_spec=prod.package_spec,
quantity=prod.quantity or prod.inbound_estimate_qty or prod.outbound_estimate_qty,
unit=_resolve_unit_label(unit_map, prod.unit),
)
)
records: list[PublicTransportHistoryRecordRead] = []
for plan, tr in plan_rows:
voided, archived = _resolve_driver_link_flags(plan, tr)
tok = (tr.driver_access_token or "").strip()
records.append(
@@ -408,6 +452,7 @@ def get_public_transport_history(
delivery_time=plan.delivery_time,
pickup_address=plan.pickup_address,
destination_address=plan.destination_address or plan.destination_name,
products=products_by_plan.get(plan.id) or [],
plan_voided=voided,
plan_archived=archived,
status_label=_history_status_label(voided, archived),