DAY110 - 路飞学城(六)- 路飞学城之结算中心,支付中心

一、路飞学城之结算中心

数据格式

# 用户选中的课程以及优惠券
payment_用户ID{
    '课程ID':{
        'default_coupon':选中的优惠券,
        'coupon':当前课程的优惠券
                {
                    '优惠券ID':{
                        "coupon_type":0,
                        "coupon_display":"立减券",
                        "money_equivalent_value":10
                    },
                    '优惠券ID':{
                        "coupon_type":1,
                        "coupon_display":"满减券",
                        "money_equivalent_value":10,
                        "minimum_consume":100
                    },
                    '优惠券ID':{
                        "coupon_type":2,
                        "coupon_display":"折扣券",
                        "off_percent":90
                    },
                },
        'title':课程名,
        'img':课程图片,
        'default_policy':选中价格策略,
        'policy':{
            当前课程的所有价格策略
            'policy的ID':{
                {
                   "period":课程周期(天),比如30,
                   "period_display":课程周期的简写,30天==1个月,
                   "price": 对应的价格
                }
            },
            ........
        }
    },
    .........
}


# 全站的优惠券
{
    'coupon':{
            '优惠券ID':{
                "coupon_type":0,
                "coupon_display":"立减券",
                "money_equivalent_value":10
            },
            '优惠券ID':{
                "coupon_type":1,
                "coupon_display":"满减券",
                "money_equivalent_value":10,
                "minimum_consume":100
            },
            '优惠券ID':{
                "coupon_type":2,
                "coupon_display":"折扣券",
                "off_percent":90
            },
        },
}

添加到结算中心

# 从前端拿到了用户想结算的课程数据,然后在后台处理,返回带优惠卷的课程数据和全站优惠卷
def post(self, request):
    '''
    业务逻辑:
    1 定义结算中心的字典,定义全局优惠券的字典
    2 拿到购物车,循环取出传入的课程id
    3 构造单个课程详情的字典,把购物车中的当前课程,update到该字典中
    4 将该课程详情,加入到结算中心
    5 一次性查出当前用户的所有优惠券信息(用户为当前用户,状态为未使用,优惠券起始时间小于当前时间,优惠券结束时间大于当前时间)
    6 循环所有优惠券
    7 构造出单个优惠券的空字典,拿到优惠券类型(1立减 2 满减 3折扣),拿到优惠券id,拿到该优惠券绑定的课程id(有可能为空)
    8 构造单个优惠券字典,将数据填充进去
    9 判断是全站优惠券还是课程优惠券
    10 讲结算中心字典和全局优惠券字典,放入redis中
    :param request:
        {
            "course_list":[
                {
                    "course_id":"1",
                    "policy_id":"1"
                },
                {
                    "course_id":"2",
                    "policy_id":"2"
                },
                .......
            ]
        }
    :return:
    '''
    response = MyResponse()
    course_list = request.data.get('course_list')
    try:
        # 1 定义结算中心的字典,定义全局优惠券的字典
        payment = {}
        global_coupon_dict = {
            'coupon': {},
            'dafault_coupon': '0',
        }

        # 2拿到购物车,获得正确的课程详情放入结算中心的字典中
        shoppingcart = self.conn.get('shoppingcart_%s' % request.user.pk)
        shoppingcart_dic = json.loads(shoppingcart) if shoppingcart else {}

        # 3 循环取出传入的course_list的课程id,循环结束后,把结算中心payment中的课程详情填满(除了课程的优惠券)
        for course in course_list:
            course_id = course['course_id']
            # 判断传入的课程id是否在购物车中
            if course_id not in shoppingcart_dic:
                raise CommonException(101, '当前结算的课程不在购物车中')

            # 构造一个课程详情的字典
            course_detail = {
                'coupon': {},
                'dafalut_coupon': 0,
            }
            # 把购物车中的当前课程,update到该字典中
            course_detail.update(shoppingcart_dic[course_id])

            # 以course_id为Key,对应的course_detail为value,将该课程详情,加入到结算中心
            payment[course_id] = course_detail

        # 4一次性查出当前用户的所有优惠券信息(用户为当前用户,状态为未使用,优惠券起始时间小于当前时间,优惠券结束时间大于当前时间)
        import datetime
        ctime = datetime.datetime.now()
        # 可使用的优惠券
        coupon_list = models.CouponRecord.objects.filter(user=request.user, status=0,
                                                         coupon__valid_begin_date__lte=ctime,
                                                         coupon__valid_end_date__gte=ctime)
        # 5循环所有优惠券
        for coupon in coupon_list:
            # 6构造出单个优惠券的空字典,拿到优惠券类型(1立减2满减3折扣),拿到优惠券id,拿到该优惠券绑定的课程id(有可能为空)

            # 优惠券类型(0,1,2)
            coupon_type = coupon.coupon.coupon_type
            # 优惠券类型(立减,满减,折扣)
            coupon_type_display = coupon.coupon.get_coupon_type_display()
            # 绑定的课程id
            object_id = coupon.coupon.object_id
            # 优惠券id
            coupon_id = str(coupon.pk)

            # 7构造单个优惠券字典,将数据填充进去
            coupon_detail = {
                "coupon_type": coupon_type,
                "coupon_display": coupon_type_display,
            }
            if coupon_type==0:# 立减
                coupon_detail['money_equivalent_value'] = coupon.coupon.money_equivalent_value
            elif coupon_type==1:# 满减
                coupon_detail['money_equivalent_value'] = coupon.coupon.money_equivalent_value
                coupon_detail['minimum_consume'] = coupon.coupon.minimum_consume
            else:
                coupon_detail['off_percent'] = coupon.coupon.off_percent

            # 8.单个优惠券字典字典构造完成,判断是全站优惠券还是课程优惠券
            # 全站优惠券
            if not object_id :
                global_coupon_dict['coupon'][coupon_id]=coupon_detail
            else:
                # 课程优惠券
                # 由于是在循环所有的优惠券,包括了没选的课程的优惠券,所以要判断当前优惠券的课程ID是否在结算中心的字典中
                if payment.get(str(object_id),None):
                    payment[str(object_id)]['coupon'][coupon_id]=coupon_detail

        # 9讲结算中心字典和全局优惠券字典,放入redis中
        self.conn.set('payment_%s' % request.user.pk,json.dumps(payment))
        self.conn.set('global_coupon_%s' % request.user.pk,json.dumps(global_coupon_dict))
        response.msg = '成功'
    except ObjectDoesNotExist as e:
        response.status = 101
        response.msg = '课程不存在'
    except CommonException as e:
        response.status = e.status
        response.msg = e.msg
    except Exception as e:
        response.status = 400
        response.msg = '未知错误'
        print(e)
    return Response(response.get_dic)

