一、路飞学城之结算中心
数据格式
# 用户选中的课程以及优惠券
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