ForcePilot/backend/package/yuxi/channel/extensions/jd/business.py
Kris bb8ade9e2b feat(channel): 添加京东渠道扩展
新增京东(JD)渠道扩展,支持在 Yuxi 平台中集成京东客服渠道。

包含以下功能模块:
- client: 京东 API 客户端封装
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- outbound: 外发消息管理
- pairing: 用户配对与绑定
- security: 安全校验
- signature: 请求签名验证
- crypto: 加解密处理
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- session: 会话管理
- business: 业务逻辑处理
- types: 类型定义
2026-05-21 11:05:40 +08:00

201 lines
9.0 KiB
Python

import logging
from yuxi.channel.extensions.jd.client import JOSClient
logger = logging.getLogger(__name__)
class JDBusiness:
def __init__(self, client: JOSClient, shop_id: str):
self._client = client
self._shop_id = shop_id
async def query_order(
self,
order_id: str | None = None,
start_time: str | None = None,
end_time: str | None = None,
page: int = 1,
page_size: int = 10,
access_token: str = "",
) -> dict:
biz_params = {
"optional_fields": "orderInfo",
"page": str(page),
"page_size": str(page_size),
}
if order_id:
biz_params["order_id"] = order_id
if start_time:
biz_params["start_date"] = start_time
if end_time:
biz_params["end_date"] = end_time
try:
data = await self._client.call("jingdong.pop.order.search", biz_params, access_token)
return {"success": True, "data": self._flatten_order_result(data)}
except Exception as e:
logger.error("JD order query failed: %s", e)
return {"success": False, "error": str(e)}
async def get_order_detail(self, order_id: str, access_token: str = "") -> dict:
biz_params = {
"order_id": order_id,
"optional_fields": "orderInfo,paymentInfo,consigneeInfo",
}
try:
data = await self._client.call("jingdong.pop.order.get", biz_params, access_token)
return {"success": True, "data": self._flatten_order_detail(data)}
except Exception as e:
logger.error("JD order detail failed: %s", e)
return {"success": False, "error": str(e)}
async def query_logistics(self, order_id: str, access_token: str = "") -> dict:
biz_params = {"order_id": order_id}
try:
data = await self._client.call("jingdong.etms.trace.get", biz_params, access_token)
trace_result = data.get("jingdong_etms_trace_get_responce", {}).get("traceResult", {})
traces = trace_result.get("traceList", []) if isinstance(trace_result, dict) else []
return {
"success": True,
"data": {
"order_id": order_id,
"waybill_code": trace_result.get("waybillCode", ""),
"traces": traces,
},
}
except Exception as e:
logger.error("JD logistics query failed: %s", e)
return {"success": False, "error": str(e)}
async def query_product(self, sku_id: str, access_token: str = "") -> dict:
biz_params = {
"sku": sku_id,
"queryExts": "warebase,wareimage",
}
try:
data = await self._client.call("jingdong.ware.product.get", biz_params, access_token)
ware_result = data.get("jingdong_ware_product_get_responce", {}).get("product", {})
if isinstance(ware_result, dict):
return {
"success": True,
"data": {
"sku_id": ware_result.get("sku", ""),
"name": ware_result.get("name", ""),
"brand_name": ware_result.get("brandName", ""),
"category": ware_result.get("category", ""),
"introduction": ware_result.get("introduction", ""),
"weight": ware_result.get("weight", ""),
"sale_date": ware_result.get("saleDate", ""),
"upc": ware_result.get("upc", ""),
"image_url": ware_result.get("imageUrl", ""),
},
}
return {"success": False, "error": "未找到商品信息"}
except Exception as e:
logger.error("JD product query failed: %s", e)
return {"success": False, "error": str(e)}
async def query_product_price(self, sku_ids: list[str], access_token: str = "") -> dict:
biz_params = {"sku": ",".join(sku_ids)}
try:
data = await self._client.call("jingdong.ware.price.get", biz_params, access_token)
price_list = data.get("jingdong_ware_price_get_responce", {}).get("priceList", [])
return {"success": True, "data": price_list}
except Exception as e:
logger.error("JD product price query failed: %s", e)
return {"success": False, "error": str(e)}
async def query_refund(self, order_id: str, access_token: str = "") -> dict:
biz_params = {"order_id": order_id}
try:
data = await self._client.call("jingdong.pop.afs.soa.refundapply.get", biz_params, access_token)
result = data.get("jingdong_pop_afs_soa_refundapply_get_responce", {}).get("queryResult", {})
return {"success": True, "data": result}
except Exception as e:
logger.error("JD refund query failed: %s", e)
return {"success": False, "error": str(e)}
async def set_cs_status(self, status: str, access_token: str = "") -> dict:
biz_params = {"status": status}
try:
await self._client.call("jingdong.im.setStatus", biz_params, access_token)
return {"success": True, "status": status}
except Exception as e:
logger.error("JD set cs status failed: %s", e)
return {"success": False, "error": str(e)}
async def get_cs_status(self, access_token: str = "") -> dict:
try:
data = await self._client.call("jingdong.im.getStatus", {}, access_token)
return {"success": True, "data": data}
except Exception as e:
logger.error("JD get cs status failed: %s", e)
return {"success": False, "error": str(e)}
async def get_user_info(self, user_id: str, access_token: str = "") -> dict:
biz_params = {"user_id": user_id}
try:
data = await self._client.call("jingdong.im.getUserInfo", biz_params, access_token)
user_info = data.get("jingdong_im_getUserInfo_responce", {}).get("result", {})
return {"success": True, "data": user_info if isinstance(user_info, dict) else {}}
except Exception as e:
logger.error("JD get user info failed: %s", e)
return {"success": False, "error": str(e)}
async def query_comments(self, sku_id: str, page: int = 1, page_size: int = 10, access_token: str = "") -> dict:
biz_params = {"sku": sku_id, "page": str(page), "pageSize": str(page_size)}
try:
data = await self._client.call("jingdong.comment.products.get", biz_params, access_token)
result = data.get("jingdong_comment_products_get_responce", {}).get("result", {})
return {"success": True, "data": result}
except Exception as e:
logger.error("JD comment query failed: %s", e)
return {"success": False, "error": str(e)}
async def evaluate_cs(self, chat_id: str, score: int, access_token: str = "") -> dict:
biz_params = {"chat_id": chat_id, "score": str(score)}
try:
await self._client.call("jingdong.im.evaluate", biz_params, access_token)
return {"success": True, "score": score}
except Exception as e:
logger.error("JD evaluate cs failed: %s", e)
return {"success": False, "error": str(e)}
def _flatten_order_result(self, data: dict) -> list[dict]:
result = data.get("jingdong_pop_order_search_responce", {}).get("searchorderinforesult", {})
order_list = result.get("orderInfoList", [])
if isinstance(order_list, dict):
order_list = [order_list]
return [
{
"order_id": o.get("orderId", ""),
"order_state": o.get("orderState", ""),
"order_total_price": o.get("orderTotalPrice", ""),
"order_create_time": o.get("orderCreateTime", ""),
"order_payment_time": o.get("orderPaymentTime", ""),
}
for o in order_list
]
def _flatten_order_detail(self, data: dict) -> dict:
result = data.get("jingdong_pop_order_get_responce", {}).get("orderDetailInfo", {})
order_info = result.get("orderInfo", {}) if isinstance(result, dict) else {}
return {
"order_id": order_info.get("orderId", ""),
"order_state": order_info.get("orderState", ""),
"order_total_price": order_info.get("orderTotalPrice", ""),
"freight_price": order_info.get("freightPrice", ""),
"seller_discount": order_info.get("sellerDiscount", ""),
"order_create_time": order_info.get("orderCreateTime", ""),
"order_payment_time": order_info.get("orderPaymentTime", ""),
"consignee_name": order_info.get("consigneeInfo", {}).get("fullname", ""),
"consignee_mobile": order_info.get("consigneeInfo", {}).get("mobile", ""),
"consignee_address": order_info.get("consigneeInfo", {}).get("fullAddress", ""),
}