# 第三方对接自测:地址联想 → 选首条可选候选 → 询价 → 轮询 # 用法: # $env:CHAJIA_BASE_URL = "https://if.dev.51track.vip" # $env:CHAJIA_SERVICE_TOKEN = "" # $env:CHAJIA_CUSTOMER_ID = "CUST_001" # powershell -ExecutionPolicy Bypass -File scripts/test-host-api.ps1 $ErrorActionPreference = "Stop" $Base = if ($env:CHAJIA_BASE_URL) { $env:CHAJIA_BASE_URL.TrimEnd("/") } else { "" } $Token = $env:CHAJIA_SERVICE_TOKEN $CustomerId = $env:CHAJIA_CUSTOMER_ID if (-not $Base -or -not $Token -or -not $CustomerId) { Write-Host "Set env: CHAJIA_BASE_URL, CHAJIA_SERVICE_TOKEN, CHAJIA_CUSTOMER_ID" -ForegroundColor Red exit 1 } $headers = @{ Authorization = "Bearer $Token" "X-Customer-Id" = $CustomerId "Content-Type" = "application/json" "Cache-Control" = "no-store" } function Pick-FirstSelectable($candidates) { foreach ($c in $candidates) { if ($c.selectable -ne $false) { return $c } } return $null } function Build-ConfirmedAddress($candidate) { return @{ street = $candidate.street city = $candidate.city state = $candidate.state zip = if ($candidate.zip) { $candidate.zip } else { "" } place_id = $candidate.option_id formatted_address = $candidate.formatted_address selected_from_suggestions = $true mothership_option_id = $candidate.option_id mothership_display_label = $candidate.display_label selected_from_mothership = $true } } Write-Host "=== [1/3] POST /api/addresses/mothership-candidates ===" -ForegroundColor Cyan $body1 = @{ customer_id = $CustomerId pickup_address = @{ street = "1234 Warehouse Blvd" city = "Los Angeles" state = "CA" zip = "90001" } delivery_address = @{ street = "5678 Distribution Dr" city = "Dallas" state = "TX" zip = "75201" } } | ConvertTo-Json -Depth 5 $r1 = Invoke-RestMethod -Uri "$Base/api/addresses/mothership-candidates" -Method POST -Headers $headers -Body $body1 if ($r1.code -ne 0) { Write-Host "Step 1 failed: $($r1.message)" -ForegroundColor Red exit 1 } $pickup = Pick-FirstSelectable $r1.data.pickup_candidates $delivery = Pick-FirstSelectable $r1.data.delivery_candidates if (-not $pickup -or -not $delivery) { Write-Host "No selectable address candidates" -ForegroundColor Red exit 1 } Write-Host " pickup: $($pickup.display_label)" Write-Host " delivery: $($delivery.display_label)" $requestId = [guid]::NewGuid().ToString() Write-Host "=== [2/3] POST /api/quotes request_id=$requestId ===" -ForegroundColor Cyan $quoteBody = @{ request_id = $requestId customer_id = $CustomerId pickup_address = Build-ConfirmedAddress $pickup delivery_address = Build-ConfirmedAddress $delivery weight = @{ value = 500; unit = "kg" } dimensions = @{ length = 120; width = 100; height = 150; unit = "cm" } pallet_count = 2 cargo_type = "general_freight" } if ($r1.data.quote_session_id) { $quoteBody.quote_session_id = $r1.data.quote_session_id } $r2 = Invoke-RestMethod -Uri "$Base/api/quotes" -Method POST -Headers $headers -Body ($quoteBody | ConvertTo-Json -Depth 8) if ($r2.code -ne 0 -or -not $r2.data.quote_id) { Write-Host "Step 2 failed: $($r2.message)" -ForegroundColor Red exit 1 } $quoteId = $r2.data.quote_id Write-Host " quote_id=$quoteId status=$($r2.data.status)" Write-Host "=== [3/3] GET /api/quotes/$quoteId (poll every 2s) ===" -ForegroundColor Cyan $final = $null for ($i = 1; $i -le 20; $i++) { Start-Sleep -Seconds 2 $r3 = Invoke-RestMethod -Uri "$Base/api/quotes/$quoteId" -Method GET -Headers $headers $st = $r3.data.status Write-Host " poll $i : status=$st" if ($st -in @("done", "failed", "expired")) { $final = $r3 break } } if (-not $final) { Write-Host "Poll timeout" -ForegroundColor Red exit 1 } if ($final.data.status -ne "done") { Write-Host "Quote failed: status=$($final.data.status) error=$($final.data.error_message)" -ForegroundColor Red exit 1 } Write-Host "" Write-Host "PASS" -ForegroundColor Green foreach ($q in $final.data.quotes) { $line = " $($q.service_level) / $($q.rate_option) / $($q.carrier) -> final_total=$($q.final_total) USD" Write-Host $line }