Преглед изворни кода

feat(backend): expose pound QR items on driver transport page

Enrich inventory links with business type/partner and attach
poundQrcodeItems for the public driver footer button.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong пре 1 месец
родитељ
комит
10183dabc2

+ 2 - 0
backend/app/api/pl/plan.py

@@ -2141,6 +2141,8 @@ def get_plan_arrange_info(
                 plan_no=plan.plan_no or "",
                 stop_type=link.stop_type,
                 stop_id=link.stop_id,
+                business_type=(inventory.business_type if inventory else None),
+                partner_company=(inventory.partner_company if inventory else None),
             )
         )
 

+ 12 - 0
backend/app/api/pl/public_transport.py

@@ -496,6 +496,17 @@ def _build_public_page(db: Session, transport: PlTransport) -> PublicTransportPa
             )
         ]
 
+    pound_items = []
+    if plan:
+        from app.services.db.pound_qr_public import build_pound_qrcode_items_for_plan
+
+        pound_items = build_pound_qrcode_items_for_plan(
+            db,
+            tenant_no=transport.tenant_no,
+            plan_id=plan.id,
+            transport_id=transport.id,
+        )
+
     return PublicTransportPageRead(
         plan_no=plan.plan_no if plan else transport.transport_no,
         plan_date=_format_plan_date(plan.plan_date if plan else None),
@@ -527,6 +538,7 @@ def _build_public_page(db: Session, transport: PlTransport) -> PublicTransportPa
         feedback_time=transport.feedback_time,
         plan_voided=plan_voided,
         plan_archived=plan_archived,
+        pound_qrcode_items=pound_items,
     )
 
 

+ 29 - 0
backend/app/api/pl/transport.py

@@ -1002,6 +1002,25 @@ def arrange_transport(
                     user_id=user.id,
                     dept_id=user.dept_id or "",
                 )
+            inv_ids = [
+                (item.db_inventory_id or "").strip()
+                for item in link_results
+                if (item.db_inventory_id or "").strip()
+            ]
+            inv_by_id: dict = {}
+            if inv_ids:
+                from app.models.db_models import DbInboundOutbound
+
+                inv_rows = (
+                    db.query(DbInboundOutbound)
+                    .filter(
+                        DbInboundOutbound.id.in_(inv_ids),
+                        DbInboundOutbound.tenant_no == tenant_no,
+                        DbInboundOutbound.del_flag == 0,
+                    )
+                    .all()
+                )
+                inv_by_id = {row.id: row for row in inv_rows}
             inventory_records = [
                 build_transport_inventory_link_read(
                     db,
@@ -1011,6 +1030,16 @@ def arrange_transport(
                     db_inventory_id=item.db_inventory_id,
                     batch_no=item.batch_no,
                     plan_no=item.plan_no,
+                    business_type=(
+                        inv_by_id[item.db_inventory_id].business_type
+                        if item.db_inventory_id in inv_by_id
+                        else None
+                    ),
+                    partner_company=(
+                        inv_by_id[item.db_inventory_id].partner_company
+                        if item.db_inventory_id in inv_by_id
+                        else None
+                    ),
                 )
                 for item in link_results
             ]

+ 13 - 0
backend/app/schemas/pl/transport.py

@@ -95,6 +95,16 @@ class TransportInventoryLinkRead(BaseModel):
     plan_no: str = Field(alias="planNo")
     stop_type: Optional[str] = Field(default=None, alias="stopType")
     stop_id: Optional[str] = Field(default=None, alias="stopId")
+    business_type: Optional[str] = Field(default=None, alias="businessType")
+    partner_company: Optional[str] = Field(default=None, alias="partnerCompany")
+    model_config = {"populate_by_name": True}
+
+
+class PublicPoundQrcodeItemRead(BaseModel):
+    inventory_id: str = Field(alias="inventoryId")
+    business_type: str = Field(alias="businessType")
+    partner_company: str = Field(alias="partnerCompany")
+    label: str
     model_config = {"populate_by_name": True}
 
 
@@ -421,6 +431,9 @@ class PublicTransportPageRead(BaseModel):
     feedback_time: Optional[datetime] = Field(default=None, alias="feedbackTime")
     plan_voided: bool = Field(default=False, alias="planVoided")
     plan_archived: bool = Field(default=False, alias="planArchived")
+    pound_qrcode_items: list[PublicPoundQrcodeItemRead] = Field(
+        default_factory=list, alias="poundQrcodeItems"
+    )
     model_config = {"populate_by_name": True}
 
 

+ 55 - 0
backend/app/services/db/pound_qr_public.py

@@ -3,6 +3,7 @@ from __future__ import annotations
 from typing import Any, Optional
 
 from app.schemas.db.public_inventory import PublicPoundQrRead
+from app.schemas.pl.transport import PublicPoundQrcodeItemRead
 from app.services.db.mappers import inventory_date_to_api
 
 
@@ -28,3 +29,57 @@ def build_public_pound_qr_read(row: Any, *, quantity_unit: Optional[str] = None)
         quantity_unit=unit,
         remarks=(row.remark or None) if getattr(row, "remark", None) else None,
     )
