zoukankan      html  css  js  c++  java
  • 路飞学城项目之加入结算中心接口

    路飞学城项目之加入结算中心接口

    功能介绍

    将加入到购物车的课程放到结算中心,结算时根据优惠券的情况进行金额的更改。

    要完成的操作有:

    1. 加入到结算中心
      应注意的是当修改课程的时候需要进行清空操作
    2. 选择优惠券
      优惠券分为两种:
      1. 全站通用的优惠券
      2. 绑定某个课程的优惠券
    3. 修改优惠券
      允许选择不同的优惠券组合
    4. 获取所有优惠券

    需要的数据表结构

    优惠券表

    将优惠券分成了立减券、满减券、折扣券三类。

    三种优惠券的使用场合有所不同,应该注意如何通过一张表的几个字段实现这三种优惠券,主要在于几个字段 (money_equivalent_value, minimum_consume, off_percent) 的填写情况。

    要有与课程绑定的字段。

    注意要有代表有效期的字段,比如有效期限或者有效日期。

    class Coupon(models.Model):
        """优惠券生成规则"""
        name = models.CharField(max_length=64, verbose_name="活动名称")
        brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
        coupon_type_choices = ((0, '立减券'), (1, '满减券'), (2, '折扣券'))
        coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
    
        """
        通用:
            money_equivalent_value=100
            off_percent=null
            minimum_consume=0
        满减:
            money_equivalent_value=100
            off_percent=null
            minimum_consume=1000
        折扣:
            money_equivalent_value=0
            off_percent=79
            minimum_consume=0
        """
        money_equivalent_value = models.IntegerField(verbose_name="等值货币")
        off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
        minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
    
        content_type = models.ForeignKey(ContentType, blank=True, null=True)
        object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
        content_object = GenericForeignKey('content_type', 'object_id')
    
        quantity = models.PositiveIntegerField("数量(张)", default=1)
        open_date = models.DateField("优惠券领取开始时间")
        close_date = models.DateField("优惠券领取结束时间")
        valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
        valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
        coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
                                                        help_text="自券被领时开始算起")
        date = models.DateTimeField(auto_now_add=True)
    
        class Meta:
            verbose_name_plural = "31. 优惠券生成记录"
    
        def __str__(self):
            return "%s(%s)" % (self.get_coupon_type_display(), self.name)
    
        def save(self, *args, **kwargs):
            if not self.coupon_valid_days or (self.valid_begin_date and self.valid_end_date):
                if self.valid_begin_date and self.valid_end_date:
                    if self.valid_end_date <= self.valid_begin_date:
                        raise ValueError("valid_end_date 有效期结束日期必须晚于 valid_begin_date ")
                if self.coupon_valid_days == 0:
                    raise ValueError("coupon_valid_days 有效期不能为0")
            if self.close_date < self.open_date:
                raise ValueError("close_date 优惠券领取结束时间必须晚于 open_date优惠券领取开始时间 ")
    
            super(Coupon, self).save(*args, **kwargs)
    
    

    优惠券发放记录表

    存放着优惠券的发放记录和消费记录,以及使用状态,需要和用户进行绑定。

    class CouponRecord(models.Model):
        """优惠券发放、消费纪录"""
        coupon = models.ForeignKey("Coupon")
        number = models.CharField(max_length=64, unique=True)
        account = models.ForeignKey("UserInfo", verbose_name="拥有者")
        status_choices = ((0, '未使用'), (1, '已使用'), (2, '已过期'))
        status = models.SmallIntegerField(choices=status_choices, default=0)
        get_time = models.DateTimeField(verbose_name="领取时间", help_text="用户领取时间")
        used_time = models.DateTimeField(blank=True, null=True, verbose_name="使用时间")
        # order = models.ForeignKey("Order", blank=True, null=True, verbose_name="关联订单")  # 一个订单可以有多个优惠券
    
        class Meta:
            verbose_name_plural = "32. 用户优惠券"
    
        def __str__(self):
            return '%s-%s-%s' % (self.account, self.number, self.status)
    
    
    

    接口逻辑处理

    前期准备工作

    1. settings.py 中

    与购物车处理类似,要放入 redis ,先在此处设置好对应的关键字。

    结算关键字的设置,形式应该为 luffy_payment_用户ID_课程ID

    # 结算关键字的设置
    PAYMENT_KEY = "luffy_payment_%s_%s"
    

    全站通用优惠券关键字的设置,形式为 luffy_payment_coupon_用户ID

    # 全站通用优惠券关键字的设置
    PAYMENT_COUPON_KEY = "luffy_payment_coupon_%s"
    
    1. urls.py 中

    添加相应的路由。

    from api.views import payment
    
    urlpatterns = [
        ...
        url(r'^payment/$', payment.PaymentViewSet.as_view()),
    
    ]
    
    1. views/payment.py 中

    所用到的包

    import json
    import datetime
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.conf import settings
    from django_redis import get_redis_connection
    from utils.response import BaseResponse
    from api.auth.auth import LufyyAuth
    from api import models
    

    视图类 PaymentViewSet ,里面要有认证类和链接到 redis 的句柄。

    authentication_classes = [LufyyAuth, ]
    conn = get_redis_connection("default")
    

    加入到结算中心

    清空结算中心并初始化信息字典

    加入到结算中心时并不见得结算中心就是空的,如果结算中心本来就有课程待结算,采取的措施并不是修改,而是清空后再重新添加。

    清空结算中心就是将 redis 中的相应键值删除即可。这里说明两种删除多个键值的方法。

    1. scan_iter 循环删除

    使用 scan_iter 函数循环得到里面的键值,依次删除。

    for key in conn.scan_iter("luffy_shopping_car_6_*"):
        conn.delete(key)
    
    1. *[] 一次性删除

    通过 keys 函数获取包函所有键值的列表,并直接以 *[] 的形式删除,这种方式在键值比较多情况下不建议使用

    key_list = conn.keys("luffy_shopping_car_6_*")
    conn.delete(*key_list)
    

    这里我们使用的是第二种方式,要删除的键包括结算键和全局优惠券键。

    # 清空当前用户结算中心的数据
    # 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
    }
    
    

    获取用户要结算的课程信息

    获取用户要结算课程 ID ,先判断是否已经加入到购物车,没有加入购物车要报错。从购物车中获取课程信息放入结算中心,数据结构形式是以课程 ID 为键,课程信息为值的字典。而课程信息也是键值对。

    # 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 = {
    		"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
    

    获取优惠券信息

    1. 从数据库中获取可用的优惠券

    这里,可用包含了未使用和在有效期范围内,相当于数据库的条件查询,这里直接用了 filter 函数中的各种信息赋值的形式(都是且关系)。

    coupon_list = models.CouponRecord.objects.filter(
    	account = request.auth.user,
    	status = 0,
    	coupon__valid_begin_date__lte = ctime,
    	coupon__valid_end_date__gte = ctime,
    )
    

    补充:条件查询 (Q函数)
    (1) 构造 AND

    con = {
    	"id":1,
    	"age__gt":9,
    	"name__lt": 8
    	"name__lt": 8
    }
    
    # 构造AND
    models.User.objects.filter(**con)
    

    (2) 构造复杂(条件写死)

    # 构造复杂(条件写死)
    con = Q(Q(account=request.auth.user) & Q(status=0)) | Q(coupon__valid_begin_date__lte=ctime)
    models.User.objects.filter(con)
    

    (3)构造复杂(条件动态)

    以键值对的方式给出查询条件

    # 构造复杂(条件动态)
    q1 = Q()
    q1.connector = 'OR'
    for k,v in con.items():
    	q1.children.append((k,v,))
    models.User.objects.filter(q1)
    
    1. 将优惠券信息放到课程字典中

    优惠券从种类上分为了满减、折扣、立减三种类型。从性质上分为了全站通用优惠券和绑定课程的优惠券。

    (1) 全站通用优惠券

    获取优惠券的各种信息后放到 global_coupon_dict 字典中。

    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
    

    (2) 绑定课程优惠券

    绑定课程的优惠券除了与上面通用优惠券都需要获取优惠券信息之外,还需要判断是否购买该课程。并且,直接放入到了结算字典中的指定课程信息字典去。

    for item in coupon_list:
    
    	# 优惠券绑定课程的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
    
    

    全部优惠券信息写入到 redis 中

    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)
    
    1. 将全站优惠券信息写入 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)
    

    这部分的完整代码:

    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 = {
    				"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
    		print("************")
    		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)
    			print(cinfo)
    			print(pay_key)
    
    		# 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)
    		print(gcoupon_key)
    		print(global_coupon_dict)
    
    	except Exception as e:
    		ret.code = 1002
    		ret.error = "获取优惠券失败"
    
    	return Response(ret.dict)
    

    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
    	}
    }
    

    修改优惠券

    1. 获取优惠券 ID

    分为两种,绑定课程的优惠券 ID 和通用优惠券 ID 。

    # 1. 用户提交要修改的优惠券
    course = request.data.get("courseid")
    course_id = str(course) if course else course
    
    coupon_id = str(request.data.get('couponid'))
    
    

    修改也应分成两种情况。

    1. 修改全站通用优惠券

    没有绑定课程 ID 的就是通用优惠券,根据用户发来数据判断是否使用优惠券,使用时判断优惠券是否合法,合法就修改优惠券。修改优惠券就是修改字典中的 default_coupon 字段,它代表着现在选择的优惠券。

    # 拼接成全站优惠券关键字
    redis_global_coupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id)
    
    # 修改全站优惠券 即没有课程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)
    
    	# 合法,修改字典中的default_coupon
    	self.conn.hset(redis_global_coupon_key, "default_coupon", coupon_id)
    	ret.data = "修改成功"
    	return Response(ret.dict)
    
    
    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)
    
    # 修改使用的优惠券 default_coupon
    self.conn.hset(redis_payment_key, "default_coupon", coupon_id)
    
    

    本部分完整代码:

    
    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'))
    
    		# 拼接成全站优惠券关键字
    		redis_global_coupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id)
    
    		# 修改全站优惠券 即没有课程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)
    
    			# 合法,修改字典中的default_coupon
    			self.conn.hset(redis_global_coupon_key, "default_coupon", coupon_id)
    			ret.data = "修改成功"
    			return Response(ret.dict)
    
    		# 修改课程优惠券
    		# 拼接成课程优惠券关键字
    		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)
    
    		# 修改使用的优惠券 default_coupon
    		self.conn.hset(redis_payment_key, "default_coupon", coupon_id)
    
    	except Exception as e:
    		ret.code = 1111
    		ret.data = "修改失败"
    
    	return Response(ret.dict)
    

    获取优惠券信息

    如果已经将优惠券信息放入到了 redis 中,那么就能很方便的获取到这心信息。

    同样需要分成通用优惠券和绑定课程的优惠券。

    完整代码:

    
    def get(self, request, *args, **kwargs):
    	ret = BaseResponse()
    
    	try:
    		# 课程优惠券关键字 luffy_payment_1_*
    		redis_payment_key = settings.PAYMENT_KEY % (request.auth.user_id, "*")
    		# 全站优惠券关键字
    		redis_global_coupon_key = settings.PAYMENT_COUPON_KEY % (request.auth.user_id, )
    
    		# 1. 获取绑定课程的信息
    		course_coupon_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_coupon_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_coupon_list": course_coupon_list,
    			"global_coupon_dict": global_coupon_dict
    		}
    
    
    	except Exception as e:
    		ret.code = 1001
    		ret.error = "获取失败"
    
    	return Response(ret.dict)
    

    此时,我们就能通过返回的数据看到整个优惠券信息的数据结构模样了:

    {
        "data": {
            "course_coupon_list": [
                {
                    "default_coupon": "1",
                    "title": "Python全栈",
                    "img": "fasdf.png",
                    "price": "399.0",
                    "coupon": {
                        "1": {
                            "coupon_type": 0,
                            "coupon_display": "立减券",
                            "money_equivalent_value": 50
                        }
                    },
                    "policy_id": "3",
                    "period": "30",
                    "period_display": "1个月"
                },
                {
                    "default_coupon": "0",
                    "title": "金融量化分析",
                    "img": "fds.png",
                    "price": "266.0",
                    "coupon": {
                        "2": {
                            "coupon_type": 1,
                            "coupon_display": "满减券",
                            "money_equivalent_value": 50,
                            "minimum_consume": 100
                        }
                    },
                    "policy_id": "7",
                    "period": "30",
                    "period_display": "1个月"
                }
            ],
            "global_coupon_dict": {
                "coupon": {
                    "3": {
                        "coupon_type": 2,
                        "coupon_display": "折扣券",
                        "off_percent": 79
                    }
                },
                "default_coupon": "0"
            }
        },
        "code": 1000,
        "error": null
    }
    

    其他

    提到的程序设计原则:

    • 简答逻辑先处理
      • 处理后直接 return
      • 处理后直接 continue
    • try
    • 细粒度异常+自定义异常
    • 导入模块
      • 内置
      • 框架
      • 自定义
    • 注释
      • 文件
      • 函数
    • 命名:文件名、类、函数、project
    • 对功能进行分类
    • 减少代码层级

    GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/s9day113/s9luffycity

    路飞学城项目之加入结算中心接口

  • 相关阅读:
    集合的遍历和扩容原理
    最新鲜最详细的Android SDK下载安装及配置教程
    开启IIS Express可以调试X64项目
    C# 正则表达式大全
    Windows下SQLMAP的安装图解
    当前比较流行的前端框架2
    前端组件库1
    服务器Windows 登录 出现401 错误
    IPV6配置
    implicit和 explicit关键字
  • 原文地址:https://www.cnblogs.com/banshaohuan/p/10222625.html
Copyright © 2011-2022 走看看