コード例 #1
0
 def delete(self, request, *args, **kwargs):
     '''删除购物车'''
     res_obj = BaseResponse()
     # 1获取信息
     course_id = request.data.get("course_id")
     user_id = request.user.id
     #2进行课程的校验
     if not course_id:
         res_obj.code = 1009
         res_obj.msg = "无效的课程id"
         return Response(res_obj.dict)
     course_obj = models.Course.objects.filter(id=course_id).first()
     #3从内存中获取并进行修改
     shopping_cat_value = CACHE.get(f'SHOPPING_CAT_{user_id}')
     if shopping_cat_value:
         shopping_cat_lst = json.loads(shopping_cat_value)
     else:
         shopping_cat_lst = []
     #对购物车列表进行遍历删除course_id对应的课程,不能循环列表进行删除
     shopping_cat_num = len(shopping_cat_lst)
     for i in range(shopping_cat_num):
         if shopping_cat_lst[i]["id"] == course_id:
             shopping_cat_lst.pop(i)
             res_obj.msg = "删除课程成功"
             # 删除成功后更新缓存
             CACHE.set(f'SHOPPING_CAT_{user_id}',
                       json.dumps(shopping_cat_lst))
             return Response(res_obj.dict)
     else:
         #要删除的课程不再购物车里
         res_obj.code = 1010
         res_obj.msg = "要删除的课程不再购物车里"
         return Response(res_obj.dict)
コード例 #2
0
ファイル: login.py プロジェクト: energy888666/k12
    def post(self, request, *args, **kwargs):
        res_obj = BaseResponse()

        #滑动验证的代码,获取用户提交的验证码
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        challenge = request.data.get(gt.FN_CHALLENGE, '')
        validate = request.data.get(gt.FN_VALIDATE, '')
        seccode = request.data.get(gt.FN_SECCODE, '')
        status = True
        if status:
            # 调用极验科技的接口检验是不是真人
            result = gt.success_validate(challenge, validate, seccode, None)
        else:
            # 本地校验是不是正经人
            result = gt.failback_validate(challenge, validate, seccode)
        if result:
            username = request.data.get("username")
            password = request.data.get("password")
            ##使用内置的auth模块提供的authenticate方法校验用户名密码是否正确(密码是加过密的)
            user_obj = authenticate(username=username, password=password)
            if user_obj:
                logger.debug("用户名密码正确")
                # logger最好接受一个参数,接收两个将会出现报错信息
                # logger.debug(res_obj,user_obj)
                # 创建Token
                token = uuid.uuid1().hex
                #当前时间
                now = datetime.datetime.now(tz=datetime.timezone.utc)
                # 设置到库中
                # ? 不是简单地创建,如果当前用户有token就更新 没有才创建新的
                # models.Token.objects.create(key=token, user=user_obj, created=now)
                obj, created = models.Token.objects.update_or_create(
                    user=user_obj, defaults={
                        "key": token,
                        "created": now
                    })
                #将token设置到缓存中,读取方便:
                cache.set(token, user_obj, settings.AUTH_TOKEN_TIMEOUT)

                #返回token
                res_obj.data = token

            else:
                logger.debug('用户名和密码错误')
                res_obj.code = 20
                res_obj.msg = "用户名或密码错误"
        else:
            res_obj.code = 10
            res_obj.msg = "请滑动验证码进行校验"
        return Response(res_obj.dict)
コード例 #3
0
ファイル: course.py プロジェクト: energy888666/k12
 def get(self, request, *args, **kwargs):
     res_obj=BaseResponse()
     try:
         instance = self.get_object()
         serializer = self.get_serializer(instance)
         res_obj.data=serializer.data
     except Exception as e:
         logger.debug(str(e))
         res_obj.code=3
         res_obj.msg=str(e)
     return Response(res_obj.dict)
コード例 #4
0
ファイル: course.py プロジェクト: energy888666/k12
    def get(self,request,*args,**kwargs):
        res_obj=BaseResponse()
        try:

            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)

            serializer = self.get_serializer(queryset, many=True)
            res_obj.data=serializer.data
        except Exception as e:
            res_obj.code=2
            res_obj.msg=str(e)
        return Response(res_obj.dict)
