关于优惠券

优惠券主要通过前端传回来的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) 优惠券的更多相关文章

  1. lf 前后端分离 (2) 课程数据获取,Serializer的返回

    一.关于课程数据的返回 在进行前后端分离时,会通过def 进行前后端传值, 本质上遵循rest 网址规范  增删改查查 get,post,put,del get(\d+) 1.在从数据库获取数据后,进 ...

  2. lf 前后端分离 (6) 支付

    支付 import datetime from django.core.exceptions import ObjectDoesNotExist from rest_framework.views i ...

  3. lf 前后端分离 (1) auth,token认证

    一.关于登录验证 用户在登录的时候会通过验证以及滑动解锁,注意的是需要后端if verify(request.data): 来判断是否发送了那三个验证数据 通过 random_str=str(uuid ...

  4. lf 前后端分离 (4) 价格策略

    一.价格策略 价格策略就是通过前端发送要购买的课程以及价格策略来找出表关联的字段返回客户端 通过contenttype 属性 找到课程所有的价格策略 for prcie_policy in cours ...

  5. lf 前后端分离 (3) 中间建跨域

    一.关于中间建跨域 为了减少跨域代码冗余,采用中间件 from django.utils.deprecation import MiddlewareMixin class CorsMiddleware ...

  6. 前后端分离跨服务器文件上传-Java SpringMVC版

    近来工作上不上特别忙,加上对后台java了解一点,所以就抽时间,写了一个java版本的前后端分离的跨服务器文件上传功能,包括前后端代码. 一.Tomcat服务器部分 1.Tomcat服务器 单独复制一 ...

  7. 前后端分离ueditor富文本编辑器的使用-Java版本

    最近在写一个自己的后台管理系统(主要是写着玩的,用来熟悉后端java的知识,目前只是会简单的写点接口),想在项目中编写一个发布新闻文章的功能,想到了使用百度的ueditor富文本编辑器,网上找了很多j ...

  8. 前后端分离中,Gulp实现头尾等公共页面的复用

    前言 通常我们所做的一些页面,我们可以从设计图里面看出有一些地方是相同的.例如:头部,底部,侧边栏等等.如果前后端分离时,制作静态页面的同学,对于这些重复的部分只能够通过复制粘贴到新的页面来,如果页面 ...

  9. nodeJS(express4.x)+vue(vue-cli)构建前后端分离详细教程(带跨域)

    好想再回到大学宿舍,当时床虽小,房随小,但是心确是满的 ----致  西安工程大学a-114舍友们 转载请注明出处:水车:http://www.cnblogs.com/xuange306/p/6185 ...

随机推荐

  1. Python常用数据类型简介

    1.变量的三个基本特征 1,大印 2,判断变量值是否相等 3,判断变量id是否相等 2.常用数据类型分类 数字类型(int) 字符串类型(str) 列表类型(list) 字典类型(dict(dicti ...

  2. (转)新建maven项目时报错Error:Maven Resources Compiler: Maven project configuration required for module 'XX'解决方法

    转载地址:https://blog.csdn.net/qq784515681/article/details/85070195 在新建maven项目时,Problems中报错: Error:Maven ...

  3. ESP8266 AT指令开发(基于STC89C52单片机): 测试下诱人的程序(51单片机,8266,MQTT远程通信控制)

    前言 实现的功能,APP通过SmartConfig给Wi-Fi模块配网并绑定设备,然后通过MQTT远程控制开发板的继电器, 简而言之: 51单片机+ESP8266用AT指令实现实现MQTT,(连接的本 ...

  4. Paper | Non-Local ConvLSTM for Video Compression Artifact Reduction

    目录 1. 方法 1.1 框图 1.2 NL流程 1.3 加速版NL 2. 实验 3. 总结 [这是MFQE 2.0的第一篇引用,也是博主学术生涯的第一篇引用.最重要的是,这篇文章确实抓住了MFQE方 ...

  5. Office Online Server 在线编辑Office文档,安装部署

    Office Online Server部署安装 部署环境 一台windows server2012 (搭建域环境)/多次遇坑之后,强烈建议域环境为server2012 一台windows serve ...

  6. golang基础之初识

    golang 简介 很久以前,有一个IT公司,这公司有个传统,允许员工拥有20%自由时间来开发实验性项目.在2007的某一天,公司的几个大牛,正在用c++开发一些比较繁琐但是核心的工作,主要包括庞大的 ...

  7. linux安装redis步骤

    1.安装gcc  redis是c语言编写的 -- 安装命令 yum install gcc-c++ -- 检查gcc 是否安装 gcc -v 2.下载redis安装包,在root目录下执行 wget ...

  8. .net core linux环境下 System.Data.SqlClient.SqlException: Connection Timeout Expired.

    最近遇到了一个很奇葩的问题,我编写了一个.net core程序读取多个数据库数据源,进行数据同步处理.该程序在windows环境下运行完全正常,但在linux环境下运行报异常,提示 System.Da ...

  9. duba网址对firefox快捷方式的劫持

    直接删除 “驱动精灵” 即可. 等我 二进制安全 学好了,一定开发一种病毒专干这种劫持的,煞笔软件.

  10. OpenGL入门1.3:着色器 GLSL

    前言 经过之前一段时间的学习(渲染管线简介)我们已经知道了着色器(Shader)是运行在GPU上的程序,这些小程序为图形渲染管线的某个特定部分而运行,着色器只是一种把输入转化为输出的程序,着色器也是一 ...