2018-11-15 17:43:50
还有一点路飞项目就结束啦!
周日打算回去!
双十一的耳机到啦,音质确实不错!2333!
等着项目做完,完整总结一下!
越努力,越幸运!永远不要高估自己!!!!
贴上源码!
今天老师实现了结算中心 显示课程,修改优惠券和其他的东西
整体逻辑不难,思路清晰,易于理解
payment.py
from rest_framework.views import APIView from rest_framework.response import Response from app01.utils.auth import LuffyAuth from django.conf import settings from django_redis import get_redis_connection import json from app01.utils.response import BaseResponse from app01 import models import datetime class PaymentViewSet(APIView): authentication_classes = [LuffyAuth, ] conn = get_redis_connection("default") def post(self, request, *args, **kwargs): """ 获取用户要结算的课程和优惠券 :param request: :param args: :param kwargs: :return: """ ret = BaseResponse() try: # 清空当前用户结算中心的数据 # luffy_payment_1_* # luffy_payment_coupon_1 key_list = self.conn.keys(settings.PAYMENT_KEY % (request.auth.user_id, "*",)) key_list.append(settings.PAYMENT_COUPON_KEY % (request.auth.user_id,)) self.conn.delete(*key_list) payment_dict = {} global_coupon_dict = { "coupon": {}, "default_coupon": 0 } # 1. 获取用户要结算课程ID course_id_list = request.data.get('courseids') for course_id in course_id_list: car_key = settings.SHOPPING_CAR_KEY % (request.auth.user_id, course_id,) # 1.1 检测用户要结算的课程是否已经加入购物车 if not self.conn.exists(car_key): ret.code = 1001 ret.error = "课程需要先加入购物车才能结算" # 1.2 从购物车中获取信息,放入到结算中心。 # 获取标题和图片 policy = json.loads(self.conn.hget(car_key, 'policy').decode('utf-8')) default_policy = self.conn.hget(car_key, 'default_policy').decode('utf-8') policy_info = policy[default_policy] payment_course_dict = { "course_id": str(course_id), "title": self.conn.hget(car_key, 'title').decode('utf-8'), "img": self.conn.hget(car_key, 'img').decode('utf-8'), "policy_id": default_policy, "coupon": {}, "default_coupon": 0 } payment_course_dict.update(policy_info) payment_dict[str(course_id)] = payment_course_dict # 2. 获取优惠券 ctime = datetime.date.today() coupon_list = models.CouponRecord.objects.filter( account=request.auth.user, status=0, coupon__valid_begin_date__lte=ctime, coupon__valid_end_date__gte=ctime, ) for item in coupon_list: # 只处理绑定课程的优惠券 if not item.coupon.object_id: # 优惠券ID coupon_id = item.id # 优惠券类型:满减、折扣、立减 coupon_type = item.coupon.coupon_type info = {} info['coupon_type'] = coupon_type info['coupon_display'] = item.coupon.get_coupon_type_display() if coupon_type == 0: # 立减 info['money_equivalent_value'] = item.coupon.money_equivalent_value elif coupon_type == 1: # 满减券 info['money_equivalent_value'] = item.coupon.money_equivalent_value info['minimum_consume'] = item.coupon.minimum_consume else: # 折扣 info['off_percent'] = item.coupon.off_percent global_coupon_dict['coupon'][coupon_id] = info continue # 优惠券绑定课程的ID coupon_course_id = str(item.coupon.object_id) # 优惠券ID coupon_id = item.id # 优惠券类型:满减、折扣、立减 coupon_type = item.coupon.coupon_type info = {} info['coupon_type'] = coupon_type info['coupon_display'] = item.coupon.get_coupon_type_display() if coupon_type == 0: # 立减 info['money_equivalent_value'] = item.coupon.money_equivalent_value elif coupon_type == 1: # 满减券 info['money_equivalent_value'] = item.coupon.money_equivalent_value info['minimum_consume'] = item.coupon.minimum_consume else: # 折扣 info['off_percent'] = item.coupon.off_percent if coupon_course_id not in payment_dict: # 获取到优惠券,但是没有购买此课程 continue # 将优惠券设置到指定的课程字典中 payment_dict[coupon_course_id]['coupon'][coupon_id] = info # 可以获取绑定的优惠券 # 3. 将绑定优惠券课程+全站优惠券 写入到redis中(结算中心)。 # 3.1 绑定优惠券课程放入redis for cid, cinfo in payment_dict.items(): pay_key = settings.PAYMENT_KEY % (request.auth.user_id, cid,) cinfo['coupon'] = json.dumps(cinfo['coupon']) self.conn.hmset(pay_key, cinfo) # 3.2 将全站优惠券写入redis gcoupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id,) global_coupon_dict['coupon'] = json.dumps(global_coupon_dict['coupon']) self.conn.hmset(gcoupon_key, global_coupon_dict) except Exception as e: pass return Response(ret.dict) def patch(self, request, *args, **kwargs): """ 修改优惠券 :param request: :param args: :param kwargs: :return: """ ret = BaseResponse() try: # 1. 用户提交要修改的优惠券 course = request.data.get('courseid') course_id = str(course) if course else course coupon_id = str(request.data.get('couponid')) # payment_global_coupon_1 redis_global_coupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id,) # 修改全站优惠券 if not course_id: if coupon_id == "0": # 不使用优惠券,请求数据:{"couponid":0} self.conn.hset(redis_global_coupon_key, 'default_coupon', coupon_id) ret.data = "修改成功" return Response(ret.dict) # 使用优惠券,请求数据:{"couponid":2} coupon_dict = json.loads(self.conn.hget(redis_global_coupon_key, 'coupon').decode('utf-8')) # 判断用户选择得优惠券是否合法 if coupon_id not in coupon_dict: ret.code = 1001 ret.error = "全站优惠券不存在" return Response(ret.dict) # 选择的优惠券合法 self.conn.hset(redis_global_coupon_key, 'default_coupon', coupon_id) ret.data = "修改成功" return Response(ret.dict) # 修改课程优惠券 # luffy_payment_1_1 redis_payment_key = settings.PAYMENT_KEY % (request.auth.user_id, course_id,) # 不使用优惠券 if coupon_id == "0": self.conn.hset(redis_payment_key, 'default_coupon', coupon_id) ret.data = "修改成功" return Response(ret.dict) # 使用优惠券 coupon_dict = json.loads(self.conn.hget(redis_payment_key, 'coupon').decode('utf-8')) if coupon_id not in coupon_dict: ret.code = 1010 ret.error = "课程优惠券不存在" return Response(ret.dict) self.conn.hset(redis_payment_key, 'default_coupon', coupon_id) except Exception as e: ret.code = 1111 ret.error = "修改失败" return Response(ret.dict) def get(self, request, *args, **kwargs): """ 结算中心展示页面(用户访问) :param request: :param args: :param kwargs: :return: """ ret = BaseResponse() try: # luffy_payment_1_* redis_payment_key = settings.PAYMENT_KEY % (request.auth.user_id, "*",) # luffy_payment_coupon_1 redis_global_coupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id,) # 1. 获取绑定课程信息 course_list = [] for key in self.conn.scan_iter(redis_payment_key): info = {} data = self.conn.hgetall(key) for k, v in data.items(): kk = k.decode('utf-8') if kk == "coupon": info[kk] = json.loads(v.decode('utf-8')) else: info[kk] = v.decode('utf-8') course_list.append(info) # 2.全站优惠券 global_coupon_dict = { 'coupon': json.loads(self.conn.hget(redis_global_coupon_key, 'coupon').decode('utf-8')), 'default_coupon': self.conn.hget(redis_global_coupon_key, 'default_coupon').decode('utf-8') } ret.data = { "course_list": course_list, "global_coupon_dict": global_coupon_dict } except Exception as e: ret.code = 1001 ret.error = "获取失败" return Response(ret.dict)
放上笔记
s9day113 内容回顾: 1. 路飞学城的购物车如何实现? 2. 商品是否有个数? - 价格策略(用事件来类比个数) - 购买之后就开始计时 3. 购物车在redis的结构? 4. 购物车购买数量有限制吗? .keys('xxxxx') 5. 购物车是否设置超时时间? .conn.expire("shopping_car_1_1" ,60*30) 方案:购买课程个数限制(200个) 6. 为什么把购物车信息放入redis? - 临时状态 - 频繁修改的话,速度快。 7. 具体购物车的逻辑? 添加: 1. 用户选择:课程、价格策略,提交 2. 获取课程、价格策略进行合法性校验(数据库查询) 3. 数据获取,构造结构: { shopping_car_用户ID_课程ID:{ title:"...", img:'xxx', policy:{ ... } } } 4. 将数据以字典的形式保存到redis中。 修改: 1. 用户选择:课程、价格策略,提交 2. 获取课程、价格策略进行合法性校验(redis查询) 3. 更新价格策略 删除: 1. 用户选择:课程提交 2. 获取课程合法性校验(redis查询) 3. 删除 查看: 1. 构造Key shopping_car_用户ID_* 2. scan_iter 8. 原则: - 简答逻辑先处理 - try - 细粒度异常+自定义异常 - 导入模块 - 内置 - 框架 - 自定义 - 注释 - 文件 - 类 - 函数 - 文件名、类、函数、project - 对功能进行分类 - 减少代码层级 - BaseResponse 今日内容: - 结算中心 - 去支付 内容详细: 1. 结算中心 a. 添加到结算中心: 请求:POST 数据: { courseids:[1,2] } Q补充: con = { "id":1, "age__gt":9, "name__lt": 8 "name__lt": 8 } # 构造AND models.User.objects.filter(**con) # 构造复杂(条件写死) con = Q(Q(account=request.auth.user) & Q(status=0)) | Q(coupon__valid_begin_date__lte=ctime) models.User.objects.filter(con) # 构造负责(条件动态) q1 = Q() q1.connector = 'OR' for k,v in con.items(): q1.children.append((k,v,)) models.User.objects.filter(q1) 结算数据及目标: payment_dict = { '2': { course_id:2, 'title': 'CRM客户关系管理系统实战开发-专题', 'img': 'CRM.jpg', 'policy_id': '4', 'coupon': {}, 'default_coupon': 0, 'period': 210, 'period_display': '12个月', 'price': 122.0}, '1': { course_id:2, 'title': '爬虫开发-专题', 'img': '爬虫开发-专题.jpg', 'policy_id': '2', 'coupon': { 4: {'coupon_type': 0, 'coupon_display': '立减券', 'money_equivalent_value': 40}, 6: {'coupon_type': 1, 'coupon_display': '满减券', 'money_equivalent_value': 60, 'minimum_consume': 100} }, 'default_coupon': 0, 'period': 60, 'period_display': '2个月', 'price': 599.0} } global_coupon_dict = { 'coupon': { 2: {'coupon_type': 1, 'coupon_display': '满减券', 'money_equivalent_value': 200, 'minimum_consume': 500} }, 'default_coupon': 0 } ========================================= redis ============================================== redis = { payment_1_2:{ course_id:2, 'title': 'CRM客户关系管理系统实战开发-专题', 'img': 'CRM.jpg', 'policy_id': '4', 'coupon': {}, 'default_coupon': 0, 'period': 210, 'period_display': '12个月', 'price': 122.0}, }, payment_1_1:{ course_id:1, 'title': '爬虫开发-专题', 'img': '爬虫开发-专题.jpg', 'policy_id': '2', 'coupon': { 4: {'coupon_type': 0, 'coupon_display': '立减券', 'money_equivalent_value': 40}, 6: {'coupon_type': 1, 'coupon_display': '满减券', 'money_equivalent_value': 60, 'minimum_consume': 100} }, 'default_coupon': 0, 'period': 60, 'period_display': '2个月', 'price': 599.0} }, payment_global_coupon_1:{ 'coupon': { 2: {'coupon_type': 1, 'coupon_display': '满减券', 'money_equivalent_value': 200, 'minimum_consume': 500} }, 'default_coupon': 0 } }