コード例 #5
0
ファイル: course.py プロジェクト: energy888666/k12
    def get(self,request,*args,**kwargs):
        res_obj=BaseResponse()
        try:
            queryset = self.filter_queryset(self.get_queryset())
            # 手动过滤
            # 拿到过滤的条件
            # category_id = str(request.query_params.get('category', ''))
            # logger.debug(f'category_id:{category_id}')
            # # 如果category_id是0或者不是数字 我们就返回所有的课程
            # if category_id != '0' and category_id.isdigit():
            #     # 按照条件去过滤
            #     queryset = queryset.filter(course_category_id=category_id)
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)

            serializer = self.get_serializer(queryset, many=True)
            res_obj.data = serializer.data
            data = serializer.data
            # 因为要排序的字段是我们序列化的时候自己加的字段,不能使用内置的order_by
            # 进行分类排序
            ordering_key = request.query_params.get("ordering", "")
            logger.debug(f'排序:{ordering_key}')
            if ordering_key:
                if ordering_key.startswith("-"):
                    ordering_key = ordering_key[1:]
                    is_reverse = True
                else:
                    is_reverse = False
                    # 对返回的数据进行排序
                data = sorted(data, key=lambda dict: dict.get(ordering_key, 0), reverse=is_reverse)
            res_obj.data = data
        except Exception as e:
                res_obj.code=1
                res_obj.msg=str(e)
                # logger.debug(str(e)) # debug 级别为10,配置的级别如果高于他,将不会写入文件
                logger.error(str(e)) #error 级别为40 #INFO = 20,waring=30
        return Response(res_obj.dict)
コード例 #6
0
 def get(self, request, *args, **kwargs):
     '''结算中心页面'''
     res_obj = BaseResponse()
     user_id = request.user.id
     # 获取缓存中存在的课程列表信息
     checkout_value = CACHE.get(f"BUY_{user_id}")
     if not checkout_value:
         res_obj.code = 2004
         res_obj.msg = "暂无结算数据"
         logger.warning("暂无结算信息")
         return Response(res_obj.dict)
     buy_list = json.loads(checkout_value)
     #获取通用的优惠券列表
     common_couple_value = CACHE.get(f'COMMON_COUPON_LIST_{user_id}')
     if not common_couple_value:
         common_couple_list = []
     else:
         common_couple_list = json.loads(common_couple_value)
     #拼接返回的数据
     res_obj.data = {
         "checkout_list": buy_list,
         "common_couple_list": common_couple_list
     }
     return Response(res_obj.dict)