+
+
+def build_pound_qrcode_items_for_plan(
+    db,
+    *,
+    tenant_no: str,
+    plan_id: str,
+    transport_id: str,
+) -> list[PublicPoundQrcodeItemRead]:
+    from app.models.db_models import DbInboundOutbound
+    from app.models.pl_models import PlTransportDbLink
+
+    links = (
+        db.query(PlTransportDbLink)
+        .filter(
+            PlTransportDbLink.tenant_no == tenant_no,
+            PlTransportDbLink.plan_id == plan_id,
+            PlTransportDbLink.transport_id == transport_id,
+            PlTransportDbLink.del_flag == 0,
+        )
+        .all()
+    )
+    items: list[PublicPoundQrcodeItemRead] = []
+    seen: set[str] = set()
+    for link in links:
+        inv_id = (link.db_inventory_id or "").strip()
+        if not inv_id or inv_id in seen:
+            continue
+        if not (link.db_purchase_plan_id or "").strip():
+            continue
+        inv = (
+            db.query(DbInboundOutbound)
+            .filter(
+                DbInboundOutbound.id == inv_id,
+                DbInboundOutbound.tenant_no == tenant_no,
+                DbInboundOutbound.del_flag == 0,
+            )
+            .first()
+        )
+        if not inv:
+            continue
+        seen.add(inv_id)
+        bt = (inv.business_type or "").strip()
+        pc = (inv.partner_company or "").strip()
+        items.append(
+            PublicPoundQrcodeItemRead(
+                inventory_id=inv.id,
+                business_type=bt,
+                partner_company=pc,
+                label=build_pound_qr_label(bt, pc),
+            )
+        )
+    return items
+

+ 4 - 0
backend/app/services/pl_inventory_link_read.py

@@ -15,6 +15,8 @@ def build_transport_inventory_link_read(
     plan_no: str,
     stop_type: str | None = None,
     stop_id: str | None = None,
+    business_type: str | None = None,
+    partner_company: str | None = None,
 ) -> TransportInventoryLinkRead:
     del db  # 现场链接已迁至 pl_transport_site_link
     return TransportInventoryLinkRead(
@@ -26,4 +28,6 @@ def build_transport_inventory_link_read(
         plan_no=plan_no,
         stop_type=stop_type,
         stop_id=stop_id,
+        business_type=business_type,
+        partner_company=partner_company,
     )

+ 5 - 0
backend/tests/test_pound_qr_label_items.py

@@ -0,0 +1,5 @@
+from app.services.db.pound_qr_public import build_pound_qr_label
+
+
+def test_label_join():
+    assert " · " in build_pound_qr_label("出库", "A")