This commit is contained in:
doudou201703
2026-08-02 14:07:04 +08:00
commit 046fac6dc1
339 changed files with 19435 additions and 0 deletions
@@ -0,0 +1,243 @@
"""注释"""
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")
@@ -0,0 +1,48 @@
import hashlib
from datetime import datetime
from zoneinfo import ZoneInfo
import requests
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 DefaultRouter
from rest_framework.viewsets import ViewSet
from sixGuoDjango import BaseResponse, ResData
class 蕊烨打印机接口ViewSets( ViewSet ):
user: str = "792282@qq.com" # 注册的账号
user_key: str = "bcdfac0dfdf444b8a4539fcc7dea905c" # 生成的密钥
sn: str = "30MYD1UMLT0B448" # 打印机机身的SN码
@action( detail=False, methods=[ "get", "post", "put", "delete" ], url_path="lable" )
def 打印标签订单有胶水的( self, request: Request ):
""""""
timestamp = str( int( datetime.now( tz=ZoneInfo( "Asia/Shanghai" ) ).timestamp( ) ) )
签名字符串 = f"{self.user}{self.user_key}{timestamp}"
sign = hashlib.sha1( data=签名字符串.encode( encoding="utf-8" ), ).hexdigest( )
json_data = {
"sn": self.sn,
"content": """<IMG x="32" y="32" w="100">""",
"copies": 1,
"voice": 2,
"user": self.user,
"timestamp": timestamp,
"sign": sign,
}
printData = requests.post( url="https://open.xpyun.net/api/openapi/xprinter/printLabel", json=json_data )
httpResData = BaseResponse( resData=ResData( listData=[ "" ], dictData={ "demo": "xiaozizi" } ), ).model_dump( )
return Response( data=httpResData, status=status.HTTP_200_OK )
蕊烨打印机接口ViewSetsRouter = DefaultRouter( )
蕊烨打印机接口ViewSetsRouter.register( prefix="", viewset=蕊烨打印机接口ViewSets, basename="蕊烨打印机接口ViewSets" )
@@ -0,0 +1,162 @@
import datetime
import jmespath
import orjson
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 wechat_第三方接口.顺丰物流.顺丰参数 import sfToken
class SF顺丰业务接口ViewSets(ViewSet):
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="order_create")
def 快递下订单接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
print('============')
requestID = f"SF{datetime.date.strftime(datetime.datetime.now(), format="%Y%m%d%H%M%S%f")}"
accessToken = sfToken()
沙箱环境 = f"https://sfapi-sbox.sf-express.com/std/service"
sftimestamp = str(int(datetime.datetime.now().timestamp()))
cargoDetails托寄物信息 = [{"name": "物品", "count": 1}]
寄件人 = {
"contactType": 1,
"company": "1",
"contact": "元宝",
"mobile": "13800138000",
"country": "CN",
"province": "江苏省",
"city": "泰州市",
"county": "海陵区",
"address": "城西街道任景路603号"
}
收件人 = {
"contactType": 2,
"company": "2",
"contact": "大帅",
"mobile": "13800138001",
"country": "CN",
"province": "四川省",
"city": "成都市",
"county": "新都区",
"address": "桂湖街道一社16号"
}
msgData = {
# 响应报文的语言,缺省值为zh-CN
"language": "zh-CN",
"parcelQty": 1,
# 客户订单号,重复使用订单号时返回第一次下单成功时的运单信息
"orderId": f"SFOD{datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d%H%M%S%f")}",
# 托寄物信息
"cargoDetails": cargoDetails托寄物信息,
"contactInfoList": [寄件人, 收件人],
"isReturnRoutelabel": 1,
"isGenWaybillNo": 1,
"payMethod": 1,
"isDocall": 0,
"monthlyCard": "7551234567"
}
formData = {
"serviceCode": "EXP_RECE_CREATE_ORDER",
"accessToken": accessToken,
"timestamp": sftimestamp,
"partnerID": "MDSKJJ1KDLJN",
"requestID": requestID,
"msgData": orjson.dumps(msgData).decode(encoding="utf-8")
}
response_data = requests.post(
url=沙箱环境, data=formData,
headers={"Content-Type": "application/x-www-form-urlencoded", },
)
apiResultData = jmespath.search(data=response_data.json(), expression="apiResultData")
return Response(data=orjson.loads(apiResultData), status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="order_update")
def 订单确认取消接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
uri = f"https://sfapi-sbox.sf-express.com/std/service"
accessToken = sfToken()
sftimestamp = str(int(datetime.datetime.now().timestamp()))
requestID = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d%H%M%S%f")
msgData = {
"dealType": 1,
"orderId": "SFOD20251126214101523682",
# "totalHeight": 29.98,
# "totalLength": 29.98,
# "totalVolume": 26946.035992000005,
# "totalWeight": 2.09,
# "totalWidth": 29.98,
"waybillNoInfoList": [
{
"waybillNo": "SF7444700285553",
"waybillType": 1
}
]
}
formData = {
"serviceCode": "EXP_RECE_UPDATE_ORDER",
"accessToken": accessToken,
"timestamp": sftimestamp,
"partnerID": "MDSKJJ1KDLJN",
"requestID": requestID,
"msgData": orjson.dumps(msgData).decode(encoding="utf-8")
}
response_data = requests.post(
url=uri, data=formData,
headers={"Content-Type": "application/x-www-form-urlencoded", "charset": "UTF-8"},
)
print(response_data.json(), "=========")
res = response_data.json()
apiResultData = jmespath.search(data=res, expression="apiResultData")
apiResultData = orjson.loads(apiResultData)
return Response(data=apiResultData, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="order_search_resp")
def 订单结果查询接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
uri = f"https://sfapi-sbox.sf-express.com/std/service"
accessToken = sfToken()
sftimestamp = str(int(datetime.datetime.now().timestamp()))
requestID = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d%H%M%S%f")
msgData = {
"searchType": "1",
"orderId": "SFOD20251126214101523682",
"language": "zh-cn"
}
formData = {
"serviceCode": "EXP_RECE_SEARCH_ORDER_RESP",
"accessToken": accessToken,
"timestamp": sftimestamp,
"partnerID": sfID,
"requestID": requestID,
"msgData": orjson.dumps(msgData).decode(encoding="utf-8")
}
response_data = requests.post(
url=uri, data=formData,
headers={"Content-Type": "application/x-www-form-urlencoded", "charset": "UTF-8"},
)
res = response_data.json()
apiResultData = jmespath.search(data=res, expression="apiResultData")
apiResultData = orjson.loads(apiResultData)
return Response(data=apiResultData, status=status.HTTP_200_OK)
SF顺丰业务接口ViewSetsRouter = SimpleRouter()
SF顺丰业务接口ViewSetsRouter.register(prefix="", viewset=SF顺丰业务接口ViewSets, basename="")
@@ -0,0 +1,22 @@
import pydash
import requests
from furl import furl
sfID = "MDSKJJ1KDLJN"
sfCode沙箱码 = "ligo0CNwIN8HLP8kmEguzFRJqpLtsvkQ"
sfCode生产环境 = "lxfzgUcYCsVbVaZXFCpN2N6jPnfWYjrs"
顺风回调路由 = furl(url=f"https://wecom.fujugongxiang.com/sf/sf_callback/").url
def sfToken():
tokneUri = f"https://sfapi-sbox.sf-express.com/oauth2/accessToken"
response_data = requests.post(url=tokneUri, data={"partnerID": sfID, "secret": sfCode沙箱码})
print(response_data.json())
accessToken = pydash.get(obj=response_data.json(), path="accessToken")
apiResponseID = pydash.get(obj=response_data.json(), path="apiResponseID")
return accessToken
if __name__ == "__main__":
pass
@@ -0,0 +1,102 @@
import datetime
import jmespath
import orjson
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 wechat_第三方接口.顺丰物流.顺丰参数 import sfToken
class SF推送ViewSets(ViewSet):
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="push_router")
def 路由推送接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
print('路由推送接口', request.data)
return Response(data={"xiao": "get_xiao接口被调用了"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="pushorderstate")
def 订单状态推送接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
print(request)
postparams = request.data
print(postparams, "订单状态推送接口")
return Response(data={"message": "post_xiao接口被调用了啦"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="push_fee")
def 清单运费推送接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
print("清单运费推送接口", request.data)
return Response(data={"message": "post_xiao接口被调用了啦"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="push_img")
def 图片注册及推送接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
postparams = request.data.get("postparams", False) #
print(request.data, "图片注册推送接口")
return Response(data={"message": "post_xiao接口被调用了啦"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="push_subsidy")
def 国补通知推送接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
return Response(data={"message": "post_xiao接口被调用了啦"}, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", ], url_path="push_register")
def 路由注册接口(self, request: WSGIRequest | Request):
"""
:param request:
:return:
"""
uri = f"https://sfapi-sbox.sf-express.com/std/service"
accessToken = sfToken()
sftimestamp = str(int(datetime.datetime.now().timestamp()))
requestID = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d%H%M%S%f")
msgData = {
"attributeNo": "SF7444700293847", # 订单号或者运单号
"type": "2", # 1-按订单号注册, 2-按运单号注册
"checkPhoneNo": "9784", # 电话号码后四位
"orderId": "SFOD20251127113410676181",
# "clientIp": "10.118.92.11",
"language": "zh-CN", # 响应报文的语言, 缺省值为zh-CN,
"country": "CN" # 国家编码
}
formData = {
"serviceCode": "EXP_RECE_REGISTER_ROUTE",
"accessToken": accessToken,
"timestamp": sftimestamp,
"partnerID": "MDSKJJ1KDLJN",
"requestID": requestID,
"msgData": orjson.dumps(msgData).decode(encoding="utf-8")
}
response_data = requests.post(url=uri, data=formData,
headers={"Content-Type": "application/x-www-form-urlencoded", "charset": "UTF-8"})
print(response_data.json(), "=========")
res = response_data.json()
apiResultData = jmespath.search(data=res, expression="apiResultData")
apiResultData = orjson.loads(apiResultData)
return Response(data=apiResultData, status=status.HTTP_200_OK)
SF推送ViewSetsRouter = SimpleRouter()
SF推送ViewSetsRouter.register(prefix="", viewset=SF推送ViewSets, basename="SF推送ViewSets")