コード例 #7
0
ファイル: pay.py プロジェクト: energy888666/k12
    def post(self, request, *args, **kwargs):
        """
          对前端传过来的数据进行校验
          格式如下
          {
              "use_beli":false/true,  贝里
              "course_list":[{ 课程列表
                  "course_id":1,  课程的id
                  "price_policy_id":1,课程价格策略id
                  "coupon_record_id":2 优惠券id
              },
              {
                  "course_id":2,
                  "price_policy_id":4
              }],
              "common_coupon_id":3,通用优惠券的id
              "pay_money":298 总价钱
          }
          """
        res_obj = BaseResponse()
        # TODO 1.获取数据
        user_id = request.user.id
        use_beli = request.data.get("use_beli")
        course_list = request.data.get("course_list")
        common_coupon_id = request.data.get("common_coupon_id", )  #通用优惠券
        pay_money = request.data.get("pay_money")
        now = datetime.datetime.utcnow()

        # TODO 2.对数据进行校验
        # 2.1对课程id进行校验
        course_coupon_price_list = []  # TODO 定义一个列表用来存放每个课程经过用课程优惠券的后价格
        try:
            if not (course_list and f"{use_beli}" and pay_money):
                raise PayException(3000, "提交的信息不全")
            for item in course_list:
                # 获取相关的数据
                course_id = item.get("course_id")
                # print(course_id)
                price_policy_id = item.get("price_policy_id")
                coupon_record_id = item.get("coupon_record_id")
                course_obj = models.Course.objects.filter(id=course_id).first()

                if not course_obj:
                    logger.warning(f'用户:{user_id} 支付 课程:{course_id} 不存在')
                    raise PayException(3001, "支付的的课程id不存在")
        # 2.2对价格策略id进行校验(是否是该课程的)
                price_policy_obj = models.PricePolicy.objects.filter(
                    id=price_policy_id,  # 价格策略id
                    object_id=course_id,  # 课程id
                    content_type__model="course"  # 课程表
                ).first()
                if not price_policy_obj:
                    logger.warning(
                        f'用户:{user_id} 支付 课程:{course_id} 的价格策略{price_policy_id} 不存在'
                    )
                    raise PayException(3002, "无效的价格策略")
        # 2.3对课程的优惠券进行校验
        # 只有勾选课程优惠券才走下面的判断及结算课程券后价格
                course_origin_price = price_policy_obj.price  # 课程原价
                course_coupon_price = course_origin_price  #TODO 假如无优惠券此时就是原来的价格
                if coupon_record_id:
                    coupon_record_obj = models.CouponRecord.objects.filter(
                        id=coupon_record_id,
                        account=request.user,
                        status=0,
                        coupon__content_type__model="course",  # 限定查哪张表
                        coupon__object_id=course_id,  # 限定哪一个课程
                        coupon__valid_begin_date__lte=now,
                        coupon__valid_end_date__gte=now,
                    ).first()

                    if not coupon_record_obj:
                        logger.warning(
                            f'用户:{user_id} 支付 课程:{course_id} 的优惠券{coupon_record_id} 不存在'
                        )
                        raise PayException(3003, "无效的优惠券id")
                    # TODO 使用了课程的优惠券 还需要计算课程券后价格
                    #  TODO 根据优惠券的类型不同 按照不同的规则计算券后价格
                    course_coupon_price = self._clac_coupon_price(
                        course_origin_price, coupon_record_obj)
                    print('#' * 60)
                    print(
                        f'课程名称:{course_obj.name} 原价:{course_origin_price} 券后价:{course_coupon_price}'
                    )
                course_coupon_price_list.append(
                    course_coupon_price)  #TODO 将所有课程价格加入到到总列表中(用过课程券后的)
            sum_course_price = sum(course_coupon_price_list)  # 所有课程的总券后价
            # 2.4对通用的优惠券进行校验
            if common_coupon_id:  #只有使用了通用优惠券才会向下走
                print("2" * 120)
                common_record_obj = models.CouponRecord.objects.filter(
                    id=common_coupon_id,
                    account=request.user,
                    status=0,
                    coupon__content_type__model="course",  # 限定哪一门课程
                    coupon__object_id=None,  # 通用的券
                    coupon__valid_begin_date__lte=now,
                    coupon__valid_end_date__gte=now).first()
                print("*" * 120, common_record_obj)
                if not common_record_obj:
                    print(f'用户:{user_id} 通用券:{common_coupon_id}不存在')
                    raise PayException(3005, "通用券无效")
                common_price = self._clac_coupon_price(
                    sum_course_price, common_record_obj)  #算出来使用通用券后的总价格
            else:
                common_price = sum_course_price
            print('*' * 120)
            print(f'初始总价:{sum_course_price} 券后总价:{common_price}')
            # 2.5对用户的贝里进行校验
            if use_beli:
                my_beli = request.user.beli / 10
                if my_beli > common_price:
                    request.user.beli = (my_beli - common_price) * 10
                    result_price = 10
                    cost_beli = common_price * 10
                else:
                    result_price = common_price - my_beli
                    request.user.beli = 0
                    cost_beli = my_beli * 10  # TODO 记录消费了多少贝里,如果订单取消或超时未支付,再返回来.
                request.user.save(
                )  #TODO 此时需要修改数据库,如果取消了订单在给用户返回,不这样的话,他在多个订单都可以使用贝里
            else:
                result_price = common_price
                cost_beli = 0

        # 2.6对价格进行校验
            if pay_money != result_price:
                logger.warning(f"用户{user_id}支付异常")
                raise PayException(3006, "支付异常")
            else:
                res_obj.msg = "支付成功"
                return Response(res_obj.dict)

        except PayException as e:
            res_obj.code = e.code
            res_obj.msg = e.msg
        except Exception as e:  # 一般不会走到这的
            res_obj.code = 500
            res_obj.msg = str(e)
            logger.error(str(e))
        return Response(res_obj.dict)
        # TODO 3.生成订单
        # TODO 4 .拼接url
        pass
