11 文章打赏

支付打赏弹窗


<template>
  <div class="_21bLU4 _3kbg6I" @click.stop="is_show_reward_window=false">
   <Header></Header>
  															

   <div class="_23ISFX-body" v-if="is_show_reward_window" @click.stop="is_show_reward_window=true">
   <div class="_3uZ5OL">
    <div class="_2PLkjk">
     <img class="_2R1-48" src="https://upload.jianshu.io/users/upload_avatars/9602437/8fb37921-2e4f-42a7-8568-63f187c5721b.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/100/h/100/format/webp" alt="" />
     <div class="_2h5tnQ">
      给作者送糖
     </div>
    </div>
    <div class="_1-bCJJ">
     <div class="LMa6S_" :class="reward_info.money==num?'_1vONvL':''" @click="reward_info.money=num" v-for="num in reward_list"><span>{{num}}</span></div>
    </div>
    <textarea class="_1yN79W" placeholder="给Ta留言..."></textarea>
    <div class="_1_B577">
     选择支付方式
    </div>
    <div class="_1-bCJJ">
     <div class="LMa6S_ _3PA8BN" :class="reward_info.pay_type==type?'_1vONvL':''" @click="reward_info.pay_type=type" v-for="type in pay_type_list"><span>{{type}}</span></div>
    </div>
    <button type="button" class="_3A-4KL _1OyPqC _3Mi9q9 _1YbC5u" @click="payhandler"><span>确认支付</span><span> ¥</span>{{reward_info.money}}</button>
   </div>
  </div>

   <Footer></Footer>
  </div>
</template>

<script>
    import Header from "./common/Header";
    import Footer from "./common/Footer";
    export default {
        name: "Article",
        data(){
            return {
                token: "",
                article_id: 0,
                is_show_reward_window:false,
                article: {
                    user:{},
                    collection:{},
                },
                reward_list:[2,5,10,20,50,100],
                pay_type_list: ["支付宝","余额支付"],
                reward_info:{
                    money: 2,
                    content:"",
                    pay_type:"支付宝",
                }
            }
        },
       
            payhandler(){
                // 支付处理
                
            }
        },
        components:{
          Header,
          Footer,
        }
    }
</script>

服务端集成支付接口实现打赏的功能

支付接口,可以实现网络转账。
很多的第三方支付接口:
国外:万事达,applePay,PayPAl,Visa,八达通,西联[邮政汇款]
国内:支付宝,微信,京东钱包,百度钱包,贝宝[PayPal中国版]

支付宝

支付宝开发平台登录

支付宝的申请需要企业资质,但是我们作为开发者可以使用支付宝提供的测试账号先开发功能,将来调整账号即可用于公司项目的正式运营。

地址:https://openhome.alipay.com/platform/developerIndex.htm

沙箱环境

真实的支付宝网关:   https://openapi.alipay.com/gateway.do
	
沙箱的支付宝网关:   https://openapi.alipaydev.com/gateway.do

支付宝开发者文档

电脑网站支付流程

【前后端不分离】时序图[ 时间顺序流程图 ]

【前后端分离】

RSA算法,属于非对称加密。
密钥成对生成的。分公钥和私钥。

两种场景:

签名:私钥签名,公钥验签

加密:公钥加密,私钥解密

A给B发信息msg,B要确认是A的,并且内容没有发生改变,那么A在自己的本地生成公私钥键值对(A私钥和A公钥),A将公钥给B,B也在自己的本地生成公私钥(B私钥和B公钥),B将B公钥给A,那么A给B发送msg时,先通过B的公钥进行msg数据的加密,然后再通过A的A私钥进行签名,那么B通过A公钥对msg的签名进行验签(只有A公钥才能对A私钥的签名进行校验),验签没有问题之后,在通过B的私钥对msg进行解密(只有B的私钥才能对通过B公钥加密的数据进行解密)。这就是大致原理。

开发支付功能

新建payments应用

cd renranapi/apps
python ../../manage.py startapp payments

注册子应用settings/dev.py

INSTALLED_APPS = [
	。。。。
    'payments',
]

