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 == "":
# 不使用优惠券,请求数据:{"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 == "":
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 = {
'': {
course_id:2,
'title': 'CRM客户关系管理系统实战开发-专题',
'img': 'CRM.jpg', 'policy_id': '',
'coupon': {},
'default_coupon': 0,
'period': 210, 'period_display': '12个月', 'price': 122.0},
'': {
course_id:2,
'title': '爬虫开发-专题',
'img': '爬虫开发-专题.jpg',
'policy_id': '',
'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': '',
'coupon': {},
'default_coupon': 0,
'period': 210, 'period_display': '12个月', 'price': 122.0},
},
payment_1_1:{
course_id:1,
'title': '爬虫开发-专题',
'img': '爬虫开发-专题.jpg',
'policy_id': '',
'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
}
}