コード例 #8
0
    def post(self, request, *args, **kwargs):
        """
        向后端提交要结算的课程的两种方法
        1. 课程详情页面点击 立即购买
        2. 购物车页面 勾选 批量结算
        因此要写个通用的接口,用列表比较好

        格式:
        {
        course_list:[
            {'course_id': 1, 'price_policy_id': 2},
            {'course_id': 2, 'price_policy_id': 4},
        ]
        }
        需要获取的数据:
         课程图片
         课程名称
         课程的价格策略
         课程的优惠券
         该用户的通用优惠券
        """
        # 1获取提交的信息
        res_obj = BaseResponse()
        # 获取用户提交的购买课程列表
        course_list = request.data.get("course_list")
        # 当前的用户id
        user_id = request.user.id
        # 2进行判断
        if not course_list:
            res_obj.code = 2000,
            res_obj.msg = "缺少课程列表course_list参数"
            logger.debug(res_obj.msg)
            return Response(res_obj.dict)
        # 3校验成功,将课程信息存在结算列表中,放入到缓存中去,经过一系列的操作,最后告知用户创建结算成功,前端拿到后就可以跳转到支付页面
        # 结算列表的格式[{课程1的信息包括id,名字.图片价格,和价格策略对应的期限.还有优惠券信息},{课程2...}]
        checkout_list = []
        # 4循环课程列表信息,拿到课程信息.价格信息,以及优惠券信息
        for item in course_list:
            # 获取课程id
            course_id = item.get("course_id")
            price_policy_id = item.get("price_policy_id")
            # 首先判断参数是否提交
            if not (course_id and price_policy_id):
                res_obj.code = 2001
                res_obj.msg = '无效的参数'
                logger.warning(
                    'post checkout without course_id and price_policy_id.')
                return Response(res_obj.dict)
            course_obj = models.Course.objects.filter(id=course_id).first()
            if not course_obj:
                res_obj.code = 2002
                res_obj.msg = '无效的课程id'
                return Response(res_obj.dict)
            # 4.1当前课程所有的价格策略
            course_price_policy = course_obj.price_policy.all()
            price_policy_obj = models.PricePolicy.objects.filter(
                id=price_policy_id).first()
            if not (price_policy_obj
                    and price_policy_obj in course_price_policy):
                res_obj.code = 2003
                res_obj.msg = "无效的价格策略id"
                return Response(res_obj.dict)
            # 4.2创建数据结构存放课程的相关信息及优惠券信息
            course_info = {}
            course_info["id"] = course_obj.id
            course_info["name"] = course_obj.name
            course_info["course_img"] = course_obj.course_img
            course_info["price_policy_id"] = price_policy_obj.id  #价格策略id
            course_info["price"] = price_policy_obj.price
            course_info[
                "valid_period_test"] = price_policy_obj.get_valid_period_display(
                )
            # 4.3查询该课程的优惠券
            # 查询的关键点 1. 当前用户 2. 当前课程  3. 未使用.4.优惠券在有效时间内
            #  4.3.1查询该用户下有哪些优惠券记录
            # now=datetime.datetime.utcnow()
            # coupon_list = models.CouponRecord.objects.filter(
            #     account=request.user,  # 当前用户
            #     status=0,  # 未使用的
            #     coupon__content_type__model='course',  # 跨表操作,找到课程表
            #     coupon__object_id=course_id,  # 限定哪一个课程
            #     coupon__valid_begin_date__lte=now,  # 这两个条件保证优惠券在有效时间内
            #     coupon__valid_end_date__gte=now
            # )
            # logger.debug(coupon_list)
            # #    4.3.2该课程优惠券可用的列表
            # curser_coupon_list = []
            # for item in coupon_list:
            #     coupon_dict = {
            #         "id":item.coupon.id,  # 优惠券的id
            #         "name": item.coupon.name,  # 跨表优惠券的名称
            #         "coupon_type": item.coupon.get_coupon_type_display(),  # 优惠券的类型
            #         "money_equivalent_value": item.coupon.money_equivalent_value,  # 等值货币
            #         "off_percent": item.coupon.off_percent,  # 百分比
            #         "minimum_consume": item.coupon.minimum_consume,  # 最低消费
            #         # "valid_begin_date":item.coupon.valid_begin_date, # 有效开始时间,json的时候时间不能进行序列化,需要格式化操作
            #         "valid_begin_date":datetime.datetime.strftime(item.coupon.valid_begin_date,"%Y-%m-%d %H:%M:%S"), # 有效开始时间
            #         "valid_end_date":datetime.datetime.strftime(item.coupon.valid_end_date,"%Y-%m-%d %H:%M:%S"), # 有效结束时间
            #     }
            #     # 将优惠券信息加到该课程优惠券列表中
            #     curser_coupon_list.append(coupon_dict)
            # 4.3.3将课程的的优惠券信息保存到课程字典中(利用自己写的方法)
            course_info["curser_coupon_list"] = self._get_coupon_list(
                request, course_id)
            # 5将课程信息放入结算列表中
            checkout_list.append(course_info)
        #6通用优惠券(没有绑定课程的即为通用优惠券)
        common_coupon_list = self._get_coupon_list(request)
        logger.debug("通用优惠券列表:>>", common_coupon_list)
        #将其也保存在缓存中(目的都是获取的时候get方便)
        CACHE.delete(f'COMMON_COUPON_LIST_{user_id}')
        CACHE.set(f'COMMON_COUPON_LIST_{user_id}',
                  json.dumps(common_coupon_list))
        # 7将结算列表存入缓存中区,由于缓存中存在切记先删除,更新成最新的
        CACHE.delete(f'BUY_{user_id}')
        CACHE.set(f'BUY_{user_id}', json.dumps(checkout_list))
        # 7还有一个通用优惠券
        res_obj.msg = "创建结算成功"
        return Response(res_obj.dict)