总路由: renranapi/urls.py

path('payments/', include('payments.urls')),

子路由:payments/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('collection/', views.ArticleCollectionView.as_view()),
]

配置秘钥

1. 生成应用的私钥和公钥

下载对应系统的秘钥生成工具: https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1

windows操作系统

生成如下,安装软件时需要管理员身份来安装.

1566548916758

Linux系统

使用openssl命令,生成如下:

cd renranapi/apps/payments/
# 新建文件,
mkdir keys
cd keys
openssl
# 在keys目录下生成RSA算法私钥--app_private_key.pem
OpenSSL> genrsa -out app_private_key.pem 2048                 # 根据私钥导出公钥        
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem  
OpenSSL> exit

应用公钥复制粘贴到支付宝网站页面中.

点击修改以后,粘贴进去

1554192143494

2. 保存应用私钥文件

在payments应用中新建keys目录,用来保存秘钥文件。

将应用私钥文件app_private_key.pem复制到payment/keys目录下。

windows系统生成的私钥必须在上下两行加上以下标识:

-----BEGIN RSA PRIVATE KEY-----
私钥
-----END RSA PRIVATE KEY-----

3. 保存支付宝公钥到项目中

在payments/key目录下新建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

后台处理

1.配置支付宝配置信息

settings/dev.py

# 支付宝打赏配置信息
ALIPAY_CONFIG = {
    # "gateway_url": "https://openapi.alipay.com/gateway.do?", # 真实支付宝网关地址
    "gateway_url": "https://openapi.alipaydev.com/gateway.do?", # 沙箱支付宝网关地址
    "appid": "2021000117635432",
    "app_notify_url": None,
    "app_private_key_path": os.path.join(BASE_DIR, "apps/payments/keys/app_private_key.pem"), # 私钥
    "alipay_public_key_path": os.path.join(BASE_DIR, "apps/payments/keys/alipay_public_key.pem"), # 支付宝公钥
    "sign_type": "RSA2", # 加密算法
    "debug": False,
    "return_url": "http://www.moluo.net:8080/wallet", # 同步回调地址
    "notify_url": "http://api.renran.cn:8000/payments/alipay/result/", # 异步结果通知,必须是真实能外部访问的网站
    
}

2.创建打赏模型

1.修改用户模型: users/models.py

用户模型新增money字段,表示作者用户接收别人打赏的资金资产。

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
	....
    money = models.DecimalField(max_digits=8,decimal_places=2,default=0, verbose_name="资金")

2.创建打赏模型,保存打赏记录 :

payments/models.py

from django.db import models
from renranapi.utils.models import BaseModel
from users.models import User
from article.models import Article

class Reward(BaseModel):
    REWARD_OPT = (
        (0, "支付宝"),
        (1, "余额"),
    )
    STATUS_OPT = (
        (0, "未付款"),
        (1, "已付款"),
        (2, "已取消"),
        (3, "超时取消"),
    )
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="打赏用户")
    money = models.DecimalField(decimal_places=2, max_digits=6, verbose_name="打赏金额")
    article = models.ForeignKey(Article, on_delete=models.DO_NOTHING, verbose_name="文章")
    status = models.SmallIntegerField(default=0,choices=STATUS_OPT, verbose_name="打赏状态")
    trade_no = models.CharField(max_length=255, null=True, blank=True, verbose_name="流水号")
    out_trade_no = models.CharField(max_length=255, null=True, blank=True, verbose_name="支付平台返回的流水号")
    reward_type = models.SmallIntegerField(default=0,choices=REWARD_OPT, verbose_name="打赏类型")
    message = models.TextField(null=True,blank=True, verbose_name="打赏留言")

    class Meta:
        db_table = "rr_user_reward"
        verbose_name = "打赏记录"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user.nickname+"打赏了"+self.article.user.nickname+"的文章《" +self.article.name+"》"+self.money+"元"

数据库迁移指令:

python manage.py makemigrations
python manage.py migrate

注册模型到xadmin中,创建adminx.py,代码

import xadmin

from .models import Reward
class RewardModelAdmin(object):
    plist_display = ["id"] # 后台显示字段
