diff --git a/backend/app/schemas/pl/plan.py b/backend/app/schemas/pl/plan.py index c8ff5692d..efccc4258 100644 --- a/backend/app/schemas/pl/plan.py +++ b/backend/app/schemas/pl/plan.py @@ -430,6 +430,7 @@ class PlanContractGapRead(BaseModel): id: str plan_no: str = Field(..., alias="planNo") plan_date: Optional[date] = Field(None, alias="planDate") + plan_type: Optional[str] = Field(None, alias="planType") follow_status: str = Field(..., alias="followStatus") supplier_id: Optional[str] = Field(None, alias="supplierId") supplier_name: Optional[str] = Field(None, alias="supplierName") @@ -440,6 +441,7 @@ class PlanContractGapRead(BaseModel): demander_contract_exempt: bool = Field(..., alias="demanderContractExempt") supplier_contracts: list[PlanContractLink] = Field(default_factory=list, alias="supplierContracts") demander_contracts: list[PlanContractLink] = Field(default_factory=list, alias="demanderContracts") + products: list[PlanProductRead] = Field(default_factory=list, description="产品明细") model_config = {"populate_by_name": True, "from_attributes": True} diff --git a/backend/app/services/pl_plan_contract_gap.py b/backend/app/services/pl_plan_contract_gap.py index 3a43b31a4..e1aa97de5 100644 --- a/backend/app/services/pl_plan_contract_gap.py +++ b/backend/app/services/pl_plan_contract_gap.py @@ -7,8 +7,8 @@ from fastapi import HTTPException from sqlalchemy import and_, exists, func, or_, select from sqlalchemy.orm import Session -from app.models.pl_models import PlPlan, PlPlanContract -from app.schemas.pl.plan import PlanContractGapRead, PlanContractLink +from app.models.pl_models import PlPlan, PlPlanContract, PlPlanProduct +from app.schemas.pl.plan import PlanContractGapRead, PlanContractLink, PlanProductRead from app.services.pl_data_scope import apply_pl_scope from app.services.pl_internal_customer import INTERNAL_CUSTOMER_NAMES, is_internal_customer_name from app.services.pl_plan_service import ( @@ -90,6 +90,7 @@ def build_plan_contract_gap_read( *, supplier_contracts: list[PlanContractLink], demander_contracts: list[PlanContractLink], + products: Optional[list[PlanProductRead]] = None, ) -> PlanContractGapRead: gap_sides = compute_contract_gap_sides( supplier_name=plan.supplier_name, @@ -101,6 +102,7 @@ def build_plan_contract_gap_read( id=plan.id, planNo=plan.plan_no, planDate=plan.plan_date, + planType=plan.plan_type, followStatus=plan.follow_status, supplierId=plan.supplier_id, supplierName=plan.supplier_name, @@ -111,9 +113,31 @@ def build_plan_contract_gap_read( demanderContractExempt=side_is_exempt(plan.customer_name), supplierContracts=supplier_contracts, demanderContracts=demander_contracts, + products=list(products or []), ) +def _load_products_by_plan_ids( + db: Session, + plan_ids: list[str], +) -> dict[str, list[PlanProductRead]]: + if not plan_ids: + return {} + 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() + ) + out: dict[str, list[PlanProductRead]] = {pid: [] for pid in plan_ids} + for row in rows: + out.setdefault(row.plan_id, []).append(PlanProductRead.model_validate(row)) + return out + + def list_plan_contract_gaps( db: Session, *, @@ -185,6 +209,7 @@ def list_plan_contract_gaps( plan_ids = [plan.id for plan in plans] contracts_by_plan = load_plan_contracts_grouped(db, tenant_no, plan_ids) + products_by_plan = _load_products_by_plan_ids(db, plan_ids) items: list[PlanContractGapRead] = [] for plan in plans: @@ -194,6 +219,7 @@ def list_plan_contract_gaps( plan, supplier_contracts=supplier_contracts, demander_contracts=demander_contracts, + products=products_by_plan.get(plan.id, []), ) ) return total, items @@ -254,8 +280,10 @@ def update_plan_side_contracts( supplier_contracts, demander_contracts = load_plan_contracts_grouped( db, tenant_no, [plan.id] ).get(plan.id, ([], [])) + products = _load_products_by_plan_ids(db, [plan.id]).get(plan.id, []) return build_plan_contract_gap_read( plan, supplier_contracts=supplier_contracts, demander_contracts=demander_contracts, + products=products, ) diff --git a/web-admin/src/api/pl/index.ts b/web-admin/src/api/pl/index.ts index e6874a8a9..2cce6fa74 100644 --- a/web-admin/src/api/pl/index.ts +++ b/web-admin/src/api/pl/index.ts @@ -658,6 +658,7 @@ export interface PlanContractGapItem { id: string planNo: string planDate?: string + planType?: string followStatus: string supplierId?: string supplierName?: string @@ -668,6 +669,7 @@ export interface PlanContractGapItem { demanderContractExempt: boolean supplierContracts: PlanContractLink[] demanderContracts: PlanContractLink[] + products?: PlanProduct[] } export interface PlanContractGapQuery { diff --git a/web-admin/src/views/pl/plan-contract/index.vue b/web-admin/src/views/pl/plan-contract/index.vue index b4c448969..dc4623631 100644 --- a/web-admin/src/views/pl/plan-contract/index.vue +++ b/web-admin/src/views/pl/plan-contract/index.vue @@ -195,11 +195,18 @@ + + +