コード例 #9
0
    def post(self, request, *args, **kwargs):
        res_obj = BaseResponse()

        # 1.先获取用户提交的数据包括,用户id,(课程id,图片,标题),(价格策略,价格)
        # 获取课程的id
        course_id = request.data.get("course_id")
        #获取价格策略的id
        price_policy_id = request.data.get("price_policy_id")
        #获取用户的id
        user_id = request.user.id
        # 2. 校验数据的有效性
        # 2.1对课程id进行校验
        course_obj = models.Course.objects.filter(id=course_id).first()
        if not course_obj:
            res_obj.code = 1000
            res_obj.msg = "无效的课程id"
            return Response(res_obj.dict)
        #2.2对价格策略的有效性进行校验,找到课程对应的价格策略
        price_policy_obj = models.PricePolicy.objects.filter(
            id=price_policy_id).first()
        #当前课程所有的价格策略
        course_price_policy = course_obj.price_policy.all()
        if not (price_policy_obj and price_policy_obj in course_price_policy):
            res_obj.code = 1002
            res_obj.msg = "无效的价格策略"
            return Response(res_obj.dict)
        #先获取当前用户购物车已有的数据
        shopping_cat_value = CACHE.get(f'SHOPPING_CAT_{user_id}')
        if shopping_cat_value:
            shopping_cat_lst = json.loads(
                shopping_cat_value)  # 能取到就把redis中存储的数据反序列化成列表
            # logger.debug(shopping_cat_lst)
        else:
            shopping_cat_lst = []  # 取不到就生成一个空列表
        # 3. 把购物车页面用到的数据都查出来
        # 3.1 把课程所有的价格策略取出来
        price_list = []
        #拿到课程所有的价格策略
        for item in course_price_policy:
            price_list.append({
                "id":
                item.id,
                "valid_period":
                item.valid_period,
                "valid_period_text":
                item.get_valid_period_display(),
                "default":
                True if str(item.id) == price_policy_id else False,
                "prcie":
                item.price
            })
        courser_info = {}
        courser_info["id"] = course_id
        courser_info["default_price_period_id"] = price_policy_id  #默认选中的价格策略id
        courser_info[
            "default_price_period"] = price_policy_obj.get_valid_period_display(
            )  #有效时间
        courser_info["default_price"] = price_policy_obj.price  #默认的价格
        courser_info["relate_price_policy"] = price_list  #价格策略
        # logger.debug(courser_info)
        # 4.判断购物车是否已有该课程
        for i in shopping_cat_lst:
            # logger.debug(type(courser_info["id"]))
            # logger.debug(i)
            if courser_info["id"] == i["id"]:
                res_obj.code = 1003
                res_obj.msg = "该购物车已存在该课程"
                return Response(res_obj.dict)
        #5.没有该课程加入购物车,并放在内存中
        shopping_cat_lst.append(courser_info)  # 把当前这个课程加入购物车列表
        # CACHE.set(f'SHOPPING_CAT_{user_id}',courser_info) #不能放字典,只能放字符串或者数字
        CACHE.set(f'SHOPPING_CAT_{user_id}', json.dumps(shopping_cat_lst))

        res_obj.msg = "加入购物车成功"
        return Response(res_obj.dict)