修改数据

# 更改某一门课的当前优惠卷
def put(self, request):
    # {"course_id": "1", "coupon_id": "1"}
    response = MyResponse()
    course_id = request.data.get('course_id')
    coupon_id = request.data.get('coupon_id')
    try:
        # 获取redis中的payment数据
        payment_bytes = self.conn.get('payment_%s' % request.user.pk)
        payment_dic = json.loads(payment_bytes) if payment_bytes else {}

        # 判断course_id是否合法
        if course_id not in payment_dic:
            raise CommonException(102, '课程不合法')

        # 判断coupon_id是否合法
        if coupon_id not in payment_dic[course_id]['coupon']:
            raise CommonException(102, '优惠券不合法')

        payment_dic[course_id]['dafalut_coupon'] = coupon_id

        self.conn.set('payment_%s' % request.user.pk,json.dumps(payment_dic))

        response.msg = '成功'
    except ObjectDoesNotExist as e:
        response.status = 101
        response.msg = '课程不存在'
    except CommonException as e:
        response.status = e.status
        response.msg = e.msg
    except Exception as e:
        response.status = 400
        response.msg = '未知错误'
        print(e)
    return Response(response.get_dic)

显示数据

def get(self, request):
    response = MyResponse()
    try:
        # 获取redis中的payment数据
        payment_bytes = self.conn.get('payment_%s' % request.user.pk)
        payment_dic = json.loads(payment_bytes) if payment_bytes else {}

        global_coupon = self.conn.get('global_coupon_%s' % request.user.pk)
        global_coupon_dic = json.loads(global_coupon) if global_coupon else {}

        response.data={
            'global_coupon':global_coupon_dic,
            'payment':payment_dic,
        }
        response.msg = '成功'
    except ObjectDoesNotExist as e:
        response.status = 101
        response.msg = '课程不存在'
    except CommonException as e:
        response.status = e.status
        response.msg = e.msg
    except Exception as e:
        response.status = 400
        response.msg = '未知错误'
        print(e)
    return Response(response.get_dic)

删除课程

