Files
sixGuoDjango/django_定时器/幸运拼团业务模型接口.py
2026-08-02 14:07:04 +08:00

193 lines
13 KiB
Python

import datetime
import threading
from datetime import timedelta
from typing import cast
from zoneinfo import ZoneInfo
import jmespath
import orjson
import pydash
import requests
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer, BaseChannelLayer
from django.forms import model_to_dict
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 django_celery.message.tasks import my_task
from django_定时器.团购任务 import TwoHourWindowManager
from django_定时器.幸运拼团数据库 import lucky拼团对象类型, lucky拼团
from sixGuoDjango import ResData, BaseResponse
from wechat_数据库.支付订单数据库.商品订单数据 import order订单
from wechat_数据库.洗衣液商品数据库.六果洗衣液商品 import goods商品, goods商品Choices
from wechat_数据库.用户数据库.小程序登陆用户 import weiuser
from wechat_数据库.雪花算法.雪花算法工具 import generator
from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory, wechatPay
# window = 0
window = TwoHourWindowManager()
default_channel_layer = cast(BaseChannelLayer, get_channel_layer(alias="default"))
class 拼团业务接口ViewSets(ViewSet):
lock = threading.Lock()
def 处理积分方法(self, attach):
pass
# 将字符串转为换字典
attachData = orjson.loads(attach)
# 拿到数据
print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", attachData)
share订单分享者ID = pydash.get(obj=attachData, path="share订单分享者ID")
out_trade_no = pydash.get(obj=attachData, path="out_trade_no")
if share订单分享者ID == "六果":
# 说明没有分享都,啥也不需要干
pass
else:
print("\n🍎 🍏 🍊 有分享者,需要调用添加积分的接口 \n", )
uri = "https://xiao.sixgou.com/integral/pay_add/"
requests.post(url=uri, json={"attachData": attachData})
pass
@action(detail=False, methods=["post"], url_path="current")
def 查询当前的拼团的数据(self, request: Request):
""""""
self_user_unionid = request.data.get("self_user_unionid", None)
self_mini_openid = request.data.get("self_mini_openid", None)
拼团商品 = goods商品.objects.filter(goods商品类型=goods商品Choices.幸运拼团.value).values()
print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", 拼团商品)
查询对象 = lucky拼团.objects.get(idKey=window.generate_str_id)
时间戳 = (查询对象.dateAndTime.astimezone(tz=ZoneInfo("Asia/Shanghai")) + timedelta(seconds=7200)).timestamp()
最终时间戳 = int(时间戳) * 1000 - int(datetime.datetime.now(tz=ZoneInfo("Asia/Shanghai")).timestamp()) * 1000
resData = {"idKey": 查询对象.idKey, "lucky拼团详细": 查询对象.lucky拼团详细, "dateAndTime": 最终时间戳}
httpResData = BaseResponse(resData=ResData(listData=拼团商品, dictData=resData), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
@action(detail=False, methods=["post"], url_path="join")
def 加入拼团支付(self, request: Request):
""""""
url_pay = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi" # 发起请求的链接
self_mini_openid = request.data.get("self_mini_openid", None)
self_mini_unionid = request.data.get("self_mini_unionid", None)
order商品数据 = request.data.get("order商品数据", None)
order商品数量 = request.data.get("order商品数量", None)
order商品总价 = request.data.get("order商品总价", None)
order商品ID = request.data.get("order商品ID", None)
share订单分享者ID = request.data.get("share订单分享者ID", None) # 当前是否有上级对象
order订单类型 = request.data.get("order订单类型", None)
superior_unionid = request.data.get("superior_unionid", None) # 当前是否有上级对象
order用户配送地址 = request.data.get("order用户配送地址", None)
print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", share订单分享者ID, "\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n")
out_trade_no = generator.generate_str()
body = {
"mchid": paymentCategory.mchid, # 【直连商户号】 直连商户号
"out_trade_no": out_trade_no, # 【商户订单号】 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。
"appid": paymentCategory.appid, # 【公众号 或者 小程序ID】
"description": "幸运拼团", # 【商品描述】 商品描述要
"notify_url": "https://xiao.sixgou.com/lucky/update/", # 回调地址要
"amount": {
"total": 1, # 【总金额】 订单总金额,单位为分。
"currency": "CNY", # 【货币类型】 CNY:人民币,境内商户号仅支持人民币。
}, # 【支付者】 支付者信息。
"payer": {
"openid": self_mini_openid, # 【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID,详见OpenID获取
# "openid": OPENID测试, # 【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID,详见OpenID获取
},
"attach": orjson.dumps({"share订单分享者ID": share订单分享者ID}, option=orjson.OPT_SORT_KEYS, ).decode(
encoding="utf-8")
} # 请求的数据
wechat_data = wechatPay(payment=paymentCategory).getpay_jsapi(uri=url_pay, body_data=body, method="POST")
order订单.objects.create(order支付商家侧订单号=out_trade_no,
order商品总价=order商品总价, order商品数据=order商品数据, order商品数量=order商品数量,
order分享者unionid=share订单分享者ID,
order商品ID=order商品ID, order支付数据=body,
wai外键lucky拼团表_id=window.generate_str_id, order支付状态="支付中",
order支付者openid=self_mini_openid, order用户配送地址=order用户配送地址,
order订单类型=order订单类型
)
payData = pydash.get(obj=wechat_data, path="response")
httpResData = BaseResponse(resData=ResData(listData=[""], dictData=payData), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
@action(detail=False, methods=["post"], url_path="update")
def 更新幸运拼团的支付回调接口(self, request: Request):
""" """
with self.lock:
wechat_data支付回调数据 = wechatPay(payment=paymentCategory).callBack回调解密(headers=request.headers,
response_body=request.data)
print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", wechat_data支付回调数据, "返回的结果支付返回",
type(wechat_data支付回调数据))
out_trade_no = jmespath.search(data=wechat_data支付回调数据, expression="out_trade_no")
trade_state_desc = pydash.get(obj=wechat_data支付回调数据, path="trade_state_desc")
self_mini_openid = pydash.get(obj=wechat_data支付回调数据, path="payer.openid")
attach = pydash.get(obj=wechat_data支付回调数据, path="attach")
self.处理积分方法(attach=attach)
# 调用异步方法 : 作用 (发起订单录入接口调用)
share订单分享者ID = pydash.get(obj=orjson.loads(pydash.get(obj=wechat_data支付回调数据, path="attach")),
path="share订单分享者ID")
my_task.apply_async(kwargs={"self_mini_openid": self_mini_openid, "out_trade_no": out_trade_no,
"share订单分享者ID": share订单分享者ID}, countdown=30)
# 更新 拼团订单的 支付状态
生成物流的订单号 = generator.generate_str()
order订单.objects.filter(order支付商家侧订单号=out_trade_no).update(order支付数据=wechat_data支付回调数据,
order支付状态=trade_state_desc,
order物流状态=order订单.order订单choosies物流状态.待发货.value,
order物流订单号=生成物流的订单号
)
当前用户对象 = weiuser.objects.get(mini_openid=self_mini_openid)
参与拼团的对象 = lucky拼团对象类型(wei_openid=self_mini_openid, pay订单号=window.generate_str_id,
avatar=当前用户对象.avatar, nickName=当前用户对象.nickName)
# 查询当前的对象,然后进行数据的更新
当前拼团的对象 = lucky拼团.objects.get(idKey=window.generate_str_id)
print("🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 长度是多少了呢", len(当前拼团的对象.lucky拼团详细))
# 需要判断当前列表的长度,如果大于等于5的话,就需要调用清团重开
if len(当前拼团的对象.lucky拼团详细) >= 4:
# 需要清掉重新
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 新开团的ID是否变更了", window.generate_str_id)
当前拼团的对象.lucky拼团详细.append(参与拼团的对象)
当前拼团的对象.lucky开团状态 = lucky拼团.choosies.已开团.value
当前拼团的对象.save()
对象 = model_to_dict(instance=当前拼团的对象, fields=None)
async_to_sync(awaitable=default_channel_layer.group_send)(group="default_group_name",
message={"lucktyData": 对象,
"type": "chat_Lucky拼团"}, )
window.开团重置()
else:
当前拼团的对象.lucky拼团详细.append(参与拼团的对象)
当前拼团的对象.save()
对象 = model_to_dict(instance=当前拼团的对象, fields=None)
async_to_sync(awaitable=default_channel_layer.group_send)(group="default_group_name",
message={"lucktyData": 对象,
"type": "chat_Lucky拼团"}, )
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="group_opening_order")
def 查询当前开团的最后一个团数据(self, request: Request):
""""""
self_user_unionid = request.data.get("self_user_unionid", None)
self_mini_openid = request.data.get("self_mini_openid", None)
拼团订单号 = window.generate_str_id
# 查询结果 = lucky拼团.objects.filter(lucky开团状态=lucky拼团.choosies.已开团.value, lucky拼团订单__order支付都ID=self_mini_openid,
# lucky拼团订单__order支付状态="支付成功"
# ).order_by("-updateTime")
查询结果 = lucky拼团.objects.filter(lucky开团状态=lucky拼团.choosies.已开团.value,
lucky拼团详细__contains=[{"wei_openid": self_mini_openid}]).order_by(
"-updateTime").first()
print(查询结果, "🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ")
if 查询结果 is None:
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
else:
返回结果数据 = model_to_dict(instance=查询结果, fields=None)
print(返回结果数据, "🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ")
httpResData = BaseResponse(resData=ResData(listData=[], dictData=返回结果数据), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
# 拼团业务接口ViewSetsRouter = DefaultRouter()
# 拼团业务接口ViewSetsRouter.register(prefix="", viewset=拼团业务接口ViewSets, basename="")