Files
sixGuoDjango/wechat_第三方接口/极兔物流/极兔快递业务.py
T
2026-08-02 14:07:04 +08:00

244 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""注释"""
import base64
from datetime import datetime, time
from zoneinfo import ZoneInfo
import jmespath
import orjson
import pydash
import requests
from django.core.handlers.wsgi import WSGIRequest
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.routers import SimpleRouter
from rest_framework.viewsets import ViewSet
from uuid6 import uuid8
from wechat_token.token工具包 import sixToken
class JiTu极名物流ViewSets(ViewSet):
biz_id = "J008610224928"
delivery_id = "JTSD"
# delivery_id = "TEST"
# service_name = "test_service_name"
service_name = "标准快递"
service_type = 0
发件人 = {
"name": "莫建海", # 发件人名称
# "tel": "",
"mobile": "18081158055",
"company": "莫大帅科技有限公司",
"post_code": "610500", # 发/收件人邮编,不超过 10 字节
"country": "中国",
"province": "四川省",
"city": "成都市",
"area": "新都区",
"address": "桂湖街道五桂村一社16号"
}
@action(detail=False, methods=["post", ], url_path="获取所有绑定的物流账号")
def 获取所有绑定的物流账号(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/account/getall?access_token={mini_token}"
data = requests.get(url=uri)
return Response(data={"xiao": "get_xiao接口被调用了"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="生成运单")
def 生成运单(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/order/add?access_token={mini_token}"
afternoon_datetime = datetime.combine(
date=datetime.today(), time=time(15, 00),
tzinfo=ZoneInfo("Asia/Shanghai"),
)
afternoon_datetime_int = int(afternoon_datetime.timestamp())
receiver收件人信息 = {
"name": "元宝", # string 否 发/收件人姓名,不超过 64 字节
# "tel": "020-88888888", # string 否 发/收件人座机号码,若不填写则必须填写 mobile,不超过32字节
"mobile": "18860891975", # string 否 发/收件人手机号码,若不填写则必须填写 tel,不超过32字节
# "company": "", # string 否 发/收件人公司名称,不超过64字节
"post_code": "225300", # string 否 发/收件人邮编,不超过10字节
"country": "中国", # string 否 发/收件人国家,不超过64字节
"province": "江苏省", # string 否 发/收件人省份,比如:"广东省",不超过64字节
"city": "泰州市", # string 否 发/收件人市/地区,比如:"广州市",不超过64字节
"area": "海陵区", # string 否 发/收件人区/县,比如:"海珠区",不超过64字节
"address": "西郊乡任景村603号" # string 否 发/收件人详细地址,比如:"XX路XX号XX大厦XX",不超过512字节
}
cargo包裹信息 = {
"count": 2, # number 是 包裹数量, 默认为1
"weight": 0.9, # number 是 货物总重量,比如1.2,单位是千克(kg)
"space_x": 30.5, # number 是 货物长度,比如20.0,单位是厘米(cm)
"space_y": 20, # number 是 货物宽度,比如15.0,单位是厘米(cm)
"space_z": 20, # number 是 货物高度,比如10.0,单位是厘米(cm)
"detail_list": [{"name": "商品名称", "count": 1}]
}
shop商品信息 = {
# 这里路由配置了,是当用户收到微信通知时,
"wxa_path": "/tabPage/Home/Home", # string 否 商家小程序的路径,建议为订单页面
# "img_url": "", # img_urlstring 否 商品缩略图 url;shop.detail_list为空则必传,shop.detail_list非空可不传。
# "goods_name": "", # string 否 商品名称, 不超过128字节;shop.detail_list为空则必传,shop.detail_list非空可不传。
# "goods_count": "", # number 否 商品数量;shop.detail_list为空则必传。shop.detail_list非空可不传,默认取shop.detail_list的size
"detail_list": [
{
"goods_name": "微信气泡狗抱枕(小号)",
"goods_img_url": "https://mmbiz.qpic.cn/mmbiz_png/OiaFLUqewuIDNQnTiaCInIG8ibdosYHhQHPbXJUrqYSNIcBL60vo4LIjlcoNG1QPkeH5GWWEB41Ny895CokeAah8A/640",
"goods_desc": "40cm * 40cm尺寸"
},
{
"goods_name": "微信气泡狗抱枕(中号)",
"goods_img_url": "https://mmbiz.qpic.cn/mmbiz_png/OiaFLUqewuIDNQnTiaCInIG8ibdosYHhQHPbXJUrqYSNIcBL60vo4LIjlcoNG1QPkeH5GWWEB41Ny895CokeAah8A/640",
"goods_desc": "50cm * 50cm尺寸"
}
],
}
insured保价信息 = {
"use_insured": 0, # number 否 是否保价,0 表示不保价,1 表示保价
# "insured_value": 100, # number 否 保价金额,单位是分,比如: 10000 表示 100 元
}
service服务类型 = {
"service_type": self.service_type, # number 是 服务类型ID,详见已经支持的快递公司基本信息
"service_name": self.service_name, # string 是 服务名称,详见已经支持的快递公司基本信息
}
post_address_data = {
"add_source": 0, # number 是 订单来源,0为小程序订单,2为App或H5订单,填2则不发送物流服务通知
"order_id": uuid8().hex, # string 是 订单ID,须保证全局唯一,不超过512字节
"openid": "o6oV61xoMYAFNpi4RpVjn3BFGB1U",
"delivery_id": self.delivery_id,
"biz_id": self.biz_id,
"custom_remark": "易碎物品", # string 否 快递备注信息,比如"易碎物品",不超过 1024 字节
"expect_time": afternoon_datetime_int,
# 预约收件时间Unix 时间戳, 单位秒,顺丰必须传。 预期的上门揽件时间,0表示已事先约定取件时间;否则请传预期揽件时间戳,需大于当前时间,收件员会在预期时间附近上门。
"sender": self.发件人,
"receiver": receiver收件人信息,
"cargo": cargo包裹信息,
"shop": shop商品信息,
"insured": insured保价信息,
"service": service服务类型,
}
print(repr(receiver收件人信息["name"])) # 应该输出 '元宝',而不是 '\\u5143\\u5b9d'
print(post_address_data)
raw_text = orjson.dumps(post_address_data)
print(raw_text)
# 发起下订单的请求
data = requests.post(
url=uri, data=orjson.dumps(post_address_data),
headers={"Content-Type": "application/json; charset=utf-8"},
)
print(orjson.loads(data.content.decode(encoding="utf-8")))
# delivery_resultmsg = pydash.get(obj=data.json(), path="delivery_resultmsg")
# print(delivery_resultmsg.encode('latin-1').decode('utf-8'))
return Response(data={"message": "post_xiao接口被调用了啦"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["post", ], url_path="取消运单")
def 取消运单(self, request: WSGIRequest | Request):
"""
:param request:
:type request:
:return:
:rtype:
"""
pass
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/order/cancel?access_token={mini_token}"
post_data = {
"order_id": "019a071e892789c2a3c4a1de897f43a0",
"openid": "o6oV61xoMYAFNpi4RpVjn3BFGB1U",
"delivery_id": self.delivery_id,
"waybill_id": "JT0019529487771"
}
data = requests.post(url=uri, json=post_data)
print(data.json())
return Response()
@action(detail=False, methods=["post", ], url_path="获取电子面单余额")
def 获取电子面单余额(self, request: WSGIRequest | Request, *args, **kwargs):
"""
:param request:
:param args:
:param kwargs:
:return:
"""
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/quota/get?access_token={mini_token}"
post_data = {
"delivery_id": self.delivery_id,
"biz_id": self.biz_id
}
data = requests.post(url=uri)
print(orjson.loads(data.content.decode(encoding="utf-8")))
return Response(data={"message": "xiao方法被调用了"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["post", ], url_path="获取运单数据")
def 获取面单的HTML(self, request: WSGIRequest | Request, *args, **kwargs):
"""
:param request:
:param args:
:param kwargs:
:return:
"""
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/order/get?access_token={mini_token}"
post_data = {
"order_id": "019a07f5a4f88e45a8423f54bc0f4040", # string 是 订单 ID,需保证全局唯一
"openid": "o6oV61xoMYAFNpi4RpVjn3BFGB1U",
# string 否 该参数仅在getOrder接口生效,batchGetOrder接口不生效。用户openid,当add_source=2时无需填写(不发送物流服务通知)
"delivery_id": self.delivery_id, # string 是 快递公司ID,参见getAllDelivery, 必须和waybill_id对应
"waybill_id": "JT0019534640361", # string 否 运单ID
"print_type": 1 # number 否 该参数仅在getOrder接口生效,batchGetOrder接口不生效。获取打印面单类型【1:一联单,0:二联单】,默认获取二联单
}
data = requests.post(url=uri, data=orjson.dumps(post_data).decode())
print_html = pydash.get(obj=orjson.loads(data.content.decode(encoding="utf-8")), path="print_html")
print(base64.b64decode(print_html))
html = base64.b64decode(print_html).decode(encoding="utf-8")
return Response(data={"message": html}, status=status.HTTP_200_OK)
@action(detail=False, methods=["post", ], url_path="查询运单轨迹")
def 查询运单轨迹(self, request: WSGIRequest | Request, *args, **kwargs):
"""
:param request:
:param args:
:param kwargs:
:return:
"""
mini_token = sixToken.get_mini_token()
uri = f"https://api.weixin.qq.com/cgi-bin/express/business/path/get?access_token={mini_token}"
print("轨迹查询")
waybill_id = request.data.get("waybill_id", ) #
idOrders = request.data.get("idOrders", False) #
self_mini_openid = request.data.get("self_mini_openid", False) #
print("在这里确认一下订单号是多少", waybill_id)
post_data = {
"order_id": idOrders,
"openid": self_mini_openid,
"delivery_id": self.delivery_id,
"waybill_id": waybill_id
}
data = requests.post(url=uri, json=post_data)
messageData = orjson.loads(data.content.decode(encoding="utf-8"))
print(messageData)
path_item_list = jmespath.search(expression="path_item_list", data=messageData, )
waybill_id = jmespath.search(expression="waybill_id", data=messageData, )
for path in path_item_list:
action_type = path.get("action_type")
if action_type == 300003:
pass
# Orders.objects.filter(order_wuliu_number=waybill_id, order_wuliu_status=Orders.OrdersStatus.运输中).update(order_wuliu_status=Orders.OrdersStatus.已签收)
return Response(data={"message": messageData}, status=status.HTTP_200_OK)
JiTu极名物流ViewSetsRouter = SimpleRouter()
JiTu极名物流ViewSetsRouter.register(prefix="", viewset=JiTu极名物流ViewSets, basename="JiTu极名物流ViewSets")