"""注释""" 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")