当前位置:   article > 正文

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_微信native支付springboot实现源码

微信native支付springboot实现源码

SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功

需求:
如图,实现流程:选择一个课程,点击支付,然后弹出一个支付二维码,用户扫描二维码进行支付。
在这里插入图片描述

签名和验签的理解:

商户端发送一个支付请求给微信支付平台:
商户端需要将请求中的一些敏感参数,通过微信支付平台提供的平台证书的公钥,进行加密,变成密文,然后再对整个请求进行签名加密

微信支付平台接收到请求后:
1、需要先对签名进行验签,作用就是判断发过来的请求是否被篡改过。
2、如果没篡改过,就从该请求中获取数据密文ciphertext(就是加密了的那些参数存放的地方),再用微信平台自己的私钥(对称加密秘钥),对请求中的数据密文进行解密,解密成明文,然后使用该参数数据进行业务操作。

反过来,微信支付平台发送请求到商户端,也是一样的操作

如何加解密敏感信息
在这里插入图片描述
在这里插入图片描述

签名生成流程

签名验证流程

基础支付API V3

1、引入支付参数

这些支付参数是视频制作者提供的
这是个配置文件

如图:这个 wxpay.private-key-path=apiclient_key.pem 是商户私钥文件路径,可以通过这个路径获取私钥文件
在这里插入图片描述

参数解释

1-1、商户号:

就是商家的账号
属于学习视频的截图:
在这里插入图片描述

1-2、商户API证书序列号:

在商户平台申请的API证书,有私钥和证书,证书里面封装了公钥
在这里插入图片描述

1-3、商户私钥文件

商户的私钥文件加载到应用程序当中的目的主要是为了做签名,用私钥将请求进行签名,然后发请求的信息发送给微信的服务器端,微信的服务器端就会根据发来的请求中的 商户API证书的序列号 这个参数找到对应的证书,然后再从这个证书中解密出我们的公钥,然后用这个公钥对这个发来的加密的请求进行验签。

(公钥就存放在加密了的证书中)

这就是一个请求发送和接收的过程,对应的是一个签名和验签的过程。

签名:就是将请求加密
验签:就是用来判断这个请求有没有被篡改过,验签通过就是没被篡改过

现在这个是商户私钥的路径,通过这个路径获取商户私钥文件

在这里插入图片描述

在这里插入图片描述

1-4、APIv3密钥

这个密钥是一个对称加密的密钥

在这里插入图片描述

1-5、APPID

在申请商户号的时候,同时申请的微信公众号,这个就是微信公众号的id

在这里插入图片描述

1-6、微信服务器地址

远程向这个地址发起调用

向微信发起请求

在这里插入图片描述

1-7、接收结果通知地址

微信向商户端发起请求

每个人的地址都是不一样的,记得修改

内网穿透用的
在这里插入图片描述

2、读取支付参数

创建一个配置文件来读取支付参数配置文件里面的数据

这个方法可以读取到配置文件的值。

在这里插入图片描述

也可以通过这种方式来获取配置文件中的属性值,这个是其他的代码,仅作记录

在这里插入图片描述

2-1、测试支付参数的获取

在这里插入图片描述

能成功拿到配置文件的里面的属性值

在这里插入图片描述

3、配置 Annotation Processor

可以帮助我们生成自定义配置的元数据信息,让配置文件和Java代码之间的对应参数可以自动定位,方

便开发。

3-1、原因:

如图,在idea 中,没有把这个wxpay 看成是一个spring的配置文件,虽然不影响程序运行,但是却少了很多功能,比如自动定位,就是点击配置文件的属性名,能自动定位到 WxPayConfig 配置文件的对应字段去。

在这里插入图片描述

在这里插入图片描述

3-2、方法:

实现配置文件能够自动定位的操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、加载商户私钥

4-1、复制商户私钥

把商户私钥复制到项目根目录下:

在这里插入图片描述

4-2、引入SDK

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient
  • 1
  • 2
  • 3

我们可以使用官方提供的 SDK,帮助我们完成开发。实现了请求签名的生成和应答签名的验证
在这里插入图片描述

微信支付的SDK 依赖

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.3.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

4-3、获取商户私钥

因为我们的私钥是存在一个文件的(apiclient_key.pem),所以用第一个示例方法

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient

在这里插入图片描述
在 WxPayConfig 中写一个获取商户私钥文件的方法
在这里插入图片描述

4-4、测试商户私钥的获取

