You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.5 KiB

#!/usr/bin/env bash
# 第三方对接自测:地址联想 → 选首条可选候选 → 询价 → 轮询
# 用法:
# export CHAJIA_BASE_URL="https://if.dev.51track.vip"
# export CHAJIA_SERVICE_TOKEN="<Token>"
# export CHAJIA_CUSTOMER_ID="CUST_001"
# bash scripts/test-host-api.sh
set -euo pipefail
BASE="${CHAJIA_BASE_URL%/}"
TOKEN="${CHAJIA_SERVICE_TOKEN:-}"
CUSTOMER_ID="${CHAJIA_CUSTOMER_ID:-}"
if [[ -z "$BASE" || -z "$TOKEN" || -z "$CUSTOMER_ID" ]]; then
echo "请设置: CHAJIA_BASE_URL, CHAJIA_SERVICE_TOKEN, CHAJIA_CUSTOMER_ID" >&2
exit 1
fi
AUTH_HEADER="Authorization: Bearer ${TOKEN}"
CID_HEADER="X-Customer-Id: ${CUSTOMER_ID}"
echo "=== [1/3] POST /api/addresses/mothership-candidates ==="
CAND_JSON=$(curl -sf -X POST "${BASE}/api/addresses/mothership-candidates" \
-H "$AUTH_HEADER" \
-H "$CID_HEADER" \
-H "Content-Type: application/json" \
-d "{
\"customer_id\": \"${CUSTOMER_ID}\",
\"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\"}
}")
CODE=$(echo "$CAND_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('code',''))")
if [[ "$CODE" != "0" ]]; then
echo "失败: $CAND_JSON" >&2
exit 1
fi
PICKUP_JSON=$(echo "$CAND_JSON" | python3 -c "
import sys, json
d = json.load(sys.stdin)['data']
for c in d['pickup_candidates']:
if c.get('selectable', True):
print(json.dumps(c)); break
")
DELIVERY_JSON=$(echo "$CAND_JSON" | python3 -c "
import sys, json
d = json.load(sys.stdin)['data']
for c in d['delivery_candidates']:
if c.get('selectable', True):
print(json.dumps(c)); break
")
SESSION_ID=$(echo "$CAND_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['data'].get('quote_session_id') or '')")
if [[ -z "$PICKUP_JSON" || -z "$DELIVERY_JSON" ]]; then
echo "无可用地址候选" >&2
exit 1
fi
REQUEST_ID=$(python3 -c "import uuid; print(uuid.uuid4())")
echo "=== [2/3] POST /api/quotes request_id=${REQUEST_ID} ==="
QUOTE_BODY=$(python3 -c "
import json, sys
pickup = json.loads('''$PICKUP_JSON''')
delivery = json.loads('''$DELIVERY_JSON''')
session = '''$SESSION_ID'''.strip()
def addr(c):
return {
'street': c['street'],
'city': c['city'],
'state': c['state'],
'zip': c.get('zip') or '',
'place_id': c['option_id'],
'formatted_address': c['formatted_address'],
'selected_from_suggestions': True,
'mothership_option_id': c['option_id'],
'mothership_display_label': c['display_label'],
'selected_from_mothership': True,
}
body = {
'request_id': '$REQUEST_ID',
'customer_id': '$CUSTOMER_ID',
'pickup_address': addr(pickup),
'delivery_address': addr(delivery),
'weight': {'value': 500, 'unit': 'kg'},
'dimensions': {'length': 120, 'width': 100, 'height': 150, 'unit': 'cm'},
'pallet_count': 2,
'cargo_type': 'general_freight',
}
if session:
body['quote_session_id'] = session
print(json.dumps(body))
")
CREATE_JSON=$(curl -sf -X POST "${BASE}/api/quotes" \
-H "$AUTH_HEADER" \
-H "$CID_HEADER" \
-H "Content-Type: application/json" \
-d "$QUOTE_BODY")
QUOTE_ID=$(echo "$CREATE_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d['code']==0; print(d['data']['quote_id'])")
echo " quote_id=${QUOTE_ID}"
echo "=== [3/3] GET /api/quotes/${QUOTE_ID} (每 2s 轮询) ==="
FINAL_JSON=""
for i in $(seq 1 20); do
sleep 2
DETAIL_JSON=$(curl -sf "${BASE}/api/quotes/${QUOTE_ID}" \
-H "$AUTH_HEADER" \
-H "$CID_HEADER")
STATUS=$(echo "$DETAIL_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")
echo " poll ${i} : status=${STATUS}"
if [[ "$STATUS" == "done" || "$STATUS" == "failed" || "$STATUS" == "expired" ]]; then
FINAL_JSON="$DETAIL_JSON"
break
fi
done
if [[ -z "$FINAL_JSON" ]]; then
echo "轮询超时" >&2
exit 1
fi
FINAL_STATUS=$(echo "$FINAL_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")
if [[ "$FINAL_STATUS" != "done" ]]; then
echo "$FINAL_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print('询价未成功:', d.get('error_message', d['status']))" >&2
exit 1
fi
echo ""
echo "自测通过"
echo "$FINAL_JSON" | python3 -c "
import sys, json
for q in json.load(sys.stdin)['data'].get('quotes', []):
print(f\" {q['service_level']} / {q['rate_option']} / {q['carrier']} -> final_total={q['final_total']} USD\")
"