xadmin.site.register(Reward,RewardModelAdmin)

3.后台支付接口

路由:payments/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("alipay/", views.AliPayAPIViewSet.as_view({"post":"post",'get':'check_result'})),
]

视图: payments/views.py

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from alipay import AliPay  # 引入支付宝类
from alipay.utils import AliPayConfig

from django.conf import settings # 引入配置文件
from .models import Reward
import datetime,random
from django.db import transaction
import logging
logger = logging.getLogger('django')

# 文章打赏
class AliPayAPIViewSet(ViewSet):
    # 登录认证
    permission_classes = [IsAuthenticated, ]

    # 实例化支付宝对象
    def alipay(self):
        alipay = AliPay(
            appid=settings.ALIPAY_CONFIG.get('appid'),
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(settings.ALIPAY_CONFIG.get('app_private_key_path')).read(),
            # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIPAY_CONFIG.get('alipay_public_key_path')).read(),
            sign_type=settings.ALIPAY_CONFIG.get('sign_type'),  # RSA 或者 RSA2
            debug = settings.ALIPAY_CONFIG.get('debug'),  # 默认False
            verbose = False,  # 输出调试数据
            config = AliPayConfig(timeout=15),  # 可选, 请求超时时间
        )
        return alipay

    def post(self,request):
        # 支付金额,支付方式,留言...
        user = request.user
        article_id = request.data.get('article_id')
        money = request.data.get('money')
        pay_type = request.data.get('pay_type')
        liuyan = request.data.get('liuyan')

        # 随机流水号
        trade_no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ("%06d" % user.id) + ("%06d" % random.randint(1, 999999))

        if pay_type == 0:  # 支付宝打赏
            # 实例化对象
            alipay = self.alipay()
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=trade_no, # 订单流水号
                total_amount=money,
                subject='荏苒打赏', # 订单标题
                return_url=settings.ALIPAY_CONFIG.get('return_url'),
                notify_url=settings.ALIPAY_CONFIG.get('notify_url'),  # 可选, 不填则使用默认notify url
            )

            # 拼接支付宝页面路径
            alipay_url = settings.ALIPAY_CONFIG.get('gateway_url') + order_string

            # 创建打赏记录
            Reward.objects.create(
                user=user,
                money=float(money),
                article_id=article_id,
                status=0,
                trade_no=trade_no,
                reward_type=pay_type,
                message=liuyan,
            )

            return Response({'alipay_url':alipay_url})

    # 处理支付宝支付成功后,同步结果通知(get)
    def check_result(self,request):
        # 验证返回的数据
        data = request.query_params.dict()
        # 获取验证信息码
        signature = data.pop("sign")
        alipay = self.alipay()
        success = alipay.verify(data, signature)

        if success:
            # 验证成功,更改订单
            with transaction.atomic():
                # 设置事务的回滚点,用于指定在事务失败时,在哪一部分的SQL语句无效
                sid = transaction.savepoint()
                try:
                    obj = Reward.objects.get(trade_no=data.get('out_trade_no'),status=0)
                    # 1.修改订单状态为已付
                    obj.status = 1
                    obj.save()

                    # 2.保存支付宝订单号
                    obj.out_trade_no = data.get('trade_no')
                    obj.save()

                    # 3.文章被打赏次数+1
                    article_obj = obj.article
                    article_obj.reward_count += 1
                    article_obj.save()

                    # 4.被打赏用户金额增加
                    user_obj = article_obj.user
                    # Decimal类型和float类型不能直接相加
                    # user_obj.money += float(data.get('total_amount'))
                    user_money = user_obj.money
                    new_money = float(user_money) + float(data.get('total_amount'))
                    user_obj.money = new_money

                    user_obj.save()
                    return Response({'msg':'ok'})
                except:
                    transaction.savepoint_rollback(sid) # 回滚
                    # 记录日志
                    logger.error('订单状态修改失败!')
                    return Response({'error':'订单状态修改失败!'},status=500)


                
                
