• 订单相关


    class Creat(APIView):   # 创建订单
        @transaction.atomic   # 开启事务
        def post(self,request):
            param=request.data
            order_obj=OrderForm(request.data)
            host_ip=request.get_host()
            goods_list=param.get("buy_list")
            #这个的goods_list,就是用户下单的商品以及数量
            #数据格式{"2":2,"1":2}
            if order_obj.is_valid() and goods_list:
                open_id=function.check_login_key(param['token'])
                if not open_id:
                    return Response({"code":200,"msg":"token不对"})
                user=models.Wxuser.objects.filter(openid=open_id).first()
                # 组织订单的信息
                order_data={"consignee_mobile":param['phone'],'consignee_name':param['name'],'wxuser_id':user.id,
                            "memo":param['remark'],"consignee_address":f"{param['province']},{param['city']},{param['county']}",
                            }
                order_data['order_id']=function.get_order_id()
    
                order_data['order_total']=0
                order_data['quantity']=0
                goods_list_id = list(goods_list.keys())
                #这里是所有商品的信息
                all_good_info=models.Product.objects.filter(product_id__in=goods_list_id)
                sid=transaction.savepoint()   # 创建一个保存点,当数据库出现错误时,可以返回到当前状态
                for goods in all_good_info:
                    goods.product_id = str(goods.product_id)
                    order_data["order_total"]+=goods.price*goods_list[goods.product_id]
                    order_data['quantity']+=goods_list[goods.product_id]
                    for i in range(3):
                        stock=goods.stock.quantity  # 点的时候还是在查数据库,拿到最新的数据
                        new_quantity=stock-goods_list[goods.product_id]
    
                        #判断库存是否够
                        if new_quantity < 1:
                            transaction.savepoint_rollback(sid)      # 在一定条件下,事务回滚到保存点
                            return Response({
                                "code": 200,
                                'msg': "库存不足"
                            })
                        buy_count=goods.buy_count+goods_list[goods.product_id]
                        res=models.Stock.objects.filter(quantity=stock,stock_id=goods.stock.stock_id).update(quantity=new_quantity)
                        if res==0:
                            if i==2:  # 多循环几次,尽量操作成功
                                transaction.savepoint_rollback(sid)
                                return Response({"code":200,"msg":"下单失败"})
                            continue
                        else:
                            break
                    order_item_data = {'order_id': order_data['order_id'], 'product_id': goods.product_id, 
                                       "name": goods.name, "image": goods.image, "price": goods.price, 
                                       "nums": goods_list[goods.product_id], "brief": goods.brief}
                    models.Order_items.objects.create(**order_item_data)   # 创建子订单
                    models.Product.objects.filter(product_id=goods.product_id).update(buy_count=buy_count)
                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['ip']=host_ip.split(":")[0]
                    order_data['open_id']=open_id
                    data=pay_class().pay(order_data)
                    transaction.savepoint_commit(sid)
                    #提交一个celery任务检查订单
                    function.add_task(order_data['order_id'])
                    return Response({"code":0,"msg":"成功","data":data})
                except:
                    transaction.savepoint_rollback(sid)
                    return  Response({"code":200,"msg":"未知的支付方式"})
            else:
                return Response({"code":200,"msg":"数据错误"})
    
    
    
    from datetime import datetime
    from app01.tasks import del_order
    def add_task(order_id,how_time=0):
        ctime = datetime.now()
        utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
        from datetime import timedelta
        time_delay = timedelta(seconds=900)
        # time_delay = timedelta(seconds=how_time)  # 传过来的时间去确定多久执行一次,而非固定时间,更加人性化
    
        task_time = utc_ctime + time_delay
        result = del_order.apply_async(args=[order_id, ], eta=task_time)
        print(result)
    
    
    
    @task
    @transaction.atomic
    def del_order(order_id):
            #把他当作一个脚本,如果要用的话,我就要启动django
            BASE_DIR = os.path.dirname(os.path.dirname(__file__))  # 定位到你的django根目录
            sys.path.append(os.path.abspath(BASE_DIR))
            os.environ.setdefault("DJANGO_SETTINGS_MODULE", "py8api.settings")
            django.setup()
            from app01 import models
            #检查该订单是否被支付,
            order_data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active")
            #如果没有被支付
            if order_data:
                #获取该订单的所有子订单中的商品和商品的数量
                order_items=models.Order_items.objects.filter(order_id=order_id).values('product','nums')
                #将查出来的商品和数量做成字典:{product_id:nums}
                goods_list= {item['product']:item['nums'] for item in order_items}
                #获取所有的商品的id
                goods_list_id=list(goods_list.keys())
                #获取所有的商品
                all_goods_info = models.Product.objects.filter(product_id__in=goods_list_id)
                #开启事务
                sid = transaction.savepoint()
                #循环处理。所有的商品
                for goods in all_goods_info:
                    # 如果下单成功后的库存
                    for i in range(3):
                        new_quantity = goods.stock.quantity + goods_list[goods.product_id]
                        buy_count = goods.buy_count - goods_list[goods.product_id]
                        res = models.Stock.objects.filter(quantity=goods.stock.quantity, stock_id=goods.stock.stock_id).update(
                            quantity=new_quantity)
                        if res == 0:
                            if i == 2:
                                # 回滚
                                transaction.savepoint_rollback(sid)
                                #但是还要继续提交任务取消订单
                                from  app01.comment import function
                                function.add_taks(order_id)
                                return
                            continue
                        else:
                            models.Product.objects.filter(product_id=goods.product_id).update(buy_count=buy_count)
                            break
                res= models.Order.objects.filter(order_id=order_id, pay_status=0,status="active").update(status="dead")
                if res ==0 :
                    #订单刚好付款了
                    transaction.savepoint_rollback(sid)
                transaction.savepoint_commit(sid)
  • 相关阅读:
    C puzzles详解【51-57题】
    C puzzles详解【46-50题】
    C puzzles详解【38-45题】
    C puzzles详解【34-37题】
    C puzzles详解【31-33题】
    C puzzles详解【26-30题】
    C puzzles详解【21-25题】
    C puzzles详解【16-20题】
    使用C++模板实现栈的求最小值功能
    模拟求幂运算,考虑的已经很周全了
  • 原文地址:https://www.cnblogs.com/changwenjun-666/p/11669395.html
Copyright © 2020-2023  润新知