在 PaymentDemoApplicationTests 测试类中添加如下方法,测试私钥对象是否能够获取出来。

(将前面的方法改成public的再进行测试)

在测试类里面测试

在这里插入图片描述

5、获取签名验证器和HttpClient

5-1、APIv3证书与密钥使用说明

https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay3_0.shtml

在这里插入图片描述

5-2、获取签名验证器

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient (定时更新平台证书功能)

平台证书:平台证书封装了微信的公钥,商户可以使用平台证书中的公钥进行验签。

签名验证器:帮助我们进行验签工作,我们单独将它定义出来,方便后面的开发。

下图是学习视频的访问该网址的代码,但是现在打开该网址的代码已经改变了。

在这里插入图片描述

在这里插入图片描述

5-3、获取HttpClient对象

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient (定时更新平台证书功能)

HttpClient 对象:是建立远程连接的基础,我们通过SDK创建这个对象

**HttpClient对象作用: **通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新。

在这里插入图片描述

5-4、WxPayConfig 代码(签名和验签)

package cn.ljh.paymentdemo.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;


@Configuration
@PropertySource("classpath:wxpay.properties") //读取配置文件
@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
public class WxPayConfig
{

    // 商户号
    private String mchId;

    // 商户API证书序列号
    private String mchSerialNo;

    // 商户私钥文件的路径
    private String privateKeyPath;

    // APIv3密钥
    private String apiV3Key;

    // APPID
    private String appid;

    // 微信服务器地址
    private String domain;

    // 接收结果通知地址
    private String notifyDomain;


    /**
     * 获取商户的私钥文件
     *
     * @param fileName 私钥文件的路径
     * @return PrivateKey
     */
    public PrivateKey getPrivateKey(String fileName)
    {
        try
        {
            return PemUtil.loadPrivateKey(
                    new FileInputStream(fileName));
        } catch (FileNotFoundException e)
        {
            throw new RuntimeException("私钥文件不存在", e);
        }
    }

    /**
     * 获取签名验证器
     *
     * @return 签名验证器
     */
    @Bean
    public ScheduledUpdateCertificatesVerifier getVerifer()
    {

        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);

        //私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);

        //身份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

        // 使用定时更新的签名验证器,不需要传入证书
        ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                wechatPay2Credentials,
                apiV3Key.getBytes(StandardCharsets.UTF_8));

        return verifier;

    }

    /**
     * 获取HttpClient 请求对象:是建立远程连接的基础,我们通过SDK创建这个对象
     * 通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新
     *
     * @param verifier 签名验证器
     * @return HttpClient 请求对象,会自动的处理签名和验签,并进行证书自动更新
     */
    @Bean
    public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier)
    {

        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);
        //用于构造HttpClient
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier));

        // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient

        // 通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新
        CloseableHttpClient httpClient = builder.build();

        return httpClient;
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123

6、API字典和相关工具

6-1、API 列表

https://pay.weixin.qq.com/docs/merchant/development/interface-rules/introduction.html

在这里插入图片描述

我们的项目中要实现以下所有API的功能。
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_3.shtml

Native支付API列表

在这里插入图片描述

6-2、接口规则

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay2_0.shtml

微信支付 APIv3 使用 JSON 作为消息体的数据交换格式。

如上图,因为使用JSON作为数据交互的格式,不再使用XML , 所以在项目里面添加这个json处理的依赖

在这里插入图片描述

6-3、定义枚举

为了开发方便,我们预先在项目中定义一些枚举。枚举中定义的内容包括接口地址,支付状态等信息。

就是我们去调用支付的一些 商户订单号查询订单、关闭订单、退款申请 的接口,这些都是微信支付平台提供的接口,因为会经常调用,所以把这些接口地址、状态等直接封装成枚举,方便调用。

在这里插入图片描述

在这里插入图片描述

6-4、添加工具类

将资料文件夹中的 util 目录复制到源码目录中,我们将会使用这些辅助工具简化项目的开发

在这里插入图片描述

7、调用Native下单API

7-1、需求:

如图,选择一个课程,点击支付,然后弹出一个支付二维码,用户扫描二维码进行支付。
在这里插入图片描述

7-2、native 支付流程图:

在这里插入图片描述

完整流程
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_4.shtml

在这里插入图片描述

7-3、Native下单

7-3-1、需求流程分析:

生成订单–>调用统一下单的API,生成支付二维码–>生成预支付交易–>返回预支付交易链接
在这里插入图片描述

下单的接口说明
https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html

在这里插入图片描述