// 支付宝成功支付异步处理结果,暂时测试不了,和同步流程一样

    def notify_result(self,request):
        """支付宝异步结果处理"""
        data = request.data.dict()
        signature = data.pop("sign")
        alipay = self.get_alipay()
        success = alipay.verify(data, signature)
        if success:
            """支付结果处理"""
            # 开启ORM的mysql事务的自动提交,在with语句范围内,所有的SQL会全部被事务控制,要么一起提交,要么一起不提交
            with transaction.atomic():
                # 设置事务的回滚点,用于指定在事务失败时,在哪一部分的SQL语句无效
                save_id = transaction.savepoint()
                try:
                    # 修改打赏记录的状态为已付款
                    reward = Reward.objects.get(
                        trade_no=data.get("out_trade_no"),
                        status=0,
                    )
                    reward.status = 1
                    reward.save()

                    # 增加文章的打赏人数
                    article = Article.objects.get(pk=reward.article.id)
                    article.reward_count += 1
                    article.save()
                    print(article.user.money)
                    print(reward.money)
                    # 给用户资产增加打赏的资金
                    article.user.money= int((article.user.money + reward.money) * 100) / 100
                    article.user.save()

                    # 参考打赏,实现一个资金流水记录[专门显示在钱包位置]

                except Reward.DoesNotExist:
                    transaction.savepoint_rollback(save_id)
                    return Response("当前打赏已经处理完成!请不要重复提交!")
                except:
                    transaction.savepoint_rollback(save_id)
                    return Response({"message": "支付结果处理有误!"})

                return Response({"message":"支付处理成功!"})
        else:
            return Response({"message": "支付失败!"}, status=status.HTTP_400_BAD_REQUEST)


客户端处理

1.客户端实现点击打赏请求

Article.vue

