lf 前后端分离 (5) 优惠券
关于优惠券
优惠券主要通过前端传回来的course_id_list 创建数据结构
首先清空操作,将所有的优惠券清空,
并将所有优惠劵放到redis中的过程
import datetime
import json
import redis REDIS_CONN = redis.Redis(decode_responses=True) from rest_framework.views import APIView
from rest_framework.response import Response from app01.models import *
from app01.utils.auth import LoginAuth
from app01.utils.response import BaseResponse
from app01.utils.exception import CommonException from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings class AccountView(APIView):
authentication_classes = [LoginAuth] def get_coupon_dict(self, request, course_id=None):
now = datetime.datetime.now()
coupon_record_list = CouponRecord.objects.filter(
account=request.user,
coupon__content_type=9,
coupon__object_id=course_id,
status=0,
coupon__valid_begin_date__lte=now,
coupon__valid_end_date__gte=now
)
coupons = {} for coupon_record in coupon_record_list:
coupons[coupon_record.pk] = { "pk": coupon_record.pk,
"name": coupon_record.coupon.name,
"coupon_type": coupon_record.coupon.get_coupon_type_display(),
"money_equivalent_value": coupon_record.coupon.money_equivalent_value,
"off_percent": coupon_record.coupon.off_percent,
"minimum_consume": coupon_record.coupon.minimum_consume,
"valid_begin_date": coupon_record.coupon.valid_begin_date.strftime("%Y-%m-%d"),
"valid_end_date": coupon_record.coupon.valid_end_date.strftime("%Y-%m-%d"),
}
print("coupons", coupons) return coupons def post(self, request, *args, **kwargs):
# 1 获取数据
user = request.user
course_id_list = request.data.get("course_id_list")
response = BaseResponse()
try:
# 2 创建数据结构
# 清空操作
# 找到所有以account_userid_*,全部清空
del_list = REDIS_CONN.keys(settings.ACCOUNT_KEY % (user.pk, "*"))
if del_list:
REDIS_CONN.delete(*del_list) price_list = []
for course_id in course_id_list: account_key = settings.ACCOUNT_KEY % (user.pk, course_id)
account_dict = {}
shopping_car_key = settings.SHOPPING_CAR_KEY % (user.pk, course_id) # 判断课程是否存在购物车中
if not REDIS_CONN.exists(shopping_car_key):
raise CommonException("购物车不存在该课程", 1040) # 将课程信息加入到每一个课程结算字典中
course_info = json.loads(REDIS_CONN.get(shopping_car_key))
account_dict["course_info"] = course_info # 课程价格加入到价格列表
price_list.append(float(course_info["default_price"])) # 查询当前用户拥有未使用的,在有效期的且与当前课程相关的优惠券
account_dict["course_coupons"] = self.get_coupon_dict(request, course_id) # 存储结算信息
REDIS_CONN.set(account_key, json.dumps(account_dict)) print("account_dict",account_dict) # 获取通用优惠券,加入redis中 REDIS_CONN.set("global_coupon_%s" % user.pk, json.dumps(self.get_coupon_dict(request)))
REDIS_CONN.set("total_price", sum(price_list)) except CommonException as e:
response.code = e.code
response.msg = e.msg except ObjectDoesNotExist as e:
response.code = 1001
response.msg = "课程不存下" return Response(response.dict) def get(self, request, *args, **kwargs): res = BaseResponse()
try:
# 1 取到user_id
user_id = request.user.id
# 2 拼接购物车的key
account_key = settings.ACCOUNT_KEY % (user_id, "*")
# shopping_car_1_*
# shopping_car_1_asdgnlaksdj
# 3 去redis读取该用户的所有加入购物车的课程
# 3.1 先去模糊匹配出所有符合要求的key
all_keys = REDIS_CONN.scan_iter(account_key) # 3.2 循环所有的keys 得到每个可以
account_course_list = []
for key in all_keys: course = json.loads(REDIS_CONN.get(key))
temp = {}
for key, val in course["course_info"].items():
temp[key] = val
coupon_list = []
for key, val in course["course_coupons"].items():
val["pk"] = key
coupon_list.append(val)
temp["coupon_list"] = coupon_list account_course_list.append(temp) global_coupons_dict = json.loads(REDIS_CONN.get("global_coupon_%s" % request.user.pk))
total_price = REDIS_CONN.get("total_price")
global_coupons = []
for key, val in global_coupons_dict.items():
global_coupons.append(val)
res.data = {
"account_course_list": account_course_list,
"total": len(account_course_list),
"global_coupons": global_coupons,
"total_price": total_price
} except Exception as e:
res.code = 1033
res.error = "获取购物车失败" return Response(res.dict) def cal_coupon_price(self,price,coupon_info): coupon_type=coupon_info["coupon_type"]
money_equivalent_value=coupon_info.get("money_equivalent_value")
off_percent=coupon_info.get("off_percent")
minimum_consume=coupon_info.get("minimum_consume")
rebate_price=0
if coupon_type == "立减券": # 立减券
rebate_price=price-money_equivalent_value
if rebate_price <= 0:
rebate_price=0
elif coupon_type == "满减券": # 满减券
if minimum_consume > price:
raise CommonException(3000,"优惠券未达到最低消费")
else:
rebate_price=price-money_equivalent_value
elif coupon_type == "折扣券":
print("VVVV",price,off_percent)
rebate_price=price*off_percent/100 return rebate_price def put(self,request, *args, **kwargs):
'''
choose_coupons:
{
choose_coupons={"1":"2","2":"3","global_coupon_id":5}
is_beli:true
}
'''
res=BaseResponse()
try: # 1 获取数据
choose_coupons=request.data.get("choose_coupons")
is_beli=request.data.get("is_beli")
user_pk=request.user.pk # 2 获取结算课程列表
cal_price={}
data=self.get(request).data.get("data")
account_course_list=data.get("account_course_list")
account_course_info={}
for account_course in account_course_list:
temp={
"coupons":{},
"default_price":account_course["default_price"]
}
account_course_info[account_course["id"]]=temp for item in account_course["coupon_list"]:
temp["coupons"][item["pk"]]=item print("account_course_info",account_course_info) price_list=[]
total_price=0
for key,val in account_course_info.items():
if str(key) not in choose_coupons:
price_list.append(val["default_price"])
cal_price[key]=val["default_price"]
else:
coupon_info=val.get("coupons").get(str(choose_coupons[str(key)]))
rebate_price=self.cal_coupon_price(val["default_price"],coupon_info)
price_list.append(rebate_price)
cal_price[key]=rebate_price print("课程优惠券后价格列表price_list",price_list)
total_price=sum(price_list)
# 3 计算通用优惠券的价格
global_coupon_id=choose_coupons.get("global_coupon_id")
if global_coupon_id: global_coupons=data.get("global_coupons")
print("global_coupons",global_coupons)
global_coupon_dict={}
for item in global_coupons:
global_coupon_dict[item["pk"]]=item total_price=self.cal_coupon_price(total_price,global_coupon_dict[global_coupon_id])
print("通用优惠券",global_coupon_dict[global_coupon_id]["coupon_type"])
print("计算后total_price=",total_price) # 计算贝里
if json.loads(is_beli):
total_price=total_price-request.user.beli/10
if total_price<0:
total_price=0
print("贝里数计算后",total_price) #res.total_price=total_price
cal_price["total_price"]=total_price
res.data=cal_price except Exception as e:
res.code=500
res.msg="结算错误!"+str(e) return Response(res.dict)
优惠券
lf 前后端分离 (5) 优惠券的更多相关文章
- lf 前后端分离 (2) 课程数据获取,Serializer的返回
一.关于课程数据的返回 在进行前后端分离时,会通过def 进行前后端传值, 本质上遵循rest 网址规范 增删改查查 get,post,put,del get(\d+) 1.在从数据库获取数据后,进 ...
- lf 前后端分离 (6) 支付
支付 import datetime from django.core.exceptions import ObjectDoesNotExist from rest_framework.views i ...
- lf 前后端分离 (1) auth,token认证
一.关于登录验证 用户在登录的时候会通过验证以及滑动解锁,注意的是需要后端if verify(request.data): 来判断是否发送了那三个验证数据 通过 random_str=str(uuid ...
- lf 前后端分离 (4) 价格策略
一.价格策略 价格策略就是通过前端发送要购买的课程以及价格策略来找出表关联的字段返回客户端 通过contenttype 属性 找到课程所有的价格策略 for prcie_policy in cours ...
- lf 前后端分离 (3) 中间建跨域
一.关于中间建跨域 为了减少跨域代码冗余,采用中间件 from django.utils.deprecation import MiddlewareMixin class CorsMiddleware ...
- 前后端分离跨服务器文件上传-Java SpringMVC版
近来工作上不上特别忙,加上对后台java了解一点,所以就抽时间,写了一个java版本的前后端分离的跨服务器文件上传功能,包括前后端代码. 一.Tomcat服务器部分 1.Tomcat服务器 单独复制一 ...
- 前后端分离ueditor富文本编辑器的使用-Java版本
最近在写一个自己的后台管理系统(主要是写着玩的,用来熟悉后端java的知识,目前只是会简单的写点接口),想在项目中编写一个发布新闻文章的功能,想到了使用百度的ueditor富文本编辑器,网上找了很多j ...
- 前后端分离中,Gulp实现头尾等公共页面的复用
前言 通常我们所做的一些页面,我们可以从设计图里面看出有一些地方是相同的.例如:头部,底部,侧边栏等等.如果前后端分离时,制作静态页面的同学,对于这些重复的部分只能够通过复制粘贴到新的页面来,如果页面 ...
- nodeJS(express4.x)+vue(vue-cli)构建前后端分离详细教程(带跨域)
好想再回到大学宿舍,当时床虽小,房随小,但是心确是满的 ----致 西安工程大学a-114舍友们 转载请注明出处:水车:http://www.cnblogs.com/xuange306/p/6185 ...
随机推荐
- luoguP2486 [SDOI2011]染色
题目 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段) ...
- 多线程(六)多线程同步_SemaPhore信号量
信号量依然是一种内核同步对象,它的作用在于控制共享资源的最大访问数量 例如:我们有一个服务器,为这服务器创建一个线程池,线程池有五个线程,每个线程处理1个请求.当五个线程都在处理请求时,这个线程池己到 ...
- 数据库连接池 DBUtils:
import pymysqlfrom DBUtils.PooledDB import PooledDB, SharedDBConnectionPOOL = PooledDB ( creator=pym ...
- 《为什么说Redis是单线程的以及Redis为什么这么快!》
为什么说Redis是单线程的以及Redis为什么这么快! 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...
- OpenStack I18N
OpenStack I18N 官方文档: https://docs.openstack.org/oslo.i18n/latest/user/usage.html https://docs.openst ...
- CF-1155 D.Beautiful Array
题目大意:现在有一个数列,还有一个数字x,你可以将这个数列中的一段连续子序列同时乘以这个数字x(当然也可以不乘),然后问你最大子段和是多少 做法:dp,你懂的 #include<iostream ...
- ubuntu 安装rocketmq
RocketMQ环境要求 ) 64bit OS,linux/Unix/Max ) 64bit JDK 1.8+ ) Maven 3.2.x ) Git 一.下载并构建 git clone https: ...
- npm ERR! Cannot read property 'resolve' of undefined
一 .有可能是版本过低,或者软件损坏,重新安装一下试试 地址
- HTML+CSS基础 border css属性 Div块 盒子
border css属性 边框颜色 border-color:red/#ffffff/rgb()默认为黑色 边框样式 border-style:solid (实线) dashed (虚线).默认为n ...
- etcd 开启auth认证
一.概述 1.etcd的v2和v3的认证有些不同,需要分别设置2.Etcd通过用户(user)-角色(role)-权限的方式来控制访问,用户关联角色,角色拥有权限,从而用户也就拥有了相应的权限3.Et ...