def delete(self, request, *args, **kwargs): ''' 删除购物车里面的记录 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() try: courseid_list = request.data.get("courseid") user_id = request.auth.user.id # 获得要删除的name ;如果redis里面没有,不会报错。 name_list = [ settings.SHOPPING_CRA_NAME % (user_id, course_id) for course_id in courseid_list ] # 获取redis连接,并且删除name self.conn.delete(*name_list) except Exception: ret.code = 1002, ret.error = "删除错误" return Response(ret.dict)
def post(self, request, *args, **kwargs): ret = BaseResponse() article_id = request.data.get("article_id") arctile_obj = models.Article.objects.filter(id=article_id).first() tokens = request.data.get("token") account = models.Tokeninfo.objects.filter(tokens=tokens).first().user isUp = request.data.get("isup") # 已经反序列化为true了 # print(isUp) # 事务 原子性操作(要么同时执行,要么都不执行) mysql try: models.ArticleUpDown.objects.create(article=arctile_obj, user=account, is_up=isUp) if isUp: # 表示点赞数 models.Article.objects.filter(pk=article_id).update( agree_num=F("agree_num") + 1) # 否则是踩数加1 # else: # Article.objects.filter(pk=article_id).update(up_count=F("agree_num") + 1) ret.status = True except Exception: # 已经点赞过了 ret.status = False # 如果有点赞或是踩的时候需要判断一下,用户第一次的操作,是点赞还是踩,然后才返回提示(点赞过或是踩过)在这么只有点赞,所以没有补充 ret.msg = "已经点赞过了" return Response(ret.dict)
def post(self, request, *args, **kwargs): # 实例化一个响应的对象. ret = BaseResponse() try: user = Userinfo.objects.filter(**request.data).first() # user = Userinfo.objects.get(**request.data) # if user: # token = str(uuid.uuid4()) # # 没有就创建,有就更新; # Tokeninfo.objects.update_or_create(user=user, defaults={"tokens": token}) # ret["data"]["token"] = token # ret["data"]["nickname"] = user.nickname # else: # ret["code"] = 10001 # ret["erorr"] = "账号或密码错误" # 简单代码往上放. #简洁 if not user: ret.code = 10001 ret.erorr = "账号或密码错误" return Response(ret.dict) token = str(uuid.uuid4()) # 没有就创建,有就更新; Tokeninfo.objects.update_or_create(user=user, defaults={"tokens": token}) ret.data["token"] = token ret.data["nickname"] = user.nickname except Exception as e: # 发生异常,需要捕获异常 ret.code = 10003 ret.erorr = "错误" return Response(ret.dict)
def patch(self, request, *args, **kwargs): ''' 修改结算中心的优惠券 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() try: user_id = request.auth.user_id courseid = request.data.get("courseid", None) couponid = str(request.data.get("coupon")) # couponid为0的话,就表示不想用优惠卷。 if courseid == None: # 全站优惠卷; global_coupon = settings.GLOBAL_COUPON % (user_id) global_coupon_dict = json.loads( self.conn.hget(global_coupon, "coupon").decode("utf-8")) # 要修改的是全站的优惠卷 if couponid not in global_coupon_dict and couponid != "0": ret.code = 1002 ret.error = "全站优惠券不合法" return Response(ret.dict) # 修改全站优惠卷 self.conn.hset(global_coupon, "default_coupon", couponid) ret.data = "修改全站的优惠券成功" return Response(ret.dict) # 修改绑定课程的优惠卷 # 绑定优惠卷 pay_name = settings.PAYMENT_CRA_NAME % (user_id, courseid) coupon_dict = json.loads( self.conn.hget(pay_name, "coupon").decode("utf-8")) # 判断传过来的优惠券是存在。(用户有) if couponid not in coupon_dict and couponid != "0": ret.code = 1003 ret.error = "绑定优惠券不合法" return Response(ret.dict) # 修改绑定的优惠券 self.conn.hset(pay_name, "default_coupon", couponid) ret.data = "修改绑定的优惠卷成功" except Exception: ret.code = 1003 ret.error = "修改优惠卷失败" return Response(ret.dict)
def list(self, request, *args, **kwargs): ''' 课程API :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() try: cobj = models.Course.objects.all() qureyset = CouserSerializers(instance=cobj, many=True) ret.data = qureyset.data except Exception as e: ret.code = 1002 ret.error = e return Response(ret.dict)
def get(self, request, *args, **kwargs): ''' 获得当前用户的购物车里面的所有信息 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() user_id = request.auth.user.id try: redis_name = settings.SHOPPING_CRA_NAME % (user_id, "*") data = [] for item in self.conn.scan_iter(redis_name, count=10): couser = {} _, c_id = item.decode("utf-8").rsplit('_', 1) title = self.conn.hget(item, "title") img = self.conn.hget(item, "img") policy = self.conn.hget(item, "policy") default_policy = self.conn.hget(item, "default_policy") couser[c_id] = { "title": title.decode("utf-8"), "img": img.decode("utf-8"), "policy": json.loads(policy.decode("utf-8")), "default_policy": default_policy.decode( "utf-8"), # bytes ---> json字符串---->dict } # redis缓存里面有数据 # 取到当前用户的购物车里面的所有商品 data.append(couser) ret.data = data # 缓存里面没有就证明为没有添加到购物车里面. # 在redis传输全部用字节 except Exception: ret.code = 1002 ret.error = "查看购物车错误" return Response(ret.dict)
def patch(self, request, *args, **kwargs): ''' 更新价格策略 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() course_id = request.data.get("courseid") user_id = request.auth.user_id policy_id = request.data.get("policyid") try: # 修改的话,课程肯定是存在的,只不过修改的价格可能是非法的。 # 先判断要修改的价格是否合法;也就是从redis里面该课程对应的取 'policy': {...} redis_name = settings.SHOPPING_CRA_NAME % (user_id, course_id) prince_list = self.conn.hget(redis_name, 'policy') prince_dict = json.loads(prince_list.decode('utf-8')) if policy_id not in prince_dict: ret.code = 1004 ret.error = "价格不合法" return Response(ret.dict) # 价格合法的话,就修改default_policy价格 self.conn.hset(redis_name, 'default_policy', policy_id) except Exception: ret.code = 1002 ret.error = "更新失败" return Response(ret.dict)
def post(self, request, *args, **kwargs): ret = BaseResponse() article_id = request.data.get("article_id") arctile_obj = models.Article.objects.filter(id=article_id).first() tokens = request.data.get("token") account = models.Tokeninfo.objects.filter(tokens=tokens).first().user try: # 收藏成功 models.Collection.objects.create(content_object=arctile_obj, account=account) # 收藏数加1 models.Article.objects.filter(pk=article_id).update( collect_num=F("collect_num") + 1) ret.status = True ret.msg = "收藏成功" except Exception: # 这里报错就相当于在点击了一次收藏,即取消收藏 models.Article.objects.filter(pk=article_id).update( collect_num=F("collect_num") - 1) str_model = models.Article._meta.model_name models.Collection.objects.filter( content_type=ContentType.objects.get(model=str_model), object_id=article_id, account=account).delete() ret.msg = "取消收藏" ret.status = False return Response(ret.dict)
def update_order(request): """ 支付成功后,支付宝向该地址发送的POST请求(用于修改订单状态) :param request: :return: """ # 发送过来的一定是POST请求 if request.method == 'POST': from urllib.parse import parse_qs ret = BaseResponse() body_str = request.body.decode('utf-8') post_data = parse_qs(body_str) post_dict = {} for k, v in post_data.items(): post_dict[k] = v[0] alipay = aliPay() sign = post_dict.pop('sign', None) status = alipay.verify(post_dict, sign) if status: # 修改订单状态 out_trade_no = post_dict.get('out_trade_no') # 2. 根据订单号将数据库中的数据进行更新 models.Order.objects.filter(order_number=out_trade_no).update(status=0) ret.data = '支付成功' return Response(ret.dict) else: ret.code = 1100 ret.data = '支付失败' return Response(ret.dict) return HttpResponse('')
def post(self, request, *args, **kwargs): ''' 往当前用户的购物车里面添加内容 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() try: # 从 前端 传过来的数据:数据类型 course_id = int(request.data.get("courseid")) price_policy_id = int(request.data.get("policyid")) # 从认证组件中获取user_id user_id = request.auth.user.id # print(user_id) # 为了防止串改价格,必须要在后台进行验证 此课程是否有这个价格。 # 反向查询 course_obj = models.Course.objects.get(id=course_id) # 验证课程是否存在;不存在,报错后,会被外面的ObjectDoesNotExist错误 捕捉到。 # 拿到这个课程的所有价格对象 price_list = course_obj.price_policy.all() policy = {} for price_obj in price_list: policy[price_obj.id] = { "period_display": price_obj.get_valid_period_display(), "price": price_obj.price, "period": price_obj.valid_period } # 如果此课程没有这个价格。policy 里面的key就是价格策略的id if price_policy_id not in policy: # 一种是报错 raise PricePolicyInvalid("价格不合法") # 另外一种是直接返回 # ret.code = 1002 # ret.error = "价格不存在" # return Response(ret.dict) # 此课程有这个价格。 # 创建课程字典放入redis中 shoppingcar_course = { 'title': course_obj.name, 'img': '/xx/xx/xx.png', 'policy': json.dumps(policy), 'default_policy': price_policy_id } # luffy_shopping_car_6_11 redis_name = settings.SHOPPING_CRA_NAME % (user_id, course_id) # 对购物车里面的商品做限制(最多存放100个商品) num = 0 for n in self.conn.scan_iter(settings.SHOPPING_CRA_NAME % (user_id, '*')): if num < 100: num += 1 else: raise ShopNumberInvalid("购物车数量已满") # 按照字典的类型存储;在name对应的hash中批量设置键值对 self.conn.hmset(redis_name, shoppingcar_course) ret.data = "添加课程成功" except ShopNumberInvalid as e: ret.code = 1005 ret.error = e.msg except PricePolicyInvalid as e: ret.code = 1004 ret.error = e.msg except ObjectDoesNotExist: ret.code = 1003 ret.error = "课程不存在" except Exception: ret.code = 1002 ret.error = "添加课程错误" return Response(ret.dict)
def post(self, request, *args, **kwargs): ret = BaseResponse() # 1.点击支付后,从前端传过来有 用来抵消支付的贝里;已经总共需要支付的价格 try: user_id = request.auth.user.id #从前端传过来的 贝里,已经 需要支付的总金额;需要与后端进行验证 balance = float(request.data.get("balance")) allmoney = float(request.data.get("allmoney")) # 2.数据验证;验证当前用户是否有 与前端传过来的一样的贝里 user_balance = models.Userinfo.objects.filter( id=user_id).first().balance if user_balance < balance: # 用户账户里面没有足够的贝里 ret.code = 1002 ret.error = "该账户余额不足" return Response(ret.dict) # 去数据库里面去验证 #用户是否用 # 3.去结算中心里面取相应的数据,并进行验证; 验证当前的课程ID是否存在,以及价格策略ID是否存在,和使用的优惠卷ID是否存在。 coupon__id_list = [] course_obj_list = [] all_price = 0 for key in self.conn.scan_iter(settings.PAYMENT_CRA_NAME % (user_id, "*")): course_dict = {} title = self.conn.hget(key, "title").decode("utf-8") course_id = self.conn.hget(key, "course_id").decode("utf-8") c_time = self.conn.hget(key, "period").decode("utf-8") period_display = self.conn.hget( key, "period_display").decode("utf-8") price_id = self.conn.hget(key, "price_policyid").decode("utf-8") price = float(self.conn.hget(key, "price").decode("utf-8")) coupon_id = self.conn.hget(key, "default_coupon").decode("utf-8") coupon_dict = json.loads( self.conn.hget(key, "coupon").decode("utf-8")) c_obj = models.Course.objects.filter(id=course_id).first() p_obj = models.PricePolicy.objects.filter(id=price_id) if not c_obj: ret.code = 1003 ret.error = "%s课程不存在" % title return Response(ret.dict) if not p_obj: ret.code = 1005 ret.error = "%s课程价格不存在" % title return Response(ret.dict) couponused_price = price # 使用绑定的优惠卷 if coupon_id != "0": coupon_obj = models.CouponRecord.objects.filter( id=coupon_id).first() if not coupon_obj: ret.code = 1003 ret.error = "%s课程的优惠卷不存在" % title return Response(ret.dict) # 优惠卷存在 coupon__id_list.append(coupon_id) coupon_item = coupon_dict[coupon_id] c_type = coupon_item["c_type"] if c_type == 0: # 立减 money_equivalent_value = coupon_item[ "money_equivalent_value"] couponused_price = price - money_equivalent_value if couponused_price < 0: couponused_price = 0 elif c_type == 1: # 满减 money_equivalent_value = coupon_item[ "money_equivalent_value"] minimum_consume = coupon_item["minimum_consume"] if price < minimum_consume: ret.code = 1005 ret.error = "%s课程的费用达不到满减的要求" % title return Response(ret.dict) # 达到满减的要求: couponused_price = price - money_equivalent_value else: # 折扣 off_percent = coupon_item["off_percent"] couponused_price = price * (off_percent / 100) # 验证完后获取每个商品的原价和优惠后的价格 # 优惠后的价格 # 没有使用绑定的优惠卷 course_dict["c_obj"] = c_obj course_dict["price"] = price course_dict["couponused_price"] = couponused_price course_dict["c_time"] = c_time course_dict["period_display"] = period_display course_obj_list.append(course_dict) all_price += couponused_price # print(course_obj_list) # print(all_price) # 4.验证全局优惠卷是否存在,以及最终的价格 global_coupon_id = self.conn.hget(settings.GLOBAL_COUPON % user_id, "default_coupon").decode("utf-8") # print(global_coupon_item) end_price = all_price # 使用全站的优惠卷 if global_coupon_id != "0": global_coupon_obj = models.CouponRecord.objects.filter( id=global_coupon_id) global_coupon_dict = json.loads( self.conn.hget(settings.GLOBAL_COUPON % user_id, "coupon").decode("utf-8")) global_coupon_item = global_coupon_dict[global_coupon_id] if not global_coupon_obj: ret.code = 1006 ret.error = "全站优惠卷已经不存在" coupon__id_list.append(global_coupon_id) c_type = global_coupon_item["c_type"] if c_type == 0: # 立减 money_equivalent_value = global_coupon_item[ "money_equivalent_value"] end_price = all_price - money_equivalent_value if end_price < 0: end_price = 0 elif c_type == 1: # 满减 money_equivalent_value = global_coupon_item[ "money_equivalent_value"] minimum_consume = global_coupon_item["minimum_consume"] if all_price < minimum_consume: ret.code = 1005 ret.error = "结算费用达不到满减的要求" return Response(ret.dict) # 达到满减的要求: end_price = all_price - money_equivalent_value else: # 折扣 off_percent = global_coupon_item["off_percent"] end_price = all_price * (off_percent / 100) # print(end_price) # 贝里抵扣;为最后支付的价格 pay_price = end_price - balance print(pay_price) if pay_price <= 0: # 相当于全部抵消 pay_price = 0 if pay_price != allmoney: # 前端显示的最终支付的钱 不等于 后端计算的钱的时候就报错 ret.code = 1100 ret.error = "金额不合法" return Response(ret.dict) print(pay_price) #对 数据库里面的操作必须是原子性操作。 # Django中的事务 #生成订单号 order_number = "x2" + str(time.time()) try: from django.db import transaction with transaction.atomic(): # ORM 的操作 # 生成订单 order_obj = models.Order.objects.create( payment_type=1, order_number=order_number, account=request.auth.user, actual_amount=pay_price, status=1) # 每一个课程分别生成订单详情 for item in course_obj_list: obj = item["c_obj"] price = item["price"] couponused_price = item["couponused_price"] c_time = item["c_time"] period_display = item["period_display"] models.OrderDetail.objects.create( order=order_obj, content_object=obj, original_price=price, price=couponused_price, valid_period=c_time, valid_period_display=period_display) #如果有贝里支付;就修改用户账号里面的贝里 if balance > 0: #有贝里支付 models.Userinfo.objects.filter( id=request.auth.user.id).update( balance=F("balance") - balance) #以及修改使用后的优惠卷的状态 for coupon_id in coupon__id_list: models.CouponRecord.objects.filter( account=request.auth.user, id=coupon_id).update(status=1) except Exception: ret.code = 1200 ret.error = "数据库操作失败" if pay_price == 0: ret.data = "支付成功" return Response(ret.dict) #pay_price>0,用第三方的支付宝支付; 即跳转到第三方去支付 url = alipay.index(request, "课程", pay_price, order_number) return redirect(url) except Exception: 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: user_id = request.auth.user_id # 绑定的优惠卷 pay_name = settings.PAYMENT_CRA_NAME % (user_id, "*") # 全站优惠卷 # global_c_dict = {} global_coupon_name = settings.GLOBAL_COUPON % (user_id) #判断是否有全局的优惠卷 global_c_dict = {} if self.conn.exists(global_coupon_name): # print(self.conn.hget(global_coupon_name, "coupon")) global_coupon = json.loads( self.conn.hget(global_coupon_name, "coupon").decode("utf-8")) global_default_coupon = self.conn.hget( global_coupon_name, "default_coupon").decode("utf-8") # global_c_dict["global_coupon"] = global_coupon # global_c_dict["default_coupon"] = global_default_coupon # 添加全站的优惠卷 global_c_dict = { "global_coupon": global_coupon, "global_default_coupon": global_default_coupon } pay_list = [] for key in self.conn.scan_iter(pay_name, count=10): pay = {} for k, v in self.conn.hgetall(key).items(): k_str = k.decode("utf-8") if k_str == "coupon": pay[k.decode("utf-8")] = json.loads(v.decode("utf-8")) else: pay[k.decode("utf-8")] = v.decode("utf-8") pay_list.append(pay) # c_id = self.conn.hget(key, "course_id").decode("utf-8") # title = self.conn.hget(key, "title").decode("utf-8") # img = self.conn.hget(key, "img").decode("utf-8") # period_display = self.conn.hget(key, "period_display").decode("utf-8") # period = self.conn.hget(key, "period").decode("utf-8") # price = self.conn.hget(key, "price").decode("utf-8") # coupon = json.loads(self.conn.hget(key, "coupon").decode("utf-8")) # default_coupon = self.conn.hget(key, "default_coupon").decode("utf-8") # # pay[c_id] = { # "title": title, # "img": img, # "period_display": period_display, # "period": period, # "price": price, # "coupon": coupon, # "default_coupon": default_coupon # } #pay_list.append(pay) # print(pay_list) # ret.data = pay_list ret.data = { "course_list": pay_list, "global_coupon_dict": global_c_dict, } except Exception: ret.code = 1002 ret.error = "查看结算中心失败" return Response(ret.dict)
def post(self, request, *args, **kwargs): ''' 提交数据到结算中心 :param request: :param args: :param kwargs: :return: ''' ret = BaseResponse() try: c_idlist = request.data.get("courseid") user_id = request.auth.user_id # 每次把数据添加到结算中心之前,需要把该用户以前的数据清空后 再进行添加; # payment_1_1 for key in self.conn.scan_iter(settings.PAYMENT_CRA_NAME % (user_id, "*")): self.conn.delete(key) # payment_global_coupon_1 self.conn.delete(settings.GLOBAL_COUPON % user_id) # 1.获取用户要结算的课程; # 要验证用户里面是否有这个课程(不加入购物车直接支付 也就可行的) # 判断这个课程是否在用户的购物车里面 pays_dict = {} for c_id in c_idlist: pay_couser = {} s_name = settings.SHOPPING_CRA_NAME % (user_id, c_id) # 校验课程是否在购物车里面self.conn.exists() 看redis字典里面 name是否存在 if not self.conn.exists(s_name): ret.code = 1002 ret.error = "课程需要加入购物车才能进行结算" return Response(ret.dict) # 从用户购物车中获取信息,放入到结算中心。 policy = json.loads( self.conn.hget(s_name, "policy").decode("utf-8")) price_policyid = self.conn.hget( s_name, "default_policy").decode("utf-8"), # print(price_policyid) 变为元组了 ('1',) policy_info = policy[price_policyid[0]] # 要结算的所有课程 pay_couser = { 'course_id': c_id, "title": self.conn.hget(s_name, "title").decode("utf-8"), "img": self.conn.hget(s_name, "img").decode("utf-8"), "price_policyid": self.conn.hget(s_name, "default_policy").decode("utf-8"), "coupon": {}, "default_coupon": 0, } pay_couser.update(policy_info) pays_dict[str(c_id)] = pay_couser # print(pays_dict) #在这里报错,只是没有优惠卷而已。 try: c_time = datetime.date.today( ) # 年月日; datetime.datetime.now() #年月日 时分秒 # 比如 优惠卷有效时间截止到7 ;如果优惠卷是包含7号当天的话,就today();如果不包含的话就用 now() # 获取优惠券: 有比有效时间大,并且比有效结束时间小的优惠卷才能使用; lte 小于等于 coupon_obj_list = models.CouponRecord.objects.filter( account__id=user_id, status=0, coupon__valid_begin_date__lte=c_time, coupon__valid_end_date__gte=c_time) # coupon_obj_list 没有找到就会报错 # print(coupon_obj_list) # 放全站优惠卷 global_coupon_dict = {"coupon": {}, "default_coupon": 0} for coupon_obj in coupon_obj_list: # 筛选出绑定课程的优惠卷 # 绑定课程的优惠卷 也分3种:通用(立减);满减;折扣; 每一个优惠券取的值不同 coupon_dic = {} # 优惠卷的id coupon_id = coupon_obj.id # 优惠卷的类型 c_type = coupon_obj.coupon.coupon_type coupon_type = coupon_obj.coupon.get_coupon_type_display() # 优惠卷绑定课程的id bind_c = coupon_obj.coupon.object_id if not bind_c: # 不是绑定课程的优惠卷; 即全站优惠卷;同样也分为三种: global_coupon = {} global_coupon["c_type"] = c_type global_coupon["coupon_type"] = coupon_type if c_type == 0: # 通用(立减) global_coupon[ "money_equivalent_value"] = coupon_obj.coupon.money_equivalent_value elif c_type == 1: # 满减 global_coupon[ "money_equivalent_value"] = coupon_obj.coupon.money_equivalent_value global_coupon[ "minimum_consume"] = coupon_obj.coupon.minimum_consume else: # 折扣 (不带满减的折扣) global_coupon[ "off_percent"] = coupon_obj.coupon.off_percent global_coupon_dict["coupon"][coupon_id] = global_coupon global_coupon_dict["coupon"] = json.dumps( global_coupon_dict["coupon"]) # print(global_coupon_dict,type(global_coupon_dict["coupon"])) coupon_dic = {} coupon_dic["c_type"] = c_type coupon_dic["coupon_type"] = coupon_type # 绑定课程的优惠卷 if c_type == 0: # 通用(立减) coupon_dic[ "money_equivalent_value"] = coupon_obj.coupon.money_equivalent_value elif c_type == 1: # 满减 coupon_dic[ "money_equivalent_value"] = coupon_obj.coupon.money_equivalent_value coupon_dic[ "minimum_consume"] = coupon_obj.coupon.minimum_consume else: # 折扣 (不带满减的折扣) coupon_dic[ "off_percent"] = coupon_obj.coupon.off_percent # 把绑定课程的优惠卷放入指定课程内: for c_id in pays_dict: if c_id != str(bind_c): continue # 是绑定该课程的优惠卷 pays_dict[c_id]['coupon'][coupon_id] = coupon_dic # print(pays_dict) # print(global_coupon_dict) for key, v in pays_dict.items(): # 把字典变为字符串 v["coupon"] = json.dumps(v["coupon"]) self.conn.hmset(settings.PAYMENT_CRA_NAME % (user_id, key), v) # 放全站优惠卷 只与用户有关。 self.conn.hmset(settings.GLOBAL_COUPON % user_id, global_coupon_dict) ret.data = "添加成功" except Exception: ret.data = "添加成功" except Exception: ret.code = 1002 ret.error = "提交错误" return Response(ret.dict)