• 课程项目


    购物车:
    -往后台传输数据(价格策略id,课程id)
    -{"course_id":"1","policy_id":"3"}
    -为什么要放到redis
    -存储数据方式:(key值为:shopping_card_userid)
    shopping_card_userid={
    "1":{
    "title":"Django从入门到放弃",
    "img":"django.png",
    "default_policy":"3",
    "policy":{
    "1":{
    "period":3,
    "period_display":"3天",
    "price":200
    },
    "3":{
    "period":60,
    "period_display":"2个月",
    "price":1000
    },
    "4":{
    "period":30,
    "period_display":"1个月",
    "price":500
    }
    }
    },
    "2":{
    "title":"Git操作",
    "img":"git.png",
    "default_policy":"2",
    "policy":{
    "2":{
    "period":30,
    "period_display":"1个月",
    "price":60
    },
    "5":{
    "period":1,
    "period_display":"1天",
    "price":0
    },
    "6":{
    "period":90,
    "period_display":"3个月",
    "price":50
    }
    }
    }
    }
    -校验规则:
    -校验课程是否存在
    -校验价格策略是否合法
    -把价格策略拼成一个字典,直接用id in 字典,判断价格策略是否合法
    -取出原来购物车的商品,更新,或者新增
    -传过来的id 在购物车字典中,只要修改默认价格策略即可
    -传过来的id不在购物车字典中,直接新增
    -存到redis


    -购物车整个逻辑:
    -(1)添加购物车 ----post:{"course_id":"1","policy_id":"1"}
    -1 校验课程是否存在
    -2 获取所有价格策略
    -3 从redis中取出当前登录用户的购物车
    shoping_card_byte=self.conn.get(redis_str)
    shoping_card_dic=json.loads(shoping_card_byte) if shoping_card_byte else {}
    -4 循环价格策略组装成以下形式
    {
    "period":3,
    "period_display":"3天",
    "price":200
    }
    polic_dict[str(item.id)] = {
    "period": item.valid_period,
    "period_display": item.get_valid_period_display(),
    "price": item.price,
    }
    -5 校验价格策略是否是该课程的价格策略(判断传入的policy_id是否在上面的字典中)
    -6 价格策略合法,构造出购物车字典(如果购物车中有该课程,修改的是默认策略)
    shoping_card_dic[course_id] = {
    'title': course.name,
    'img': course.course_img,
    'default_policy': policy_id,
    'policy': polic_dict
    }
    -7 转成json,存入redis name值为:'shopping_%s' % (request.user.id,)
    -(2)修改购物车中某个课程价格策略---patch:{"course_id":"1","policy_id":"1"}
    -1 从redis中取出购物车
    -2 判断价格策略是否合法(也就是是否在当前课程的policy字典中)
    -3 在的话,直接修改default_policy为传入的policy_id
    shopping_card[course_id]['default_policy'] = policy_id
    -4 把数据写回redis
    self.conn.set(redis_str, json.dumps(shopping_card))
    -(3)删除购物车中课程---delete:{"course_id":"1"}
    -1 从redis中取出购物车
    -2 从购物车中pop掉当前传入的course_id
    -3 把数据写会redis
    -(4)获取购物车---get
    -1 从redis中取出购物车
    -2 把购物车放到res.data 中返回


    优惠券表介绍:

    结算中心:
    -请求格式:
    {"course_list":[{"course_id":"1","policy_id":"1"},{"course_id":"2","policy_id":"2"}]}
    -存储格式(结算中心和全局优惠券格式):
    {
    "1":{
    "coupon":{
    "7":{
    "coupon_type":0,
    "coupon_display":"立减券",
    "money_equivalent_value":10
    },
    "8":{
    "coupon_type":1,
    "coupon_display":"满减券",
    "money_equivalent_value":10,
    "minimum_consume":100
    },
    "9":{
    "coupon_type":2,
    "coupon_display":"折扣券",
    "off_percent":90
    }
    },
    "title":"Django从入门到放弃",
    "img":"django.png",
    "default_policy":"3",
    "policy":{
    "1":{
    "period":3,
    "period_display":"3天",
    "price":200
    },
    "3":{
    "period":60,
    "period_display":"2个月",
    "price":1000
    },
    "4":{
    "period":30,
    "period_display":"1个月",
    "price":500
    }
    }
    },
    "2":{
    "coupon":{

    },
    "title":"Git操作",
    "img":"git.png",
    "default_policy":"2",
    "policy":{
    "2":{
    "period":30,
    "period_display":"1个月",
    "price":60
    },
    "5":{
    "period":1,
    "period_display":"1天",
    "price":0
    },
    "6":{
    "period":90,
    "period_display":"3个月",
    "price":50
    }
    }
    }
    }
    -全局优惠券格式:
    {
    "coupon":{
    "4":{
    "coupon_type":1,
    "coupon_display":"满减券",
    "money_equivalent_value":10,
    "minimum_consume":100
    },
    "5":{
    "coupon_type":0,
    "coupon_display":"立减券",
    "money_equivalent_value":10
    },
    "6":{
    "coupon_type":2,
    "coupon_display":"折扣券",
    "off_percent":80
    }
    },
    "default_coupon":0
    }
    -结算中心逻辑分析:
    -(1)添加到结算中心--post---{"course_list":[{"course_id":"1","policy_id":"1"},{"course_id":"2","policy_id":"2"}]}
    -1 定义结算中心的字典,定义全局优惠券的字典
    payment_dict_userid={}
    global_coupon_dict = {
    "coupon": {},
    "default_coupon": 0
    }
    -2 拿到购物车,循环取出传入的课程id,判断是否在购物车中,不在直接抛异常
    -3 构造单个课程详情的字典,把购物车中的当前课程,update到该字典中
    course_detail={
    'coupon':{}
    }
    course_detail.update(shopping_cart[course_id])
    -4 将该课程详情,加入到结算中心(现在里面没有优惠券相关信息)(为了效率,不在for循环中查询数据库,查出优惠券)
    payment_dict_userid[course_id]=course_detail
    -5 一次性查出当前用户的所有优惠券信息(用户为当前用户,状态为未使用,优惠券起始时间小于当前时间,优惠券结束时间大于当前时间)
    ctime=datetime.datetime.today().strftime('%Y-%m-%d')
    print(ctime)
    coupon_list=models.CouponRecord.objects.filter(
    user=request.user,
    status=0,
    coupon__valid_begin_date__lte=ctime,
    coupon__valid_end_date__gte=ctime,
    )
    -6 循环所有优惠券
    -7 构造出单个优惠券的空字典,拿到优惠券类型(1立减 2 满减 3折扣),拿到优惠券id,拿到该优惠券绑定的课程id(有可能为空)
    coupon_detail = {}
    coupon_type = item.coupon.coupon_type
    coupon_id = item.id
    coupon_course_id = item.coupon.object_id
    -8 构造单个优惠券字典,将数据填充进去,格式如下:
    {
    "7":{"coupon_type":0,"coupon_display":"立减券","money_equivalent_value":10},
    "8":{"coupon_type":1,"coupon_display":"满减券","money_equivalent_value":10,"minimum_consume":100},
    "9":{"coupon_type":2,"coupon_display":"折扣券","off_percent":90}
    }
    coupon_detail['coupon_type'] = coupon_type
    coupon_detail['coupon_display'] = item.coupon.get_coupon_type_display()
    if coupon_type == 0: #立减券,构造出等值金额
    coupon_detail['money_equivalent_value'] = item.coupon.money_equivalent_value
    elif coupon_type == 1:#满减券,构造出等值金额,和最低消费金额
    coupon_detail['money_equivalent_value'] = item.coupon.money_equivalent_value
    coupon_detail['minimum_consume'] = item.coupon.minimum_consume
    else:#其他情况,构造出打折(如打八折,80)
    coupon_detail['off_percent'] = item.coupon.off_percent
    -9 判断是全站优惠券还是课程优惠券
    if not coupon_course_id:#全站优惠券放到全站优惠券字典里
    global_coupon_dict['coupon'][str(coupon_id)]=coupon_detail
    else:
    #其它情况,说明是绑定给课程的优惠券
    coupon_course_id=str(coupon_course_id)
    if coupon_course_id not in payment_dict_userid:#当前课程优惠券对应的可能如果不在结算中心字典里,continue
    continue
    #在结算中心字典中的,对应放入到课程优惠券字段上
    payment_dict_userid[str(coupon_course_id)]['coupon'][coupon_id]=coupon_detail
    payment_dict_userid[str(coupon_course_id)]['default_coupon'] = 0
    -10 讲结算中心字典和全局优惠券字典,放入redis中
    self.conn.set('payment_dict_%s'%request.user.id,json.dumps(payment_dict_userid))
    self.conn.set('global_coupon_dict_%s'%request.user.id,json.dumps(global_coupon_dict))
    -11 返回成功

    -(2)修改结算中心某个课程的优惠券信息---patch--{"course_id":"1","coupon_id":"1"}
    -1 从reids中取出结算中心数据
    -2 先校验coupon_id是否合法,也就是是否在结算中心的优惠券信息中
    if coupon_id not in payment_dict_userid[course_id]['coupon']:
    raise Exception('该优惠不合法')
    -3 合法,直接修改,返回正确信息
    payment_dict_userid[course_id]['default_coupon']=coupon_id
    -(3)获取结算中心数据----get
    -1 从redis中取出本人的结算中心数据 ('payment_dict_%s'%request.user.id))
    -2 从redis中取出本人的全局优惠券数据 ('global_coupon_dict_%s'%request.user.id))
    -3 构造数据返回前台
    res.data={
    'payment':payment_dict_userid,
    'global_coupon_dict':global_coupon_dict
    }


    -去支付:
    -前端传递数据格式:
    {
    "price":600
    "bely":100
    }
    -去支付逻辑:
    -从支付中心拿出字典,全局优惠券字典取出来
    -payment_dic = self.conn.get('payment_dic_%s' % request.user.id)
    -循环结算中心字典,得到课程和课程id
    -for course_id,course_detail in payment_dic.items():
    -取出默认价格策略,取出默认价格,取出默认优惠券id
    default_policy_id=course_detail['default_policy']
    price=course_detail['policy'][str(default_policy_id)]['price']
    default_coupon_id=course_detail['default_coupon']
    -判断如果默认优惠券不为0,表示使用了优惠券:取出默认优惠券的字典,调用计算价格函数得到价格,把价格放到价格列表中(后面直接用sum函数计算总价格)
    if default_coupon_id!=0:
    coupon_dic=course_detail['coupon'][str(default_coupon_id)]
    price= self.account_price(price,coupon_dic)
    price_list.append(price)
    -取出全局默认优惠券id,根据默认优惠券id取出全局优惠券字典,调用计算价格函数得到实际支付价格
    default_coupon_id=global_coupon['default_coupon']
    global_coupon_dic=global_coupon['coupon'][str(default_coupon_id)]
    debate_price=self.account_price(sum(price_list),global_coupon_dic)
    -判断贝利数大于传入的贝利数,用实际价格减去贝利数,如果得到结果小于0,直接等于0,判断最终价格和传如的价格是否相等,不相等抛异常
    if bely>request.user.bely:
    raise MyException('贝利数不合法')
    final_price=debate_price-bely/10
    if final_price<0:
    final_price=0
    if price!=final_price:
    raise MyException('传入的价格有问题')
    -如果实际支付价格大于0,生成支付宝url地址,返回给前端,让前端跳转
    if final_price>0:
    # 拼凑支付宝url
    alipay = ali()
    # 生成支付的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)
    response.url=pay_url
    -计算价格方法:
    #传入价格和优惠券字典
    def account_price(self,price,coupon_dic):
    #设置总价格为price
    total_price=price
    #取出优惠券类型
    coupon_type=coupon_dic['coupon_type']
    #优惠券类型是0,立减
    if coupon_type==0:
    total_price=price-coupon_dic['money_equivalent_value']

    ##优惠券类型是1,满减,必须大于最低消费金额
    elif coupon_type==1:
    if price>=coupon_dic['minimum_consume']:
    total_price=price-coupon_dic['money_equivalent_value']
    else:
    raise MyException('优惠券不满足最低使用金额')
    ##优惠券类型是2,直接打折
    elif coupon_type==2:
    total_price=price*coupon_dic['off_percent']/100

    return total_price

  • 相关阅读:
    Js获取时间,当前,一周前,一月前的时间,时间戳转换,时间格式化,日期格式化
    echarts图随窗口大小的变化而变化
    Vue中使用Google地图插件
    element el-progress渐变色进度条
    Vue中使用mixins
    CSS3 使用 calc() 计算高度 vh px
    element-ui饿了么框架中导航菜单中箭头方向问题
    Vue中使用QRcode.js生成二维码---qrcodejs2
    鼠标经过时显示样式的两种方法
    element 按钮样式:确认按钮发布后样式发生改变
  • 原文地址:https://www.cnblogs.com/zhouhai007/p/10486309.html
Copyright © 2020-2023  润新知