def delete(self, request):
    # {"course_id": "1"}
    response = MyResponse()
    course_id = request.data.get('course_id')
    try:
        # 获取redis中的payment数据
        payment_bytes = self.conn.get('payment_%s' % request.user.pk)
        payment_dic = json.loads(payment_bytes) if payment_bytes else {}

        # 判断course_id是否合法
        if course_id not in payment_dic:
            raise CommonException(102, '课程不合法')

        payment_dic.pop(course_id,None)

        self.conn.set('payment_%s' % request.user.pk,json.dumps(payment_dic))

        response.msg = '删除成功'
    except ObjectDoesNotExist as e:
        response.status = 101
        response.msg = '课程不存在'
    except CommonException as e:
        response.status = e.status
        response.msg = e.msg
    except Exception as e:
        response.status = 400
        response.msg = '未知错误'
        print(e)
    return Response(response.get_dic)

二、路飞学城之支付中心

# 支付成功后,并且支付宝回调,才去对购物车和结算中心清空
class Account(APIView):
    authentication_classes = [Login_token]
    conn = get_redis_connection()

    def post(self, request):
        response = MyResponse()
        price_in = request.data.get('price')
        bely = request.data.get('bely')
        try:
            payment_bytes = self.conn.get('payment_%s' % request.user.pk)
            payment_dic = json.loads(payment_bytes) if payment_bytes else {}
            global_coupon = self.conn.get('global_coupon_%s' % request.user.pk)
            global_coupon_dic = json.loads(global_coupon) if global_coupon else {}

            list_price = []
            # 循环所有课程是为了计算每个课程优惠券优惠后的价格
            for course_id, course_detail in payment_dic.items():
                # 取出默认价格策略,取出默认价格,取出默认优惠券id
                default_policy = course_detail['default_policy']
                default_price = course_detail['policy'][str(default_policy)]['price']
                default_coupon_id = course_detail['default_coupon']

                # !=0说明是选择了优惠券的
                if default_coupon_id !='0':
                    # 默认优惠券对应详情
                    default_coupon_detail = course_detail['coupon'][str(default_coupon_id)]
                    default_price = self.account(default_coupon_id, default_price, default_coupon_detail)
                # 课程优惠后的价格:default_price
                # 所有课程价格列表:list_price
                list_price.append(default_price)


            # 默认全站优惠券ID
            global_coupon_id = global_coupon_dic['dafault_coupon']
            global_coupon_price = sum(list_price)
            if global_coupon_id!='0':
                # 默认全站优惠券详情
                global_coupon_detail = global_coupon_dic['coupon'][str(global_coupon_id)]
                # 全站优惠后的价格
                global_coupon_price = self.account(global_coupon_id, sum(list_price), global_coupon_detail)



            # 贝利可以抵一部分钱

            if int(bely) > request.user.bely:
                raise CommonException(102,'贝利数超出用户本身所有,不合法')
            # 最后的价格:final_price
            final_price = global_coupon_price - int(bely) / 10
            # 把剩余的贝利存入数据库
            request.user.bely = request.user.bely - int(bely)
            request.user.save()

            if not final_price==float(price_in):
                raise CommonException(103,'传入的价格与计算不一致')
            if final_price<=0:
                final_price=0
            # 为了测试数据,所以没有用支付宝接口
            # 构造支付宝链接
            # 拼凑支付宝url
            # alipay = ali()
            # import time
            # # 生成支付的url
            # query_params = alipay.direct_pay(
            #     subject="路飞学成课程",  # 商品简单描述
            #     out_trade_no="x2" + str(time.time()),  # 商户订单号
            #     total_amount=final_price,  # 交易金额(单位: 元 保留俩位小数)
            # )
            # pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
            pay_url = "https://openapi.alipaydev.com/gateway.do?"
            response.url = pay_url
            response.msg = '成功'
        except ObjectDoesNotExist as e:
            response.status = 101
            response.msg = '课程不存在'
        except CommonException as e:
            response.status = e.status
            response.msg = e.msg
        except Exception as e:
            response.status = 400
            response.msg = '未知错误'
            print(e)
        return Response(response.get_dic)

    # 把优惠券的计算单独封装
    def account(self,default_coupon_id,default_price,default_coupon_detail):
        if default_coupon_id == '1':  # 立减
            default_price = default_price - default_coupon_detail['money_equivalent_value']
        elif default_coupon_id == '2':  # 满减
            if default_price >= 100:
                default_price = default_price - default_coupon_detail['money_equivalent_value']
            else:
                raise CommonException(102, '不满足最低消费金额')
        else:
            default_price = default_price * default_coupon_detail['off_percent'] / 100
        return default_price

猜你喜欢

转载自www.cnblogs.com/xvchengqi/p/10197749.html
今日推荐