feat: 修复订单查询和物流查询功能
主要修改: 1. 订单数据解析修复 (agent/agents/order.py) - 修复 Mall API 返回数据的嵌套结构解析 - 更新字段映射:orderId→order_id, orderProduct→items, statusText→status_text - 支持多种商品图片字段:image, pic, thumb, productImg - 添加详细的调试日志 2. 物流查询修复 (mcp_servers/order_mcp/server.py) - 修复物流接口返回数据结构解析 (data[].trackingCode→tracking_number) - 添加 print() 日志用于调试 - 支持多种字段名映射 3. Chatwoot 集成优化 (agent/integrations/chatwoot.py) - 添加 json 模块导入 - 完善订单卡片和表单展示功能 4. API 请求头优化 (mcp_servers/shared/mall_client.py) - 更新 User-Agent 和 Accept 头 - 修正 Origin 和 Referer 大小写 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -315,12 +315,10 @@ async def get_mall_order(
|
||||
"""
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
logger.info(
|
||||
"get_mall_order called",
|
||||
order_id=order_id,
|
||||
has_user_token=bool(user_token),
|
||||
user_token_prefix=user_token[:20] if user_token else None
|
||||
f"get_mall_order called: order_id={order_id}, has_user_token={bool(user_token)}, "
|
||||
f"token_prefix={user_token[:20] if user_token else None}"
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -347,9 +345,8 @@ async def get_mall_order(
|
||||
result = await client.get_order_by_id(order_id)
|
||||
|
||||
logger.info(
|
||||
"Mall API request successful",
|
||||
order_id=order_id,
|
||||
result_keys=list(result.keys()) if isinstance(result, dict) else None
|
||||
f"Mall API request successful: order_id={order_id}, "
|
||||
f"result_keys={list(result.keys()) if isinstance(result, dict) else None}"
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -359,9 +356,7 @@ async def get_mall_order(
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Mall API request failed",
|
||||
order_id=order_id,
|
||||
error=str(e)
|
||||
f"Mall API request failed: order_id={order_id}, error={str(e)}"
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
@@ -395,18 +390,11 @@ async def get_logistics(
|
||||
Returns:
|
||||
物流信息,包含快递公司、状态、预计送达时间、物流轨迹等
|
||||
"""
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger.info(
|
||||
"get_logistics called",
|
||||
order_id=order_id,
|
||||
has_user_token=bool(user_token)
|
||||
)
|
||||
print(f"[get_logistics] Called with order_id={order_id}, has_user_token={bool(user_token)}")
|
||||
|
||||
# 必须提供 user_token
|
||||
if not user_token:
|
||||
logger.error("No user_token provided for logistics query")
|
||||
print("[get_logistics] ERROR: No user_token provided")
|
||||
return {
|
||||
"success": False,
|
||||
"error": "用户未登录,请先登录账户以查询物流信息",
|
||||
@@ -424,32 +412,50 @@ async def get_logistics(
|
||||
source=settings.mall_source
|
||||
)
|
||||
|
||||
print(f"[get_logistics] Calling Mall API: /mall/api/order/parcel?orderId={order_id}")
|
||||
|
||||
result = await client.get(
|
||||
"/mall/api/order/parcel",
|
||||
params={"orderId": order_id}
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Logistics query successful",
|
||||
order_id=order_id,
|
||||
has_tracking=bool(result.get("trackingNumber"))
|
||||
)
|
||||
print(f"[get_logistics] SUCCESS: result_keys={list(result.keys()) if isinstance(result, dict) else type(result).__name__}")
|
||||
print(f"[get_logistics] Sample data: {str(result)[:500]}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"order_id": order_id,
|
||||
"tracking_number": result.get("trackingNumber"),
|
||||
"courier": result.get("courier"),
|
||||
"status": result.get("status"),
|
||||
"estimated_delivery": result.get("estimatedDelivery"),
|
||||
"timeline": result.get("timeline", [])
|
||||
}
|
||||
# Mall API 返回结构:{ "total": 1, "data": [{ "trackingCode": "...", "carrier": "...", ... }] }
|
||||
logistics_list = result.get("data", [])
|
||||
|
||||
if logistics_list and len(logistics_list) > 0:
|
||||
first_logistics = logistics_list[0]
|
||||
tracking_number = first_logistics.get("trackingCode", "")
|
||||
carrier = first_logistics.get("carrier", "未知")
|
||||
|
||||
print(f"[get_logistics] Extracted: tracking_number={tracking_number}, carrier={carrier}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"order_id": order_id,
|
||||
"tracking_number": tracking_number,
|
||||
"courier": carrier,
|
||||
"tracking_url": first_logistics.get("trackingUrl", ""),
|
||||
"status": first_logistics.get("status", ""),
|
||||
"timeline": [] # 如果 API 返回轨迹信息,可以在这里添加
|
||||
}
|
||||
else:
|
||||
print(f"[get_logistics] WARNING: No logistics data found in response")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"order_id": order_id,
|
||||
"tracking_number": "",
|
||||
"courier": "暂无物流信息",
|
||||
"status": "",
|
||||
"timeline": []
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Logistics query failed",
|
||||
order_id=order_id,
|
||||
error=str(e)
|
||||
)
|
||||
import traceback
|
||||
print(f"[get_logistics] ERROR: {type(e).__name__}: {str(e)}")
|
||||
print(f"[get_logistics] TRACEBACK:\n{traceback.format_exc()}")
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
|
||||
@@ -55,14 +55,16 @@ class MallClient:
|
||||
headers={
|
||||
"Authorization": f"Bearer {self.api_token}",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Device-Type": "pc",
|
||||
"tenant-Id": self.tenant_id,
|
||||
"currency-code": self.currency_code,
|
||||
"language-id": self.language_id,
|
||||
"source": self.source,
|
||||
"origin": "https://www.qa1.gaia888.com",
|
||||
"referer": "https://www.qa1.gaia888.com/",
|
||||
"Origin": "https://www.qa1.gaia888.com",
|
||||
"Referer": "https://www.qa1.gaia888.com/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
||||
"DNT": "1",
|
||||
},
|
||||
timeout=30.0
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user