feat: 添加物流查询功能和完善 token 传递
- 添加 get_logistics 工具查询 Mall API /mall/api/order/parcel - 修复 Cookie token 传递到 MCP 的问题 - 增强 LLM 客户端超时处理和日志 - 移除 MALL_API_TOKEN,使用用户登录 token - 更新测试页面使用 setUser 设置用户属性 - 增强 webhook 调试日志
This commit is contained in:
@@ -313,37 +313,150 @@ async def get_mall_order(
|
||||
订单详情,包含订单号、状态、商品信息、金额、物流信息等
|
||||
Order details including order ID, status, items, amount, logistics info, etc.
|
||||
"""
|
||||
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
|
||||
)
|
||||
|
||||
try:
|
||||
# 如果提供了 user_token,使用用户自己的 token
|
||||
if user_token:
|
||||
client = MallClient(
|
||||
api_url=settings.mall_api_url,
|
||||
api_token=user_token,
|
||||
tenant_id=settings.mall_tenant_id,
|
||||
currency_code=settings.mall_currency_code,
|
||||
language_id=settings.mall_language_id,
|
||||
source=settings.mall_source
|
||||
)
|
||||
else:
|
||||
# 否则使用默认的 mall 实例
|
||||
client = mall
|
||||
# 必须提供 user_token
|
||||
if not user_token:
|
||||
logger.error("No user_token provided, user must be logged in")
|
||||
return {
|
||||
"success": False,
|
||||
"error": "用户未登录,请先登录账户以查询订单信息",
|
||||
"order_id": order_id,
|
||||
"require_login": True
|
||||
}
|
||||
|
||||
logger.info("Using user token for Mall API request")
|
||||
client = MallClient(
|
||||
api_url=settings.mall_api_url,
|
||||
api_token=user_token,
|
||||
tenant_id=settings.mall_tenant_id,
|
||||
currency_code=settings.mall_currency_code,
|
||||
language_id=settings.mall_language_id,
|
||||
source=settings.mall_source
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"order": result,
|
||||
"order_id": order_id
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Mall API request failed",
|
||||
order_id=order_id,
|
||||
error=str(e)
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"order_id": order_id
|
||||
}
|
||||
finally:
|
||||
# 如果创建了临时客户端,关闭它
|
||||
if user_token:
|
||||
# 关闭客户端
|
||||
if 'client' in dir() and client:
|
||||
await client.close()
|
||||
|
||||
|
||||
@register_tool("get_logistics")
|
||||
@mcp.tool()
|
||||
async def get_logistics(
|
||||
order_id: str,
|
||||
user_token: str = None,
|
||||
user_id: str = None,
|
||||
account_id: str = None
|
||||
) -> dict:
|
||||
"""Query logistics tracking information from Mall API
|
||||
|
||||
从 Mall API 查询订单物流信息
|
||||
|
||||
Args:
|
||||
order_id: 订单号 (e.g., "201941967")
|
||||
user_token: 用户 JWT token(必需,用于身份验证)
|
||||
user_id: 用户 ID(自动注入,此工具不使用)
|
||||
account_id: 账户 ID(自动注入,此工具不使用)
|
||||
|
||||
Returns:
|
||||
物流信息,包含快递公司、状态、预计送达时间、物流轨迹等
|
||||
"""
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger.info(
|
||||
"get_logistics called",
|
||||
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")
|
||||
return {
|
||||
"success": False,
|
||||
"error": "用户未登录,请先登录账户以查询物流信息",
|
||||
"order_id": order_id,
|
||||
"require_login": True
|
||||
}
|
||||
|
||||
try:
|
||||
client = MallClient(
|
||||
api_url=settings.mall_api_url,
|
||||
api_token=user_token,
|
||||
tenant_id=settings.mall_tenant_id,
|
||||
currency_code=settings.mall_currency_code,
|
||||
language_id=settings.mall_language_id,
|
||||
source=settings.mall_source
|
||||
)
|
||||
|
||||
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"))
|
||||
)
|
||||
|
||||
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", [])
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Logistics query failed",
|
||||
order_id=order_id,
|
||||
error=str(e)
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"order_id": order_id
|
||||
}
|
||||
finally:
|
||||
if 'client' in dir() and client:
|
||||
await client.close()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user