Files
sixGuoDjango/wechat_第三方接口/极兔物流/极兔快递业务.py
T

244 lines
12 KiB
Python
Raw Normal View History

2026-08-02 14:07:04 +08:00
"""注释"""
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")