コード例 #10
0
    def put(self, request, *args, **kwargs):
        res_obj = BaseResponse()
        '''更新购物车,在内存中进行校验'''
        # 1.获取用户更新的信息
        # 获取用户提交的课程id
        course_id = request.data.get("course_id")
        #获取更新的价格策略的id
        price_policy_id = request.data.get("price_policy_id")
        # 获取用户的id
        user_id = request.user.id
        # 2判断是否有效
        if not (course_id and price_policy_id):
            res_obj.code = 1004
            res_obj.msg = '没有参数'
            logger.warning(
                'shopping cart put without course_id and price_policy_id.')
            return Response(res_obj.dict)
        # 判断是否存在
        # course_obj=models.Course.objects.filter(id=course_id).first()
        price_policy_obj = models.PricePolicy.objects.filter(
            id=price_policy_id).first()
        # 3.从内存中获取数据进行更新
        shopping_cat_value = CACHE.get(f'SHOPPING_CAT_{user_id}')
        # 判断内存中该购物车是否有课程
        if not shopping_cat_value:
            res_obj.code = 1005  # 更新时,购物车是空的
            res_obj.msg = "您的购物车为空,无法进行更新"
            logger.debug(res_obj.msg)
            return Response(res_obj.dict)
        #有的话进行序列化
        shopping_cat_list = json.loads(shopping_cat_value)
        #然后进行修改
        for item in shopping_cat_list:  #循环购物车列表
            if str(item["id"]) == course_id:  #找到要修改的课程id,修改价格策略
                #校验修改的价格策略

                valid_price_id = [
                    str(i["id"]) for i in item["relate_price_policy"]
                ]
                if price_policy_id not in valid_price_id:
                    res_obj.code = 1006
                    res_obj.msg = "无效的价格策略"
                    return Response(res_obj.dict)
                #有效后进行修改

                item["default_price_period_id"] = price_policy_id  # 修改更新价格策略id
                item[
                    "default_price_period"] = price_policy_obj.get_valid_period_display(
                    )  # 有效时间
                item["default_price"] = price_policy_obj.price  # 修改的价格
                #循环该课程价格策略,修该默认选中:
                for i in item["relate_price_policy"]:
                    if str(i["id"]) == price_policy_id:
                        i["default"] = True
                    else:
                        i["default"] = False
                res_obj.msg = "修改成功"
                #并在内存中进行修改
                CACHE.set(f'SHOPPING_CAT_{user_id}',
                          json.dumps(shopping_cat_list))
                return Response(res_obj.dict)
        else:
            res_obj.code = 1007
            res_obj.msg = "您的购物车列表无要修改的课程id"
            return Response(res_obj.dict)