<template>
  <div class="_21bLU4 _3kbg6I" @click="boss">
   <Header></Header>
   <div class="_3VRLsv" role="main">
    <div class="_gp-ck">
     <section class="ouvJEz">
      <h1 class="_1RuRku">{{article_detail_data.title}}</h1>
      <div class="rEsl9f">
       <div class="_2mYfmT">
        <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_13D2Eh" :src="article_detail_data.user.avatar" alt="" /></a>
        <div style="margin-left: 8px;">
         <div class="_3U4Smb">
          <span class="FxYr8x"><a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer">{{article_detail_data.user.nickname}}</a></span>
          <button data-locale="zh-CN" type="button" class="_3kba3h _1OyPqC _3Mi9q9 _34692-"><span>关注</span></button>
         </div>
         <div class="s-dsoj">
          <time datetime="2020-01-08T12:01:00.000Z">{{article_detail_data.pub_date}}</time>
          <span>字数 {{article_detail_data.content?article_detail_data.content.length:0}}</span>
          <span>阅读 {{article_detail_data.read_count}}</span>
         </div>
        </div>
       </div>
      </div>
      <article class="_2rhmJa" v-html="article_detail_data.render">
       </article>
      <div></div>
      <div class="_1kCBjS">
       <div class="_18vaTa">
        <div class="_3BUZPB">
         <div class="_2Bo4Th" role="button" tabindex="-1" aria-label="给文章点赞">
          <i aria-label="ic-like" class="anticon">
           <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
            <use xlink:href="#ic-like"></use>
           </svg></i>
         </div>
         <span class="_1LOh_5" role="button" tabindex="-1" aria-label="查看点赞列表">{{article_detail_data.like_count}}<i aria-label="icon: right" class="anticon anticon-right">
           <svg viewbox="64 64 896 896" focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true">
            <path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"></path>
           </svg></i></span>
        </div>
        <div class="_3BUZPB">
         <div class="_2Bo4Th" role="button" tabindex="-1">
          <i aria-label="ic-dislike" class="anticon">
           <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
            <use xlink:href="#ic-dislike"></use>
           </svg></i>
         </div>
        </div>
       </div>
       <div class="_18vaTa">
        <a class="_3BUZPB _1x1ok9 _1OhGeD" href="/nb/38290018" target="_blank" rel="noopener noreferrer"><i aria-label="ic-notebook" class="anticon">
          <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
           <use xlink:href="#ic-notebook"></use>
          </svg></i><span>{{article_detail_data.collection.name}}</span></a>
        <div class="_3BUZPB ant-dropdown-trigger">
         <div class="_2Bo4Th">
          <i aria-label="ic-others" class="anticon">
           <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
            <use xlink:href="#ic-others"></use>
           </svg></i>
         </div>
        </div>
       </div>
      </div>
      <div class="_19DgIp" style="margin-top:24px;margin-bottom:24px"></div>
      <div class="_13lIbp">
       <div class="_191KSt">
        &quot;小礼物走一走,来荏苒关注我&quot;
       </div>
       <button @click.stop="show_reward" type="button" class="_1OyPqC _3Mi9q9 _2WY0RL _1YbC5u"><span>赞赏支持</span></button>
       <span class="_3zdmIj">还没有人赞赏,支持一下</span>
      </div>
      <div class="d0hShY">
       <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_27NmgV" :src="article_detail_data.user.avatar" alt="  " /></a>
       <div class="Uz-vZq">
        <div class="Cqpr1X">
         <a class="HC3FFO _1OhGeD" href="/u/a70487cda447" title="書酱" target="_blank" rel="noopener noreferrer">{{article_detail_data.user.nickname}}</a>
         <span class="_2WEj6j" title="你读书的样子真好看。">{{article_detail_data.title}}</span>
        </div>
        <div class="lJvI3S">
         <span>总资产0</span>
         <span>共写了78.7W字</span>
         <span>获得6,072个赞</span>
         <span>共1,308个粉丝</span>
        </div>
       </div>
       <button data-locale="zh-CN" type="button" class="_1OyPqC _3Mi9q9"><span>关注</span></button>
      </div>
     </section>
     <div id="note-page-comment">
      <div class="lazyload-placeholder"></div>
     </div>
    </div>
    <aside class="_2OwGUo">
     <section class="_3Z3nHf">
      <div class="_3Oo-T1">
       <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_3T9iJQ" :src="article_detail_data.user.avatar" alt="" /></a>
       <div class="_32ZTTG">
        <div class="_2O0T_w">
         <div class="_2v-h3G">
          <span class="_2vh4fr" title="書酱"><a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer">{{article_detail_data.user.nickname}}</a></span>
         </div>
         <button data-locale="zh-CN" type="button" class="tzrf9N _1OyPqC _3Mi9q9 _34692-"><span>关注</span></button>
        </div>
        <div class="_1pXc22">
         总资产0
        </div>
       </div>
      </div>
      <div class="_19DgIp"></div>
     </section>
     <div>
      <div class="">
       <section class="_3Z3nHf">
        <h3 class="QHRnq8 QxT4hD"><span>推荐阅读</span></h3>
        <div class="cuOxAY" role="listitem">
         <div class="_3L5YSq" title="这些话没人告诉你,但必须知道的社会规则">
          <a class="_1-HJSV _1OhGeD" href="/p/a3e56a0559ff" target="_blank" rel="noopener noreferrer">这些话没人告诉你,但必须知道的社会规则</a>
         </div>
         <div class="_19haGh">
          阅读 5,837
         </div>
        </div>

       </section>
      </div>
     </div>
    </aside>
   </div>

<!--  打赏弹窗-->
   <div class="_23ISFX-body" v-if="is_show_reward_window" @click.stop="is_show_reward_window=true">
   <div class="_3uZ5OL">
    <div class="_2PLkjk">
     <img class="_2R1-48" src="https://upload.jianshu.io/users/upload_avatars/9602437/8fb37921-2e4f-42a7-8568-63f187c5721b.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/100/h/100/format/webp" alt="" />
     <div class="_2h5tnQ">
      给作者送糖
     </div>
    </div>
    <div class="_1-bCJJ">
     <div class="LMa6S_ el-icon-lollipop" :class="reward_info.money==num?'_1vONvL':''" @click="reward_info.money=num" v-for="(num,index) in reward_list" :key="index"><span>{{num}}</span></div>
    </div>
    <textarea v-model="liuyan" class="_1yN79W" placeholder="给Ta留言..."></textarea>
    <div class="_1_B577">
     选择支付方式
    </div>
    <div class="_1-bCJJ">
     <div class="LMa6S_ _3PA8BN " :class="reward_info.pay_type==type?'_1vONvL':''" @click="reward_info.pay_type=type" v-for="type in pay_type_list"><span>{{type}}</span></div>
    </div>
    <button type="button" class="_3A-4KL _1OyPqC _3Mi9q9 _1YbC5u" @click="payhandler"><span>确认支付</span><span> ¥</span>{{reward_info.money}}</button>
   </div>
  </div>

   <Footer></Footer>
  </div>
