递归与树的写法-多种支付的设计-支付的接通-celery订单的回退实现
递归与树的写法
data:
data=[
{"cat_id":1,"name":"北京","parent_id":0},
{"cat_id":2,"name":"上海","parent_id":0},
{"cat_id":3,"name":"沙河","parent_id":1},
{"cat_id":4,"name":"sb镇","parent_id":3},
{"cat_id":5,"name":"昌平","parent_id":1},
{"cat_id":6,"name":"青浦","parent_id":2},
]
#需求
'''
问题:
我们数据不是有序的,但是我们要排序,并归类,把父集放在子集的前面,辈分等级通过level标明 '''
实现的方法
res=[]
def get_son(data,level=0,parent_id=0,is_clear=True):
if is_clear:
res.clear()
for item in data:
if item['parent_id']==parent_id:
item['level']=level
res.append(item)
get_son(data,level=level+1,parent_id=item['cat_id'],is_clear=False)
return res
实现树状的等级分类
'''
问题: 因为前端,需要通过循环多少成来,展示多个等级
for item in data:
print(item.name)
for item1 in item.children
item1.name 归档:我要把我的子集,都放在我的children列表里面 '''
def get_tree(data):
lists=[]
tree={}
for i in data:
tree[i['cat_id']]=i
for item in data:
if not item['parent_id']:
lists.append(tree[item['cat_id']])
else:
if "children" not in tree[item['parent_id']]:
tree[item['parent_id']]['children']=[]
tree[item['parent_id']]['children'].append(tree[item['cat_id']])
return lists
分析
多种支付的设计
例如实现微信或支付宝等支付接口的封装.
封装的支付接口方法
class Notity(APIView):
def post(self,request,paymethon):
pay_file = importlib.import_module(f"app01.Pay.{paymethon}")
pay_class = getattr(pay_file, paymethon)
data=pay_class().notity(request.data)
if data['status']=="success":
models.Order.objects.filter(order_id=data['order']).updata(pay_status=1)
pay.Alipay.py
class Alipay():
def pay(self):
pass
"order/notify/Alipay" def notity(self,data):
data['shangcheng_id']
data['sucess']
if data['sucess']="":
return_data['stauts']="success"
return_data['order_id'] = data['shangcheng_id']
return return_data
else:
pass
pay.Wxpay.py
import time
from app01.wx import settings
class Wxpay:
def pay(self,order_data):
self.order_id = order_data["order_id"]
self.open_id = order_data['open_id']
self.ip = order_data['ip']
data_body = self.get_body_data()
import requests
url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
response = requests.post(url, data_body.encode("utf-8"), headers={'content-type': "application/xml"})
res_dict = self.xml_to_dic(response.content)
timeStamp = str(int(time.time()))
paySign = self.get_pay_sign(res_dict, timeStamp) data_dic = {
'timeStamp': timeStamp,
'nonceStr': res_dict['nonce_str'],
'package': f"prepay_id={res_dict['prepay_id']}",
'signType': 'MD5',
"paySign": paySign,
} return data_dic
支付的接通
from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.cache import cache
from app01 import models import hashlib,time
from django.db import transaction from django import forms
import importlib class OrderForm(forms.Form):
phone = forms.CharField(
error_messages={
"required": "手机号不能为空"
},
# 调用Form组件中的验证器来校验手机号
# validators=[RegexValidator(r'1[1-9][0-9]{9}', '手机号格式不正确')],
)
token = forms.CharField( error_messages={
"required": "token不能为空"
})
province=forms.CharField( error_messages={
"required": "省份不能为空"
})
city = forms.CharField(error_messages={
"required": "城市不能为空"
})
county = forms.CharField(error_messages={
"required": "县/区不能为空"
})
address = forms.CharField(error_messages={
"required": "详细地址不能为空"
})
name = forms.CharField(error_messages={
"required": "姓名不能为空"
})
class Creat(APIView):
@transaction.atomic
def post(self,request):
param=request.data
form_obj=OrderForm(param) if form_obj.is_valid() and param['buy_list']:
if request.META.get("HTTP_X_FORWARDED_FOR"):
host_ip = request.META["HTTP_X_FROWARDED_FOR"]
else:
host_ip = request.META["REMOTE_ADDR"]
user_cache=cache.get(param['token'])
if user_cache:
openid=user_cache.split("&")[0]
user_data=models.Wxuser.objects.filter(openid=openid).first()
order_data = {"consignee_mobile": param['phone'],
'consignee_name': param['name'],
'wxuser_id': user_data.id,
"memo": param['remark'],
"consignee_area":f"{param['province']},{param['city']},{param['county']}",
"consignee_address":param['address'] ,
}
buy_list=param['buy_list']
goods_key=list(buy_list.keys())
all_product=models.Product.objects.filter(product_id__in=goods_key)
order_data['order_id']=func.get_order_id()
order_data['order_total']=0
order_data['quantity']=0
#开启库存
sid=transaction.savepoint()
for product in all_product:
product.product_id=str(product.product_id)
order_data['order_total']+=product.price*buy_list[product.product_id]
order_data['quantity']+=buy_list[product.product_id] #创建子订单
for i in range(3):
#查询当前库存
stock=product.stock.quantity
#当前减轻购买的数量,等于剩余的库存
new_stock=stock-buy_list[product.product_id]
#判断库存是否足够
if new_stock<0:
#回滚
transaction.savepoint_rollback(sid)
#如果库存不住够,我们直接返回
return Response({"code":203,"msg":f"{product.name}库存不足"})
res=models.Stock.objects.filter(quantity=stock,stock_id=product.stock.stock_id).update(quantity=new_stock)
if not res:
if i==2:
transaction.savepoint_rollback(sid)
return Response({"code": 203, "msg": f"创建订单失败"})
else:
continue
else:
break
new_buy_count = product.buy_count + buy_list[product.product_id]
models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count)
order_item_data={'order_id': order_data['order_id'], 'product_id': product.product_id, \
"name": product.name, "image": product.image, "price": product.price, \
"nums": buy_list[product.product_id], "brief": product.brief}
models.Order_items.objects.create(**order_item_data)
models.Order.objects.create(**order_data)
pay_methon="Wxpay"
try:
pay_file=importlib.import_module(f"app01.Pay.{pay_methon}")
pay_class=getattr(pay_file,pay_methon)
order_data['open_id'] = openid
order_data['ip']=host_ip
data=pay_class().pay(order_data)
except:
transaction.savepoint_rollback(sid)
return Response({"code": 200, "msg": "未知的支付方式" }) transaction.savepoint_commit(sid)
func.add_task(order_data['order_id'])
return Response({"code": 200, "msg": "ok" ,"data":data}) else:
return Response({"code":202,"msg":"token已过期"})
else:
return Response({"code":201,"msg":"缺少参数"})
celery实现订单的回退
简单的理解就是通过celery异步回调的机制,设置代码段过多少时间之后再去工作,把发起订单后为支付的数据信息返回。
task方法:
from pro_celery.celery import del_order
def add_task(order_id,seconds=5):
ctime = datetime.now()
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=seconds)
task_time = utc_ctime + time_delay
result = del_order.apply_async(args=[order_id, ], eta=task_time)
celery.py方法的封装
import celery
import time
# broker='redis://127.0.0.1:6379/2' 不加密码
backend='redis://127.0.0.1:6379/1'
broker='redis://127.0.0.1:6379/2'
cel=celery.Celery('test',backend=backend,broker=broker) import os, sys
import django
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # 定位到你的django根目录
# sys.path.append(os.path.join(BASE_DIR, "app01"))
sys.path.append(os.path.abspath(BASE_DIR))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wxshop.settings")
django.setup()
from django.db import transaction @cel.task
@transaction.atomic
def del_order(order_id):
'''
1 拿订单查询,订单号,是否支付,活跃
2 判断data是否有 :param order_id:
:return:
'''
from app01 import models
data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active").first()
if data:
item_data=models.Order_items.objects.filter(order_id=order_id).values("product","nums")
# [{product:1,nums:3}]
# {1:3,2:1}
all_product_dict = { k['product']:k['nums'] for k in item_data}
all_product_id =list(all_product_dict.keys())
products_all=models.Product.objects.filter(product_id__in=all_product_id)
sid=transaction.savepoint() for product in products_all:
for i in range(3):
stock=product.stock.quantity
new_stock=stock+all_product_dict[product.product_id]
new_buy_count=product.buy_count-all_product_dict[product.product_id]
res=models.Stock.objects.filter(quantity=stock,stock_id=product.stock).update(quantity=new_stock)
if not res:
if i==2:
from app01.comment import func
transaction.savepoint_rollback(sid)
func.add_task(order_id,1)
return
else:
continue
else:
break
models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count) row=models.Order.objects.filter(order_id=order_id,pay_status=0).update(status="dead")
if row:
transaction.savepoint_commit(sid)
else:
transaction.savepoint_rollback(sid)
递归与树的写法-多种支付的设计-支付的接通-celery订单的回退实现的更多相关文章
- 菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)
初学Web端开发,今天是第一次将所学做随笔记录,肯定存在多处欠妥,望大家海涵:若有不足,望大家批评指正. 进实验室后分配到的第一个项目,需要制作一个不确定层级树形菜单的数据接口,对于从来没实战编过程的 ...
- ASP.NET通过递归添加树(Treeview)
先来看看效果,基本上就是这样的. 所谓树,无非就是2点,第一个:根节点,第二:叶子节点,其中叶子节点中还可能有叶子节点,但是根节点始终只有一个. 下面贴上 各部分的代码 1.PAGE_LOAD载入事件 ...
- C# 递归构造树状数据结构(泛型),如何构造?如何查询?
十年河东,十年河西,莫欺少年穷. 学无止境,精益求精 难得有清闲的一上午,索性写篇博客. 首先,我们需要准备一张表,如下范例: create table TreeTable ( TreeId ) no ...
- oracle的递归运算(树运算) 无限树形
oracle的递归运算(树运算)start with org_id ='1'connect by prior parent_id=son_id 1.前言 oracle的递归运算,在我们web页面的 ...
- LeetCode--二叉树2--运用递归解决树的问题
LeetCode--二叉树2--运用递归解决树的问题 在前面的章节中,我们已经介绍了如何利用递归求解树的遍历. 递归是解决树的相关问题最有效和最常用的方法之一. 我们知道,树可以以递归的方式定义为一个 ...
- 微信公众号中的支付宝支付与微信支付 && 支付宝支付问题(微信bug)
一般,在微信公众号中的商城都是需要支持微信支付和支付宝支付的,当然,较大的公司对于鹅厂和阿里的站队就不说了,所以这里简单记录一下支付宝支付和微信支付的主要流程.说是简单介绍,这是因为确实不难,因为前端 ...
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-1.常用的第三方支付和聚合支付介绍
笔记 第六章 开发在线教育视频站点核心业务之从零基础接入 微信扫一扫网页支付 1.常用的第三方支付和聚合支付介绍 简介:介绍常用的第三方支付和聚合支付 1.什么是第三方支付 第 ...
- Java之微信支付(扫码支付模式二)案例实战
摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...
- iOS-集成支付宝支付、微信支付简单总结
支付宝快捷支付: 官方文档中,支付宝说建议我们使用支付时要讲签名过程放在服务器端,这样安全.同时给的demo中签名是在本地移动端做的...不过支付宝的集成还是较简单的. 为了安全签名当然放后台做了.我 ...
随机推荐
- UVA - 1153 Keep the Customer Satisfied(顾客是上帝)(贪心)
题意:有n(n<=800000)个工作,已知每个工作需要的时间qi和截止时间di(必须在此之前完成),最多能完成多少个工作?工作只能串行完成.第一项任务开始的时间不早于时刻0. 分析:按截止时间 ...
- 如何生成 SSH keys, 并在 Github 或 Gitlab 等上添加密钥
1 打开 Git Bash $ 2 输入 dir, 确认当前文件夹,并切换到想存密钥文件即pub文件的路径 $ dir 3 生成 密钥命令 ssh-keygen -t rsa -C "{ y ...
- Arduino - Nano针脚分配时需要注意的事项
0.1为Rx.Tx 针脚,这两个针脚一般作为串口使用,非串口设备尽量不占用该针脚.2.3为中断口,分别对应中断0.中断1,需要中断功能的设备,必须接入此.2-13.A0-A5,共18个针脚,都可以作为 ...
- bzoj 3876: [Ahoi2014]支线剧情
就是加一个1的下界就好了. #include<bits/stdc++.h> #define N 100005 #define LL long long #define inf 0x3f3f ...
- 调用servlet报The requested resource is not available.
调用servlet的时候经常有这种报错,一般来说我直到现在遇到的情况大致有以下几类: 1.参数写错了 在新创建的servlet文件中有这么一行代码,“/LoginCheck”这个一定要和form表单中 ...
- 关于spring cloud “Finchley.RC2”版本在spring cloud config中的ArrayIndexOutOfBoundsException
原文 https://www.cnblogs.com/Little-tree/p/9166382.html 在学spring cloud config的时候遇到一个ArrayIndexOutOfBou ...
- UML-持久框架-目标&关键思想
1.目标 1).使用模板方法.状态模式.命令模式来设计部分框架 2).介绍对象-关系(O-R)映射中的一些问题 3).使用虚代理实现的滞后具体化 2.关键思想 1).映射(Mapping) 类--表 ...
- POJ 3911:Internet Service Providers
Internet Service Providers Time Limit: 2MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I ...
- XML--XML Schema Definition(一)
参考 https://blog.csdn.net/wangw2008/article/details/83195283 https://blog.csdn.net/lmj623565791/artic ...
- LVS DR模式搭建、keepalived+LVS搭建介绍
参考文献 http://blog.51cto.com/taoxie/2066993 疑问: 1.为什么要修改RealServer的返回arp响应和发送arp请求参数 echo "1&quo ...