7-3-2、代码:
7-3-2-1、接口相关数据

由官方指定的一些要求和示例

【服务端】Native下单 的官方示例代码

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_2.shtml

在这里插入图片描述

native下单的接口说明

https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html

在这里插入图片描述

要封装哪些请求参数,在这里看
在这里插入图片描述

7-3-2-2、controller

在这里插入图片描述

7-3-2-3、Service

在这里插入图片描述

7-3-2-4、Impl

创建订单,调用native支付接口

这个是封装支付接口要的url:
在这里插入图片描述

这里才是执行调用该支付接口的方法:签名、验签和调用支付接口
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7-3-2-5、测试结果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

7-3-2-6、成功真实支付

在这里插入图片描述

7-3-4、后端完整代码

一些配置文件、枚举类就没列出来了,太多了

WxPayController
package cn.ljh.paymentdemo.controller;

import cn.ljh.paymentdemo.service.WxPayService;
import cn.ljh.paymentdemo.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

@CrossOrigin //跨域
@RestController
@RequestMapping("/api/wx-pay")
@Api(tags = "网站微信支付API") //swagger 注解
@Slf4j
public class WxPayController
{
    @Resource
    private WxPayService wxPayService;
    
    //调用统一下单API,生成支付二维码的链接和订单号
    //swagger注解
    @ApiOperation("调用统一下单API,生成支付二维码")
    @PostMapping("/native/{productId}")
    public R nativePay(@PathVariable Long productId) throws Exception
    {
        log.info("发起支付请求");
        //返回支付二维码的链接和订单号
        Map<String,Object> map = wxPayService.nativePay(productId);
        return R.ok().setData(map);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
WxPayService
package cn.ljh.paymentdemo.service;

import java.util.Map;

public interface WxPayService
{
    //调用统一下单API,生成支付二维码的链接和订单号
    Map<String, Object> nativePay(Long productId) throws  Exception;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
WxPayServiceImpl
package cn.ljh.paymentdemo.service.impl;

import cn.ljh.paymentdemo.config.WxPayConfig;
import cn.ljh.paymentdemo.entity.OrderInfo;
import cn.ljh.paymentdemo.enums.OrderStatus;
import cn.ljh.paymentdemo.enums.wxpay.WxApiType;
import cn.ljh.paymentdemo.enums.wxpay.WxNotifyType;
import cn.ljh.paymentdemo.service.WxPayService;
import cn.ljh.paymentdemo.util.OrderNoUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


//创建订单,调用 Native 支付接口
@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService
{
    @Resource
    private WxPayConfig wxPayConfig;

    /* 原本应该注 入WxPayConfig 这个类,然后调用 getWxPayClient() 方法获取 HttpClient请求对象
     * 但是因为 getWxPayClient() 方法加了@Bean注解,交给了spring容器管理,所以项目启动的时候就会执行这个方法,
     * 就会存在返回值为 CloseableHttpClient 类型的 HttpClient请求对象
     * 所以这里可以直接注入这个 CloseableHttpClient 对象
     */
    @Resource
    private CloseableHttpClient wxPayClient;

    /**
     * 创建订单,调用 Native 支付接口
     *
     * @param productId 商品id
     * @return code_url 和 订单号
     * @throws Exception
     */
    //调用统一下单API,生成支付二维码的链接和订单号
    @Override
    public Map<String, Object> nativePay(Long productId) throws Exception
    {
        log.info("生成订单.....");

        //生成订单
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setTitle("test"); //订单标题
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //生成订单号
        orderInfo.setProductId(productId); //商品id
        orderInfo.setTotalFee(1); //单位是:分
        orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType()); //支付状态
        //TODO: 需要将这个订单存到数据库

        /*
         * 官方提供的 Native下单 接口
         * 支持商户:【普通商户】
         * 请求方式:【POST】/v3/pay/transactions/native
         * 请求域名:【主域名】https://api.mch.weixin.qq.com
         * "https://api.mch.weixin.qq.com/v3/pay/transactions/native" 改成
         * wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType())
         */

        log.info("调用统一下单API.....");

        //调用统一下单API---拷贝官网的实例代码进行修改---统一下单的接口地址
        HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));

        // 请求body参数---------调用接口需要的参数
        Gson gson = new Gson();
        //数据类型不固定,所以就不写泛型了
        Map paramsMap = new HashMap();
        //设置参数 --- 根据官网要求设置对应的参数
        paramsMap.put("appid", wxPayConfig.getAppid()); //公众号ID
        paramsMap.put("mchid", wxPayConfig.getMchId()); //直连商户号
        paramsMap.put("description", orderInfo.getTitle()); // 商品描述
        paramsMap.put("out_trade_no", orderInfo.getOrderNo()); //商户订单号
        paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType())); //通知地址
        //订单金额有两个参数--嵌套数据
        Map amountMap = new HashMap();
        amountMap.put("total", orderInfo.getTotalFee()); //总金额
        amountMap.put("currency", "CNY"); //货币类型
        paramsMap.put("amount", amountMap); // 订单金额

        //将参数转成字符串
        String jsonParams = gson.toJson(paramsMap);

        log.info("支付的请求参数:" + jsonParams);

        //把参数设置到请求体当中
        StringEntity entity = new StringEntity(jsonParams, "utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        //希望得到的响应类型
        httpPost.setHeader("Accept", "application/json");

        //完成签名并执行请求
        CloseableHttpResponse response = wxPayClient.execute(httpPost);

        //这些就是对调用下单方法的响应结果的处理了
        try
        {
            //字符串形式的响应体
            String bodyAsString = EntityUtils.toString(response.getEntity());
            //响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200)
            { //处理成功
                System.out.println("成功, 返回结果  = " + bodyAsString);
            } else if (statusCode == 204)
            { //处理成功,无返回Body
                System.out.println("成功");
            } else
            {
                System.out.println("下单失败, 响应码 = " + statusCode + ", 返回结果 = " + bodyAsString);
                throw new IOException("请求失败 request failed");
            }
            //如果下单成功,获取响应结果,   gson.fromJson()用于将 JSON 字符串转换为 Java 对象
            Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
            //从返回的结果中获取二维码的url, 从官网看出 code_url 是 二维码的key
            String codeUrl = resultMap.get("code_url");
            //创建一个url和订单号的返回值
            Map<String, Object> map = new HashMap<>();
            map.put("codeUrl", codeUrl);
            map.put("orderNo", orderInfo.getOrderNo());
            return map;
        } finally
        {
            response.close();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141

8、前端代码分析

在这里插入图片描述

8-1、获取商品列表数据分析

1、前端调用后端接口流程

后端返回的数据,主要的商品列表数据存在属性名为 productList 中,

前端的 created(){} 是页面加载的时候自动执行,

productApi 这个类里面有一个 list() 方法,

list()方法有url,一看就是在执行远程调用,就是在调用后端的 url: ‘/api/product/list’ 接口

then 就是回调函数,在then 方法中取出后端的响应数据,response 就是后端响应到前端的数据

response.data.productList 就是获取后端返回来的属性名为 productList 的值

data 就是response响应中的结果数据,因为response 还有其他一些数据。
在这里插入图片描述

2、一些值赋予过程

this.productList 就是把获取到的值设置到 data 里面的 productList: []
在这里插入图片描述

遍历的值就是从data里面获取的

在这里插入图片描述

3、模块调用分析

基于上面继续分析:

import 引入模块分析,如图,也可以理解为在 index.vue 中调用 productApi 这个模块

在这里插入图片描述

然后product.js 调用 request.js ,

request.js 引入 axios

如图:在 product.js 中,url 是调用后端的接口的具体路径,但是明显还少了主机地址,

就是http://localhost:端口号这些主机地址。

所以需要引入 request 模块,在这个request 模块中就初始化了所有远程ajax调用需要的请求的主机地址

然后为什么能实现ajax远程调用呢?

是因为在request模块中,又引入了 axios 模块,这个模块就是在vue中专门做发送ajax 请求的模块。

axios 模块是从哪里来的呢?

axios 是在 package.json 里面引入的,相当于 java 在 pom.xml 文件中引入所需依赖一样。

因为在 package.json 引入了 “axios”: “^0.24.0” 这个专门发送ajax的工具,所以前端才能实现ajax 调用,

所以可以在 request.js 中创建 axios 实例。

在这里插入图片描述

如果远程调用数据失败,那么处理的方式就是这个拦截器。
在这里插入图片描述

8-2、选择课程的点击事件分析

在这里插入图片描述

8-3、支付类型和确认支付分析

都是点击触发点击事件

在这里插入图片描述

远程调用都是一样的,跟获取商品列表数据一样

在这里插入图片描述

在这里插入图片描述

8-4、前端支付二维码的展示分析

在这里插入图片描述

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/874136
推荐阅读
相关标签
  

闽ICP备14008679号