</template>

<script>
    import Header from "./common/Header";
    import Footer from "./common/Footer";
    export default {
      name: "Article",
      components:{
        Header,
        Footer,
      },
      data(){
        return{
          token:'',
          article_detail_data:{
            user:{},
            collection:{},
          }, // 存放文章详情数据
          is_show_reward_window:false, // 是否显示支付弹窗
          reward_list:[2,5,10,20,50,100],// 支付金额列表
          pay_type_list: ["支付宝","微信"],
          liuyan:'', // 打赏留言
          reward_info:{   // 打赏信息
              money: 2,
              content:"",
              pay_type:"支付宝",
          },
        }
      },
      created() {
        this.token = this.$settings.check_user_login(this);
        this.get_article_detail()
      },
      methods:{
        // 点击确认支付
        payhandler(){
          this.$axios.post(`${this.$settings.host}/payments/alipay/`,{
            article_id : this.$route.params.id,
            money:this.reward_info.money,
            pay_type:0, // 后台0--支付宝,1--微信
            liuyan:this.liuyan,
          },{
            headers:{
                Authorization: "jwt " + this.token,
              }
          }).then((res)=>{
            // 请求成功跳转到支付宝页面
            location.href = res.data.alipay_url
            this.$message.success('请求成功!')
          }).catch((error)=>{
            this.$message.error('支付失败!')
          })
        },

        // 最外层标签点击事件
        boss(){
          this.is_show_reward_window = false
        },

        // 点击打赏,弹出打赏弹窗
        show_reward(){
          this.is_show_reward_window = true
        },

        // 获取文章详细信息
        get_article_detail(){
          this.$axios.get(`${this.$settings.host}/article/article_detail/${this.$route.params.id}/`,{
            headers:{
                Authorization: "jwt " + this.token,
              }
          }).then((res)=>{
            this.article_detail_data = res.data;
            this.$message.success('获取文章详情数据成功')
          }).catch((error)=>{
            this.$message.error('获取文章详情数据失败!')
          })
        }
      },

    }
</script>

2.用户支付完成以后的支付结果处理

客户端接收支付宝跳转发送回来的同步结果参数,并发起请求服务端的同步处理结果API接口

Wallet.vue

<template>

</template>

<script>
    export default {
        name: "Wallet",
        data(){
          return {
            token:"",
          }
        },
        created() {
          this.token = this.$settings.check_user_login(this);
          // 把支付宝的同步结果通知转发给服务端
          this.get_pay_result();
        },
        methods:{
          get_pay_result(){
            // 判断是否是从支付页面返回
            // $route.query 获取支付宝返回路径的查询参数数据 -- out_trade_no支付宝订单流水号
            if(this.$route.query.out_trade_no){
              // 转发支付结果到服务端 -- location.search获取返回路径的所有查询参数
              this.$axios.get(`${this.$settings.Host}/payments/alipay/`+location.search,{
                  headers:{
                      Authorization: "jwt " + this.token,
                  }
              }).then((res)=>{
                this.$message.success('支付成功')
              }).catch((error)=>{
                this.$message.error("支付结果处理有误!请及时联系客服工作人员!");
              });
            }
          }
        }
    }
</script>

<style scoped>

</style>

路由,代码:

import Wallet from "@/components/Wallet"
      {
       name:"Wallet",
       path:"/wallet",
       component: Wallet,
     },

原文地址:https://www.cnblogs.com/jia-shu/p/14677196.html