优惠券
创建一个coupon子应用.
cd luffy/apps python ../../manage.py startapp coupon
注册子应用
INSTALLED_APPS = [ # 子应用 。。。 'coupon', ]
模型分析:
代码:
from django.db import models from luffy.utils.models import BaseModel # Create your models here. class Coupon(BaseModel): """优惠券""" coupon_choices = ( (0, '折扣优惠'), (1, '减免优惠') ) name = models.CharField(max_length=32, verbose_name="优惠券标题") coupon_type = models.SmallIntegerField(choices=coupon_choices, default=0, verbose_name="优惠券类型") timer = models.IntegerField(verbose_name="优惠券有效期", default=30, help_text="") condition = models.IntegerField(blank=True, default=0, verbose_name="满足使用优惠券的价格条件") sale = models.TextField(verbose_name="优惠公式", help_text=""" *号开头表示折扣价,例如*0.82表示八二折;<br> -号开头表示减免价,例如-10表示在总价基础上减免10元<br> """) class Meta: db_table = "ly_coupon" verbose_name="优惠券" verbose_name_plural="优惠券" def __str__(self): return "%s" % (self.name) from users.models import User class UserCoupon(BaseModel): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="coupons", verbose_name="用户") coupon = models.ForeignKey(Coupon, on_delete=models.CASCADE, related_name="users", verbose_name="优惠券") start_time = models.DateTimeField(verbose_name="优惠策略的开始时间") is_use = models.BooleanField(default=False,verbose_name="优惠券是否使用过") class Meta: db_table = "ly_user_coupon" verbose_name = "用户的优惠券" verbose_name_plural = "用户的优惠券" def __str__(self): return "优惠券:%s,用户:%s" % (self.coupon.name, self.user.username)
数据迁移
cd ../../ python manage.py makemigrations python manage.py migrate
注册到xadmin,添加测试数据[1.添加优惠券,给用户发放优惠券]
import xadmin from .models import Coupon class CouponModelAdmin(object): """优惠券模型管理类""" list_display = ["name","coupon_type","timer"] xadmin.site.register(Coupon, CouponModelAdmin) from .models import UserCoupon class UserCouponModelAdmin(object): """我的优惠券模型管理类""" list_display = ["user","coupon","start_time","is_use"] xadmin.site.register(UserCoupon, UserCouponModelAdmin)
在订单页面查询当前用户拥有的优惠券
前端编写优惠券的样式代码:
<template> <div class="cart"> <Header/> <div class="cart-info"> <h3 class="cart-top">购物车结算 <span>共1门课程</span></h3> <div class="cart-title"> <el-row> <el-col :span="2"> </el-col> <el-col :span="10">课程</el-col> <el-col :span="8">有效期</el-col> <el-col :span="4">价格</el-col> </el-row> </div> <div class="cart-item" v-for="course in order_info.order_courses"> <el-row> <el-col :span="2" class="checkbox"> </el-col> <el-col :span="10" class="course-info"> <img style="float: left;" :src="$settings.Host+course.course_img" alt=""> <span class="course_name"> <span>{{course.course_name}}</span><br> <span class="discount_name">{{course.discount_name}}</span> </span> </el-col> <el-col :span="8" class="lh"><span>{{course.expire_text}}</span></el-col> <el-col :span="4"> <div class="course-price"> <p class="real_price">¥{{course.real_price}}</p> <span class="original_price">原价: ¥{{course.price}}</span> </div> </el-col> </el-row> </div> <div> <div class="coupon"> <div id="accordion"> <div class="coupon-box"> <div class="coupon-title"> <span class="select-coupon">使用优惠劵:</span> <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" style="width: 20px; height: 20px" class="collapsed" aria-expanded="false"> <img class="sign" src="../../static/img/12.png" width="20" height="20" alt=""></a> <span class="coupon-num">有0张可用</span> </div> <p class="sum-price-wrap" style="margin-right: 45px">商品总金额:<span class="sum-price">{{order_info.total_price}}元</span></p> </div> <div style="text-align: left;" id="collapseOne" class="panel-collapse out collapse" aria-expanded="false"> <ul class="coupon-list" style=""> <li class="coupon-item"> <span>优惠券</span> <span>¥10元</span> <span>开始使用时间: 2019-10-01</span> </li> <li class="coupon-item"> <span>优惠券</span> <span>¥10元</span> <span>开始使用时间: 2019-10-01</span> </li> </ul> <div style="text-align: center; width: 100%; padding: 50px 0px; align-items: center; justify-content: center; border-bottom: 1px solid rgb(232, 232, 232);"> <span style="font-size: 16px; color: #9b9b9b">暂无可用优惠券</span> </div> </div> </div> <div style="height: 30px; margin-top: 40px; display: flex; align-items: center; justify-content: flex-end"> <input type="checkbox" class="ok" id="color-input-red"> <label for="color-input-red"><img src="" alt=""></label> <p class="discount-num" style="color:#9B9B9B">使用我的贝里</p> <p class="discount-num" style="margin-right: 45px"> <span style="display: none;">可用0个已抵扣 ¥0</span> </p> </div> <p class="sun-coupon-num" style="margin-right: 45px;margin-bottom:43px">优惠券抵扣:<span>0元</span></p> </div> </div> <div class="calc"> <el-row class="pay-row"> <el-col :span="4" class="pay-col"><span class="pay-text">支付方式:</span></el-col> <el-col :span="8"> <span class="alipay"><img src="../../static/img/alipay2.png" alt=""></span> <span class="alipay wechat"><img src="../../static/img/wechat.png" alt=""></span> </el-col> <el-col :span="8" class="count">实付款: <span>¥{{order_info.total_price}}</span></el-col> <el-col :span="4" class="cart-pay"><span @click="payhander">支付宝支付</span></el-col> </el-row> </div> </div> <Footer/> </div> </template> <script> 。。。。 </script> <style scoped> 。。。 .coupon-list{ overflow: hidden; } .coupon-item{ float: left; margin-left: 10px; margin-right: 10px; width: 200px; height: 120px; border: 1px solid #000; padding: 10px; } .coupon-item span{ display: block; font-size: 14px; } </style>
后端提供查询当前用户拥有的优惠券api接口
序列化器,代码:
from rest_framework import serializers from .models import Coupon, UserCoupon class CouponModelSerializer(serializers.ModelSerializer): class Meta: model = Coupon fields = ("name","coupon_type","timer","condition","sale") class UserCouponModelSerializer(serializers.ModelSerializer): coupon = CouponModelSerializer() class Meta: model = UserCoupon fields = ("id","start_time","coupon")
视图,代码:
from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated from django_filters.rest_framework import DjangoFilterBackend from .models import UserCoupon from .serializers import UserCouponModelSerializer class UserCouponAPIVew(ListAPIView): """我的优惠券""" queryset = UserCoupon.objects.filter(is_show=True,is_delete=False,is_use=False) serializer_class = UserCouponModelSerializer permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] ordering_fields = ('user_id',)
子应用路由,代码:
from django.urls import path from . import views urlpatterns = [ path(r"list/",views.UserCouponAPIVew.as_view()), ]
总路由,代码:
path('coupon/', include("coupon.urls")),
前端展示当前用户拥有的优惠券并勾选使用优惠券以后,会自动调整订单实付价格
代码:
<template> <div class="cart"> <Header/> <div class="cart-info"> <h3 class="cart-top">购物车结算 <span>共1门课程</span></h3> <div class="cart-title"> <el-row> <el-col :span="2"> </el-col> <el-col :span="10">课程</el-col> <el-col :span="8">有效期</el-col> <el-col :span="4">价格</el-col> </el-row> </div> <div class="cart-item" v-for="course in order_info.order_courses"> <el-row> <el-col :span="2" class="checkbox"> </el-col> <el-col :span="10" class="course-info"> <img style="float: left;" :src="$settings.Host+course.course_img" alt=""> <span class="course_name"> <span>{{course.course_name}}</span><br> <span class="discount_name">{{course.discount_name}}</span> </span> </el-col> <el-col :span="8" class="lh"><span>{{course.expire_text}}</span></el-col> <el-col :span="4"> <div class="course-price"> <p class="real_price">¥{{course.real_price}}</p> <span class="original_price">原价: ¥{{course.price}}</span> </div> </el-col> </el-row> </div> <div> <div class="coupon"> <div id="accordion"> <div class="coupon-box"> <div class="coupon-title"> <span class="select-coupon">使用优惠劵:</span> <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" style="width: 20px; height: 20px" class="collapsed" aria-expanded="false"> <img class="sign" src="../../static/img/12.png" width="20" height="20" alt=""></a> <span class="coupon-num">有0张可用</span> </div> <p class="sum-price-wrap" style="margin-right: 45px">商品总金额:<span class="sum-price">{{order_info.total_price}}元</span></p> </div> <div style="text-align: left;" id="collapseOne" class="panel-collapse out collapse" aria-expanded="false"> <ul class="coupon-list" v-if="coupon_list.length>0"> <li @click="use_coupon=item.id" v-for="item in coupon_list" class="coupon-item" :class="use_coupon==item.id?'coupon_selected':''"> <span>{{item.coupon.name}}</span> <span v-if="item.coupon.type==1">¥{{item.coupon.sale}}元</span> <span style="font-size: 12px;">开始使用时间: {{new Date(item.start_time).toLocaleString()}}</span> </li> </ul> <div v-else style="text-align: center; width: 100%; padding: 50px 0px; align-items: center; justify-content: center; border-bottom: 1px solid rgb(232, 232, 232);"> <span style="font-size: 16px; color: #9b9b9b">暂无可用优惠券</span> </div> </div> </div> <div style="height: 30px; margin-top: 40px; display: flex; align-items: center; justify-content: flex-end"> <input type="checkbox" class="ok" id="color-input-red"> <label for="color-input-red"><img src="" alt=""></label> <p class="discount-num" style="color:#9B9B9B">使用我的贝里</p> <p class="discount-num" style="margin-right: 45px"> <span style="display: none;">可用0个已抵扣 ¥0</span> </p> </div> <p class="sun-coupon-num" style="margin-right: 45px;margin-bottom:43px">优惠券抵扣:<span>0元</span></p> </div> </div> <div class="calc"> <el-row class="pay-row"> <el-col :span="4" class="pay-col"><span class="pay-text">支付方式:</span></el-col> <el-col :span="8"> <span class="alipay"><img src="../../static/img/alipay2.png" alt=""></span> <span class="alipay wechat"><img src="../../static/img/wechat.png" alt=""></span> </el-col> <el-col :span="8" class="count">实付款: <span>¥{{order_info.real_price}}</span></el-col> <el-col :span="4" class="cart-pay"><span @click="payhander">支付宝支付</span></el-col> </el-row> </div> </div> <Footer/> </div> </template> <script> import Header from "./common/Header" import Footer from "./common/Footer" export default { name:"Order", data(){ return { use_coupon: 0, order_info:{}, coupon_list:[], // 用于展示优惠券列表 coupon_list2:[],// 用于勾选优惠券功能 } }, components:{ Header, Footer, }, watch:{ use_coupon(coupon_id){ let data = this.coupon_list2[ coupon_id ]; let sale = parseFloat( data.coupon.sale.slice(1) ); if( data.coupon.coupon_type == 0 ){ // 折扣优惠券 this.order_info.real_price = this.order_info.total_price * sale; }else if(data.coupon.coupon_type == 1){ // 减免优惠券 this.order_info.real_price = this.order_info.total_price - sale; } this.order_info.real_price = this.order_info.real_price.toFixed(2); // 发送数据到后端,进行同步 } }, created(){ // 判断用户是否已经登录 let token = sessionStorage.token || localStorage.token; let _this = this; if(!token){ this.$alert("对不起,您尚未登录!请登录!","警告",{ callback(){ _this.$router.push("/login"); } }) } // 获取地址栏上面的订单号 let order_number = this.$route.params.order; // 发送请求获取数据 this.$axios.get(this.$settings.Host+`/orders/${order_number}/`,{ headers:{ // 注意下方的空格!!! "Authorization":"jwt " + token, }, }).then(response=>{ this.order_info = response.data; }).catch(error=>{ console.log(error.response); }); // 获取用户的优惠券 this.get_coupon_list() }, methods: { get_coupon_list(){ let user_id = localStorage.user_id || sessionStorage.user_id; let token = localStorage.token || sessionStorage.token; // 获取当前用户的优惠券 this.$axios.get(this.$settings.Host+"/coupon/list/",{ params:{ user_id, }, headers:{ // 注意下方的空格!!! "Authorization":"jwt " + token, }, }).then(response=>{ // 调整获取到优惠券列表,以优惠券ID作为下标 let data_list = []; response.data.forEach(row=>{ data_list[row.id] = row; }); this.coupon_list2= data_list; this.coupon_list = response.data; }).catch(error=>{ console.log(error.response); }) }, payhander(){ }, } } </script> <style scoped> .cart{ margin-top: 80px; } .cart-info{ overflow: hidden; width: 1200px; margin: auto; } .cart-top{ font-size: 18px; color: #666; margin: 25px 0; font-weight: normal; } .cart-top span{ font-size: 12px; color: #d0d0d0; display: inline-block; } .cart-title{ background: #F7F7F7; height: 70px; } .calc{ margin-top: 25px; margin-bottom: 40px; } .calc .count{ text-align: right; margin-right: 10px; vertical-align: middle; } .calc .count span{ font-size: 36px; color: #333; } .calc .cart-pay{ margin-top: 5px; width: 110px; height: 38px; outline: none; border: none; color: #fff; line-height: 38px; background: #ffc210; border-radius: 4px; font-size: 16px; text-align: center; cursor: pointer; } .cart-item{ height: 120px; /*line-height: 120px;*/ } .cart-item .lh{ line-height: 120px; } .course-info img{ width: 175px; height: 115px; margin-right: 35px; vertical-align: middle; } .course-price{ margin-top: 40px; } .alipay{ display: inline-block; height: 48px; } .alipay img{ height: 100%; width:auto; } .pay-text{ display: block; text-align: right; height: 100%; line-height: 100%; vertical-align: middle; margin-top: 20px; } .real_price{ color: #333; margin-bottom: 10px; } .original_price{ color: #9b9b9b; letter-spacing: .36px; text-decoration: line-through; } .coupon{ margin-top: 30px; } .coupon-box{ text-align: left; display: flex; padding-bottom: 22px; padding-left:30px; border-bottom: 1px solid #e8e8e8; } .coupon-title{ display: flex; } .sum-price-wrap{ display: inline-block; margin-left: auto; font-size: 16px; color: #4a4a4a; } .discount_name{ color: #ffc210; margin-top: 24px; font-size: 14px; letter-spacing: .32px; } .course_name{ margin-top: 40px; display: block; } .coupon-list{ overflow: hidden; } .coupon-item{ float: left; margin-left: 10px; margin-right: 10px; width: 200px; height: 60px; border: 1px solid #000; padding: 10px; } .coupon-item span{ display: block; font-size: 14px; } .coupon_selected{ border-color: red; color: indianred; } </style>
发起支付-支付宝
支付宝开发平台登录
https://open.alipay.com/platform/home.htm
沙箱环境
是支付宝提供给开发者的模拟支付的环境
沙箱环境跟真实环境是分开的,项目上线时必须切换对应的配置服务器地址和开发者ID和密钥。
沙箱应用开发文档:<https://docs.open.alipay.com
沙箱账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account
真实的支付宝网关: https://openapi.alipay.com/gateway.do 沙箱的支付宝网关: https://openapi.alipaydev.com/gateway.do
支付宝开发者文档
- 文档主页:https://openhome.alipay.com/developmentDocument.htm
- 产品介绍:https://docs.open.alipay.com/270
电脑网站支付流程
开发支付功能
cd luffy/apps python ../../manage.py startapp payments
注册子应用
INSTALLED_APPS = [ 。。。。 'payments', ]
配置秘钥
1. 生成应用的私钥和公钥
下载对应系统的秘钥生成工具: https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
应用公钥复制粘贴到支付宝网站页面中.
点击修改以后,粘贴进去
2. 保存应用私钥文件
在payments应用中新建keys目录,用来保存秘钥文件。
将应用私钥文件app_private_key.pem复制到payment/keys目录下。
-----BEGIN RSA PRIVATE KEY----- 私钥 -----END RSA PRIVATE KEY-----
3. 保存支付宝公钥
在payment/keys目录下新建alipay_public_key.pem文件,用于保存支付宝的公钥文件。
将支付宝的公钥内容复制到alipay_public_key.pem文件中
-----BEGIN PUBLIC KEY----- 公钥 -----END PUBLIC KEY-----
4. 使用支付宝的sdk开发支付接口
SDK:https://docs.open.alipay.com/270/106291/
python版本的支付宝SDK文档:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
安装命令:
pip install python-alipay-sdk --upgrade
后端提供发起支付的接口url地址
from rest_framework.views import APIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework import status from orders.models import Order from coupon.models import UserCoupon from alipay import AliPay from django.conf import settings import os from django.db import transaction from decimal import Decimal class AlipayAPIView(APIView): # permission_classes = [IsAuthenticated] def get(self,request): """生成支付宝支付地址""" # 接受参数[优惠券,订单号] coupon_id = request.query_params.get("coupon_id") order_number = request.query_params.get("order_number") try: order = Order.objects.get(order_number=order_number) except Order.DoesNotExist: return Response({"message":"对不起,当前订单信息不存在!无法进行支付"},status=status.HTTP_400_BAD_REQUEST) if coupon_id != None and coupon_id != "0": with transaction.atomic(): save_id = transaction.savepoint() # 重新计算订单实际支付价格 try: user_coupon = UserCoupon.objects.get(pk=coupon_id) except UserCoupon.DoesNotExist: return Response({"message": "对不起,当前订单使用的优惠券不存在!无法进行支付"}, status=status.HTTP_400_BAD_REQUEST) if user_coupon.coupon.coupon_type == 0: """折扣优惠""" order.real_price = order.total_price * Decimal(user_coupon.coupon.sale[1:]) elif user_coupon.coupon.coupon_type == 1: order.real_price = order.total_price - Decimal(user_coupon.coupon.sale[1:]) else: return Response({"message": "当前优惠券无法使用!无法进行支付"}, status=status.HTTP_400_BAD_REQUEST) try: # 经过上面的计算,保存实付价格和使用的优惠券 order.use_coupon = True order.coupon = user_coupon.id order.save() # 上面的优惠券已经被使用了,所以我们需要修改优惠券的状态 user_coupon.is_use = True user_coupon.save() except: transaction.savepoint_rollback(save_id) return Response({"message": "系统异常,无法进行支付"}, status=status.HTTP_400_BAD_REQUEST) # 构造支付宝支付链接地址 alipay = AliPay( appid=settings.ALIPAY_APPID, app_notify_url=settings.APP_NOTIFY_URL, # 默认回调url app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"), # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem"), sign_type="RSA2", # RSA 或者 RSA2 debug=settings.ALIPAY_DEBUG ) order_string = alipay.api_alipay_trade_page_pay( out_trade_no=order.order_number, total_amount= "%.2f" % order.real_price, subject=order.order_title, return_url=settings.ALIPAY_RETURN_URL, notify_url=settings.ALIPAY_NOTIFY_URL, ) url = settings.APIPAY_GATEWAY + "?" + order_string return Response({"message":"发起支付成功","url":url})
在配置文件中编辑支付宝的配置信息[实际的值根据自己的账号而定]
# 支付宝 ALIPAY_APP_ID="2016091600523592" # 应用ID APLIPAY_APP_NOTIFY_URL = None # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面] ALIPAY_DEBUG = True # APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do" APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do" ALIPAY_RETURN_URL = "http://127.0.0.1:8080/success" ALIPAY_NOTIFY_URL = "http://127.0.0.1:8080/success"
前端点击"支付宝支付",请求后端的发起支付api
<template> <div class="cart"> <Header/> <div class="cart-info"> <h3 class="cart-top">购物车结算 <span>共1门课程</span></h3> <div class="cart-title"> <el-row> <el-col :span="2"> </el-col> <el-col :span="10">课程</el-col> <el-col :span="8">有效期</el-col> <el-col :span="4">价格</el-col> </el-row> </div> <div class="cart-item" v-for="course in order_info.order_courses"> <el-row> <el-col :span="2" class="checkbox"> </el-col> <el-col :span="10" class="course-info"> <img style="float: left;" :src="$settings.Host+course.course_img" alt=""> <span class="course_name"> <span>{{course.course_name}}</span><br> <span class="discount_name">{{course.discount_name}}</span> </span> </el-col> <el-col :span="8" class="lh"><span>{{course.expire_text}}</span></el-col> <el-col :span="4"> <div class="course-price"> <p class="real_price">¥{{course.real_price}}</p> <span class="original_price">原价: ¥{{course.price}}</span> </div> </el-col> </el-row> </div> <div> <div class="coupon"> <div id="accordion"> <div class="coupon-box"> <div class="coupon-title"> <span class="select-coupon">使用优惠劵:</span> <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" style="width: 20px; height: 20px" class="collapsed" aria-expanded="false"> <img class="sign" src="../../static/img/12.png" width="20" height="20" alt=""></a> <span class="coupon-num">有0张可用</span> </div> <p class="sum-price-wrap" style="margin-right: 45px">商品总金额:<span class="sum-price">{{order_info.total_price}}元</span></p> </div> <div style="text-align: left;" id="collapseOne" class="panel-collapse out collapse" aria-expanded="false"> <ul class="coupon-list" v-if="coupon_list.length>0"> <li @click="use_coupon=item.id" v-for="item in coupon_list" class="coupon-item" :class="use_coupon==item.id?'coupon_selected':''"> <span>{{item.coupon.name}}</span> <span v-if="item.coupon.type==1">¥{{item.coupon.sale}}元</span> <span style="font-size: 12px;">开始使用时间: {{new Date(item.start_time).toLocaleString()}}</span> </li> </ul> <div v-else style="text-align: center; width: 100%; padding: 50px 0px; align-items: center; justify-content: center; border-bottom: 1px solid rgb(232, 232, 232);"> <span style="font-size: 16px; color: #9b9b9b">暂无可用优惠券</span> </div> </div> </div> <div style="height: 30px; margin-top: 40px; display: flex; align-items: center; justify-content: flex-end"> <input type="checkbox" class="ok" id="color-input-red"> <label for="color-input-red"><img src="" alt=""></label> <p class="discount-num" style="color:#9B9B9B">使用我的贝里</p> <p class="discount-num" style="margin-right: 45px"> <span style="display: none;">可用0个已抵扣 ¥0</span> </p> </div> <p class="sun-coupon-num" style="margin-right: 45px;margin-bottom:43px">优惠券抵扣:<span>0元</span></p> </div> </div> <div class="calc"> <el-row class="pay-row"> <el-col :span="4" class="pay-col"><span class="pay-text">支付方式:</span></el-col> <el-col :span="8"> <span class="alipay"><img src="../../static/img/alipay2.png" alt=""></span> <span class="alipay wechat"><img src="../../static/img/wechat.png" alt=""></span> </el-col> <el-col :span="8" class="count">实付款: <span>¥{{order_info.real_price}}</span></el-col> <el-col :span="4" class="cart-pay"><span @click="payhander">支付宝支付</span></el-col> </el-row> </div> </div> <Footer/> </div> </template> <script> import Header from "./common/Header" import Footer from "./common/Footer" export default { name:"Order", data(){ return { use_coupon: 0, // 使用的优惠券ID order_info:{}, coupon_list:[], // 用于展示优惠券列表 coupon_list2:[],// 用于勾选优惠券功能 } }, components:{ Header, Footer, }, watch:{ use_coupon(coupon_id){ let data = this.coupon_list2[ coupon_id ]; let sale = parseFloat( data.coupon.sale.slice(1) ); if( data.coupon.coupon_type == 0 ){ // 折扣优惠券 this.order_info.real_price = this.order_info.total_price * sale; }else if(data.coupon.coupon_type == 1){ // 减免优惠券 this.order_info.real_price = this.order_info.total_price - sale; } this.order_info.real_price = this.order_info.real_price.toFixed(2); // 发送数据到后端,进行同步 } }, created(){ // 判断用户是否已经登录 let token = sessionStorage.token || localStorage.token; let _this = this; if(!token){ this.$alert("对不起,您尚未登录!请登录!","警告",{ callback(){ _this.$router.push("/login"); } }) } // 获取地址栏上面的订单号 let order_number = this.$route.params.order; // 发送请求获取数据 this.$axios.get(this.$settings.Host+`/orders/${order_number}/`,{ headers:{ // 注意下方的空格!!! "Authorization":"jwt " + token, }, }).then(response=>{ this.order_info = response.data; }).catch(error=>{ console.log(error.response); }); // 获取用户的优惠券 this.get_coupon_list() }, methods: { get_coupon_list(){ let user_id = localStorage.user_id || sessionStorage.user_id; let token = localStorage.token || sessionStorage.token; // 获取当前用户的优惠券 this.$axios.get(this.$settings.Host+"/coupon/list/",{ params:{ user_id, }, headers:{ // 注意下方的空格!!! "Authorization":"jwt " + token, }, }).then(response=>{ // 调整获取到优惠券列表,以优惠券ID作为下标 let data_list = []; response.data.forEach(row=>{ data_list[row.id] = row; }); this.coupon_list2= data_list; this.coupon_list = response.data; }).catch(error=>{ console.log(error.response); }) }, payhander(){ this.$confirm("您即将跳转到支付宝页面进行订单支付?","提示").then(()=>{ let token = localStorage.token || sessionStorage.token; // 获取订单号 let order_number = this.$route.params.order; // 发起支付请求 this.$axios.get(this.$settings.Host+"/payments/alipay/url/",{ params:{ order_number: order_number, coupon_id: this.use_coupon, }, headers:{ // 注意下方的空格!!! "Authorization":"jwt " + token, }, }).then(response=>{ let url = response.data.url; console.log(url); // 页面跳转 location.assign( url ); }).catch(error=>{ console.log(error.response) }) }); }, } } </script> <style scoped> .cart{ margin-top: 80px; } .cart-info{ overflow: hidden; width: 1200px; margin: auto; } .cart-top{ font-size: 18px; color: #666; margin: 25px 0; font-weight: normal; } .cart-top span{ font-size: 12px; color: #d0d0d0; display: inline-block; } .cart-title{ background: #F7F7F7; height: 70px; } .calc{ margin-top: 25px; margin-bottom: 40px; } .calc .count{ text-align: right; margin-right: 10px; vertical-align: middle; } .calc .count span{ font-size: 36px; color: #333; } .calc .cart-pay{ margin-top: 5px; width: 110px; height: 38px; outline: none; border: none; color: #fff; line-height: 38px; background: #ffc210; border-radius: 4px; font-size: 16px; text-align: center; cursor: pointer; } .cart-item{ height: 120px; /*line-height: 120px;*/ } .cart-item .lh{ line-height: 120px; } .course-info img{ width: 175px; height: 115px; margin-right: 35px; vertical-align: middle; } .course-price{ margin-top: 40px; } .alipay{ display: inline-block; height: 48px; } .alipay img{ height: 100%; width:auto; } .pay-text{ display: block; text-align: right; height: 100%; line-height: 100%; vertical-align: middle; margin-top: 20px; } .real_price{ color: #333; margin-bottom: 10px; } .original_price{ color: #9b9b9b; letter-spacing: .36px; text-decoration: line-through; } .coupon{ margin-top: 30px; } .coupon-box{ text-align: left; display: flex; padding-bottom: 22px; padding-left:30px; border-bottom: 1px solid #e8e8e8; } .coupon-title{ display: flex; } .sum-price-wrap{ display: inline-block; margin-left: auto; font-size: 16px; color: #4a4a4a; } .discount_name{ color: #ffc210; margin-top: 24px; font-size: 14px; letter-spacing: .32px; } .course_name{ margin-top: 40px; display: block; } .coupon-list{ overflow: hidden; } .coupon-item{ float: left; margin-left: 10px; margin-right: 10px; width: 200px; height: 60px; border: 1px solid #000; padding: 10px; } .coupon-item span{ display: block; font-size: 14px; } .coupon_selected{ border-color: red; color: indianred; } </style>
支付成功的模板
<template> <div class="success"> <Header :current_page="current_page"/> <div class="main"> <div class="title"> <img src="../../static/images/right.svg" alt=""> <div class="success-tips"> <p class="tips1">您已成功购买 1 门课程!</p> <p class="tips2">你还可以加入QQ群 <span>747556033</span> 学习交流</p> </div> </div> <div class="order-info"> <p class="info1"><b>付款时间:</b><span>2019/04/02 10:27</span></p> <p class="info2"><b>付款金额:</b><span >0</span></p> <p class="info3"><b>课程信息:</b><span><span>《Pycharm使用秘籍》</span></span></p> </div> <div class="wechat-code"> <img src="../../static/images/server.cf99f78.png" alt="" class="er"> <p><img src="../../static/images/tan.svg" alt="">重要!微信扫码关注获得学习通知&课程更新提醒!否则将严重影响学习进度和课程体验!</p> </div> <div class="study"> <span>立即学习</span> </div> </div> <Footer/> </div> </template> <script> import Header from "./common/Header" import Footer from "./common/Footer" export default{ name:"Success", data(){ return { current_page:0, }; }, components:{ Header, Footer, } } </script> <style scoped> .success{ padding-top: 80px; } .main{ height: 100%; padding-top: 25px; padding-bottom: 25px; margin: 0 auto; width: 1200px; background: #fff; } .main .title{ display: flex; -ms-flex-align: center; align-items: center; padding: 25px 40px; border-bottom: 1px solid #f2f2f2; } .main .title .success-tips{ box-sizing: border-box; } .title img{ vertical-align: middle; width: 60px; height: 60px; margin-right: 40px; } .title .success-tips{ box-sizing: border-box; } .title .tips1{ font-size: 22px; color: #000; } .title .tips2{ font-size: 16px; color: #4a4a4a; letter-spacing: 0; text-align: center; margin-top: 10px; } .title .tips2 span{ color: #ec6730; } .order-info{ padding: 25px 48px; padding-bottom: 15px; border-bottom: 1px solid #f2f2f2; } .order-info p{ font-family: PingFangSC-Regular; display: -ms-flexbox; display: flex; margin-bottom: 10px; font-size: 16px; } .order-info p b{ font-weight: 400; color: #9d9d9d; white-space: nowrap; } .wechat-code{ display: flex; -ms-flex-align: center; align-items: center; padding: 25px 40px; border-bottom: 1px solid #f2f2f2; } .wechat-code>img{ width: 100px; height: 100px; margin-right: 15px; } .wechat-code p{ font-family: PingFangSC-Regular; font-size: 14px; color: #d0021b; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .wechat-code p>img{ width: 16px; height: 16px; margin-right: 10px; } .study{ padding: 25px 40px; } .study span{ display: block; width: 140px; height: 42px; text-align: center; line-height: 42px; cursor: pointer; background: #ffc210; border-radius: 6px; font-family: PingFangSC-Regular; font-size: 16px; color: #fff; } </style>
精彩评论