QA快速掌握:VUE Fetch API提效工具实践

1.背景

1.用券场景多,建券频繁,用到优惠券的场景:下单、到店礼、预约报名、满返满赠、抽奖
2.建券发券耗时长,平均建券发券时间在3分钟左右

2.目标

1.提高效率把重复的建券发券花费的时间释放出来
2.把不关注的参数在请求接口时固定,页面只展示常用必要参数

3. 前期准备

技术栈选择:

  • vue+springboot
  • vue+fastapi
  • vue

1.在JavaScript中,进行网络请求通常使用以下几种方法:

1.1 XMLHttpRequest:
  • 优点:

  • 原生浏览器支持,不需要额外的库。

  • 缺点:

  • 较为繁琐的API,需要多行代码来完成简单的请求。

  • 不支持Promise,需要通过事件监听器来处理回调。

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/api/data", true);
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    var responseData = JSON.parse(xhr.responseText);
    console.log(responseData);
  }
};
xhr.send();```
#### **1.2 Fetch API:**

- 优点:

- 简洁性: 提供了更清晰、更强大的API。
- 基于Promise,支持更现代的异步操作。
- 提供了丰富的 **Response** 对象,以更好地处理请求。


- 缺点:

- 在一些较旧的浏览器中可能不受支持。


fetch(“https://example.com/api/data”)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(“Error:”, error));```

1.3 Axios (第三方库):
  • 优点:

  • 简单易用的API设计。

  • 支持Promise。

  • 支持拦截请求和响应。

  • 自动转换JSON数据。

  • 缺点:

  • 需要额外安装和引入库,增加了项目体积。

使用Axios需要先安装它,可以通过npm或yarn进行安装。

npm install axios
```在代码中使用:

const axios = require('axios');
axios.get('https://example.com/api/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));```
#### **1.4jQuery Ajax:**

- 优点:

- 在需要支持老版本浏览器时可能更容易兼容。
- 相对简单的API。


- 缺点:

- 依赖于整个jQuery库,可能会增加项目体积。
- 不如现代的Fetch API提供的Promise支持丰富。


如果你在项目中使用了jQuery,可以使用其Ajax方法:

$.ajax({
url: ‘https://example.com/api/data’,
method: ‘GET’,
success: function (data) {
console.log(data);
},
error: function (error) {
console.error(‘Error:’, error);
}
});```

2 为什么使用 Fetch API?

Fetch API 是一种现代的 JavaScript 网络请求接口,取代了传统的 XMLHttpRequest。它提供了更简单、更强大的方式来发起网络请求。

1.2 优点和特性
  • Promise 和异步操作: 使用 Promise 处理异步操作,使代码更清晰。
  • 更灵活的请求配置: 可以设置请求方法、请求头、模式、缓存等。
  • 流式操作: 支持流式操作,可以处理大文件等场景。
  • 同源策略和跨域: 遵循同源策略,但支持跨域请求,提供了 CORS 支持。

3.Fetch API 支持多种请求方式

  1. GET 请求
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log('GET Data:', data))
  .catch(error => console.error('Error:', error));
  1. POST 请求
fetch('https://api.example.com/data', {
  method: 'POST',
  body: JSON.stringify({ key: 'value' }),
  headers: {
    'Content-Type': 'application/json'
  },
})
  .then(response => response.json())
  .then(data => console.log('POST Data:', data))
  .catch(error => console.error('Error:', error));```
1. PUT 请求

fetch(‘https://api.example.com/data/123’, {
method: ‘PUT’,
body: JSON.stringify({ key: ‘updatedValue’ }),
headers: {
‘Content-Type’: ‘application/json’
},
})
.then(response => response.json())
.then(data => console.log(‘PUT Data:’, data))
.catch(error => console.error(‘Error:’, error));```

  1. DELETE 请求
fetch('https://api.example.com/data/123', {
  method: 'DELETE',
})
  .then(response => response.json())
  .then(data => console.log('DELETE Data:', data))
  .catch(error => console.error('Error:', error));```
1. Fetch API 还支持其他请求方式,例如:

- **HEAD:** 与 GET 类似,但只返回响应头,不返回实体主体。
- **OPTIONS:** 用于描述目标资源的通信选项。
- **PATCH:** 用于对资源进行部分修改。
- 等等...


### 4.vue常用的指令和监听器

#### 4.1:**v-model**

**v-model** 是 Vue.js 中用于实现表单元素和数据之间双向绑定的指令。这意味着当用户在表单元素中输入数据时,不仅会更新表单元素的值,还会自动更新 Vue 实例中对应的数据,反之亦然。
**简单理解:**
##### 1. **Input 绑定数据:**当你在一个输入框(比如文本框)中使用 **v-model**,它会自动将输入框的值与 Vue 实例中的一个变量绑定在一起。例如:

```<input v-model="message">```

这表示 **message** 这个变量和输入框的值是相互关联的。当你输入文本时,**message** 的值会自动更新。
##### 2. **Checkbox 和 Radio 绑定数据:**

对于复选框和单选框,**v-model** 同样很方便。它会把复选框的状态或选中的单选框的值与 Vue 实例中的一个变量关联起来。例如:

```<input type="checkbox" v-model="isChecked">```

这表示 **isChecked** 和复选框的状态是相互关联的。当你勾选或取消勾选时,**isChecked** 的值会自动更新。
##### 3. **修饰符:**

**v-model** 还提供了一些修饰符,可以根据需要调整其行为。例如,使用 **.number** 修饰符可以确保输入的值被解析为数值类型,使用 **.trim** 可以自动去除首尾空格。

```<input v-model.number="numericValue">```
```<input v-model.trim="trimmedValue">```

总的来说,**v-model** 让前端开发者更轻松地处理用户输入和表单元素的状态,而不必手动管理数据的同步。这使得代码更简洁、易读,并提高了开发效率。
#### 4.2:**@change**

##### **@change** 是 Vue.js 中的事件监听器,用于捕获表单元素的变化事件。当用户在输入框、选择框等表单元素中输入或选择内容,并且元素失去焦点时,**@change** 事件就会触发。

需要注意的是,Vue.js 的事件绑定支持多种写法,包括:
- **@change**:简写形式,推荐在模板中使用。
- **v-on:change**:完整写法,更灵活,适用于动态绑定事件名的情况。

##### **简单解释:**

##### **1.监听输入框变化:**

```<input v-model="message" @change="handleInputChange" placeholder="Enter your message">```
这表示当用户在输入框中输入内容并且输入框失去焦点时,会触发 **handleInputChange** 方法,你可以在该方法中处理输入框的变化。
**2.监听选择框变化:**

<select v-model=“selectedOption” @change=“handleSelectChange”>
Option 1
Option 2
```
对于选择框,同样地,当用户选择不同的选项并且选择框失去焦点时,会触发 handleSelectChange 方法,你可以在该方法中处理选择框的变化。
总之,@change 提供了一种简单的方式来监听用户在表单元素中进行的变化,适用于需要在用户完成输入或选择后触发操作的场景。需要注意的是,如果你需要实时监听用户输入的过程,可以考虑使用 @input 事件。

4.3:@input

@input 是 Vue.js 中用于监听输入框输入事件的一种事件监听器。它用于捕获用户在输入框中输入文本时触发的事件。
简单解释:

  1. 在模板中使用:

<input v-model="message" @input="handleInput" placeholder="Type something">
这表示当用户在输入框中输入文本时,会触发 handleInput 方法。

  1. 在 Vue 实例中定义方法:
  methods: {
  handleInput() {
  console.log('Input event triggered:', this.message);
  // 在这里执行你的输入事件处理逻辑
  }
  }```
**handleInput** 方法会在每次用户输入时被调用,你可以在这里获取输入框的值并执行相应的逻辑。
这样的组合使用,使得在用户输入时能够实时地获取输入框的值,并在 Vue 实例中进行相应的处理。**@input** 常常与 **v-model** 一同使用,以实现输入框内容的双向绑定。
#### 4.4:@click

**@click** 是 Vue.js 中用于监听点击事件的一种简便写法。它用于绑定在特定元素上,当用户点击该元素时触发相应的处理函数。
**简单解释:**
1. **监听按钮点击事件:**
 ```<button @click="handleButtonClick">Click me</button>```
这表示当用户点击按钮时,将触发名为 **handleButtonClick** 的方法。你可以在这个方法中定义按钮点击后的逻辑。
1. **方法定义:**在 Vue 实例的 **methods** 中定义被 **@click** 绑定的方法:


methods: {
handleButtonClick() {
console.log(‘Button clicked!’);
// 在这里执行你的点击事件处理逻辑
}
}```
当按钮被点击时,handleButtonClick 方法会被调用,你可以在这里执行任何与点击按钮相关的操作。
总的来说,@click 是一种简便的 Vue.js 事件绑定写法,用于处理用户点击特定元素的情况。

4.实践

https://chat.openai.com/share/faf2f3c1-1beb-4243-bfe3-c6ffbd9a2c18

1.0版本

纯静态只有优惠券名称、优惠券类型、满多少、减多少
image
D:/01_居然之家/07_测试工具实现/分享素材/01_第一个版本.html

<!DOCTYPE html>
<html>
  <head>
    <title>优惠券输入</title>
  </head>
  <body>
    <label for="couponName">优惠券名称:</label>
    <input type="text" id="couponName"><br><br>

    <label for="couponType">优惠券类型:</label>
    <select id="couponType" onchange="handleCouponTypeChange()">
      <option value="红包券">红包券</option>
      <option value="满减券">满减券</option>
      <option value="直减券">直减券</option>
    </select><br><br>

    <label for="fullAmount">满多少:</label>
    <input type="number" id="fullAmount" disabled><br><br>

    <label for="discountAmount">减多少:</label>
    <input type="number" id="discountAmount"><br><br>

    <script>
      function handleCouponTypeChange() {
        const couponTypeSelect = document.getElementById("couponType");
        const fullAmountInput = document.getElementById("fullAmount");
        const discountAmountInput = document.getElementById("discountAmount");

        if (couponTypeSelect.value === "满减券") {
          fullAmountInput.disabled = false;
        } else {
          fullAmountInput.disabled = true;
          fullAmountInput.value = ""; // 清空满多少输入框
        }

        discountAmountInput.value = ""; // 清空减多少输入框
      }
    </script>
  </body>
</html>
1.01版本

增加券类型
image
D:/01_居然之家/07_测试工具实现/分享素材/区分券类型和优惠券类型.html

<!DOCTYPE html>
<html>
<head>
            <meta charset="UTF-8">

    <title>优惠券输入</title>
</head>
<body>
    <label for="couponName">优惠券名称:</label>
    <input type="text" id="couponName"><br><br>

    <label for="couponType">券类型:</label>
    <select id="couponType" onchange="handleCouponTypeChange()">
        <option value="红包券">红包券</option>
        <option value="优惠券">优惠券</option>
    </select><br><br>

    <label for="discountType">优惠类型:</label>
    <select id="discountType">
        <option value="直减券">直减券</option>
        <option value="优惠券">优惠券</option>
    </select><br><br>

    <label for="fullAmount">满多少:</label>
    <input type="number" id="fullAmount" disabled><br><br>

    <label for="discountAmount">减多少:</label>
    <input type="number" id="discountAmount"><br><br>

    <script>
        function handleCouponTypeChange() {
            const couponTypeSelect = document.getElementById("couponType");
            const fullAmountInput = document.getElementById("fullAmount");

            if (couponTypeSelect.value === "红包券") {
                fullAmountInput.disabled = true;
                fullAmountInput.value = ""; // 清空满多少输入框
            } else {
                fullAmountInput.disabled = false;
            }
        }
    </script>
</body>
</html>
1.02版本

增加环境选择框、券类型和优惠类型优化为单选、创建按钮

<!DOCTYPE html>
<html>
<head>
        <meta charset="UTF-8">

    <title>Vue.js 优惠券输入</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <label for="environment">选择环境:</label>
        <select id="environment" v-model="selectedEnvironment" @change="handleEnvironmentChange">
            <option value="sit">SIT</option>
            <option value="dev">DEV</option>
            <option value="dev2">DEV2</option>
            <option value="dev3">DEV3</option>
            <option value="dev4">DEV4</option>
            <option value="uat">UAT</option>
            <option value="gray">Gray</option>
        </select><br><br>

        <label for="couponName">优惠券名称:</label>
        <input type="text" id="couponName" v-model="couponName" required><br><br>

        <label>券类型:</label>
        <input type="radio" id="couponTypeRed" name="couponType" value="红包券" v-model="couponType" required>
        <label for="couponTypeRed">红包券</label>
        <input type="radio" id="couponTypeDiscount" name="couponType" value="优惠券" v-model="couponType" required>
        <label for ="couponTypeDiscount">优惠券</label><br><br>

        <label>优惠类型:</label>
        <input type="radio" id="discountTypeDirect" name="discountType" value="直减券" v-model="discountType" required @change="clearFullAmount">
        <label for="discountTypeDirect">直减券</label>
        <input type="radio" id="discountTypeCoupon" name="discountType" value="满减券" v-model="discountType" required>
        <label for="discountTypeCoupon">满减券</label><br><br>

        <label for="fullAmount">满多少:</label>
        <input type="number" id="fullAmount" step="0.01" v-model="fullAmount" @input="validateDecimal" required :disabled="discountType === '直减券'"><br><br>

        <label for="discountAmount">减多少:</label>
        <input type="number" id="discountAmount" step="0.01" v-model="discountAmount" @input="validateDecimal" required><br><br>

        <button @click="createCoupon">创建</button><br><br>
    </div>
</body>
</html>

1.1版本

<script>
        new Vue({
            el: '#app',
            data: {
                selectedEnvironment: 'sit',
                couponName: '',
                couponType: '优惠券', // 默认选中"优惠券"
                discountType: '直减券', // 默认选中"直减券"
                fullAmount: '',
                discountAmount: ''
            },
            methods: {
                handleEnvironmentChange: function() {
                    // 处理环境切换,您可以在这里执行相关操作,如修改后端API的地址
                    const selectedEnvironment = this.selectedEnvironment;
                    // 根据选定的环境设置后端API的地址
                    switch (selectedEnvironment) {
                        case 'sit':
                            // 设置为SIT环境的后端API地址
                            // this.apiBaseUrl = 'https://sit-api.example.com';
                            break;
                        case 'dev':
                            // 设置为DEV环境的后端API地址
                            // this.apiBaseUrl = 'https://dev-api.example.com';
                            break;
                        // 添加其他环境的处理逻辑
                    }
                },
                validateDecimal: function() {
                    const regex = /^\d+(\.\d{1,2})?$/;
                    if (!regex.test(this.fullAmount)) {
                        this.fullAmount = '';
                    }
                },
                clearFullAmount: function() {
                    // 清空"满多少"输入框
                    this.fullAmount = '';
                },
                createCoupon: function() {
                    // 检查是否所有字段都已填写
                    if (!this.selectedEnvironment || !this.couponName || !this.couponType || !this.discountType || !this.discountAmount) {
                        alert('请填写所有必填字段。');
                        return;
                    }

                    // 构建要发送到后端的数据对象
                    const requestData = {
                        couponName: this.couponName,
                        couponType: this.couponType,
                        discountType: this.discountType,
                        fullAmount: this.fullAmount,
                        discountAmount: this.discountAmount,
                        selectedEnvironment: this.selectedEnvironment // 将选定的环境作为参数传递给后端
                    };

                    // 使用fetch API或其他AJAX方法将数据发送到后端Java接口
                    // 这里只是示例,实际情况下需要替换为您的后端接口地址和请求方式
                    fetch('your_backend_api_url', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(requestData)
                    })
                    .then(response => {
                        if (response.ok) {
                            // 处理成功响应
                            alert('优惠券创建成功!');
                        } else {
                            // 处理错误响应
                            alert('优惠券创建失败,请重试。');
                        }
                    })
                    .catch(error => {
                        // 处理请求错误
                        alert('请求出错,请重试。');
                        console.error(error);
                    });
                }
            },
            created: function() {
                // 在Vue实例创建时处理初始环境设置
                this.handleEnvironmentChange();
            }
        });
    </script>

2.0版本

优化输入框按钮样式,增加接口请求
页面部分
<template>
  <div id="app">
    <label style="color: red" >建券默认适用于北京所有卖场,使用时间:2028-10-08截止,数量:100</label>
    <br><br/>
      <label style="color: red" >发券默认发放方式:落地页 + app手动领取,发放时间:2028-10-08截止,每人每天可领取张数:1,每人发放数量:1,发放数量:30</label><br><br/>

        <!-- 选择环境 -->
        <label for="environment">选择环境:</label>
        <!-- @change监听,调用handleEnvironmentChange方法 -->
        <el-select  size="small" id="environment" v-model="selectedEnvironment" @change="handleEnvironmentChange" style="width: 100px;">
          <el-option value="uat">UAT</el-option>
          <el-option value="gray">Gray</el-option>
          <el-option value="sit">SIT</el-option>
          <el-option value="dev">DEV</el-option>
          <el-option value="dev2">DEV2</el-option>
          <el-option value="dev3">DEV3</el-option>
          <el-option value="dev4">DEV4</el-option>
        </el-select><br><br>

          <!-- 优惠券名称 -->
          <label for="couponName">优惠券名称:</label>
          <el-input type="text" id="couponName" v-model="couponName" required style="width: 150px;" size="mini" /><br><br/>

            <!-- 券类型 -->
            <label>券类型:</label>
            <input type="radio" id="couponCategoryTypeDiscount" name="couponCategoryType" value="0" v-model="couponCategoryType" required>
              <label for="couponCategoryTypeDiscount">优惠券</label>
              <input type="radio" id="couponCategoryTypeRed" name="couponCategoryType" value="1" v-model="couponCategoryType" required>
                <label for="couponCategoryTypeRed">红包券</label>

                  <!-- 优惠类型 -->
                  <label>优惠类型:</label>
                 <!-- @change监听,调用clearCouponThresholdAmount方法 -->
                  <input type="radio" id="couponTypeDirect" name="couponType" value="1" v-model="couponType" required @change="clearCouponThresholdAmount">

                    <!-- 直减券 -->
                    <label for="couponTypeDirect">直减券</label>
                    <input type="radio" id="couponTypeCoupon" name="couponType" value="0" v-model="couponType" required>

                      <!-- 满减券   -->
                      <label for="couponTypeCoupon">满减券</label>

                        <!-- 满多少 -->
                        <label for="couponThresholdAmount">满多少:</label>
                      <!-- @input实时监听 调用validateDecimal1方法-->
                        <el-input   id="couponThresholdAmount"  v-model="couponThresholdAmount" size="mini" style="width: 100px;" :controls="false" @input="validateDecimal1" required :disabled="couponType === '1'"  autocomplete="off" /><br><br/>

                          <!-- 减多少 -->
                          <label for="couponAmount">减多少:</label>
                          <!-- @input实时监听 调用validateDecimal1方法-->
                          <el-input  id="couponAmount" :controls="false"  size="mini" style="width: 100px;" v-model="couponAmount" @input="validateDecimal2" required   />
                          <br><br/>
                            <!-- @click监听点击 调用creatCoupon -->
                            <el-button  @click="createCoupon" size="mini" type="primary" >创建</el-button><br><br>
  </div>
</template>```



js部分
javascript
export default {
  data() {
    return {
      selectedEnvironment: 'uat',
      couponName: '',
      couponCategoryType: '0', // 默认选中"优惠券"
      couponType: '1', // 默认选中"直减券"
      couponThresholdAmount: '',
      couponAmount: '',
   }
  },
  methods: {
    //设置环境
    handleEnvironmentChange: function() {
      // 处理环境切换,您可以在这里执行相关操作,如修改后端API的地址
      const selectedEnvironment = this.selectedEnvironment;
      // 根据选定的环境设置后端API的地址
      switch (selectedEnvironment) {
        case 'sit':
          // 设置为SIT环境的后端API地址
          this.apiBaseUrl = 'http://gatewaysit.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewaysit.jrdaimao.com';
          this.apiqueryCouponListUrl = 'http://gatewaysit.jrdaimao.com';
          this.apiaddCouponSendUrl = 'http://gatewaysit.jrdaimao.com';
          break;
        case 'dev':
          // 设置为DEV环境的后端API地址
          this.apiBaseUrl = 'http://gatewaydev.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewaydev.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewaydev.jrdaimao.com/';
          this.apiaddCouponSendUrl = 'http://gatewaydev.jrdaimao.com/';

          break;
        case 'dev2':
          // 设置为DEV2环境的后端API地址
          this.apiBaseUrl = 'http://gatewaydev2.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewaydev2.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewaydev2.jrdaimao.com/';
          this.apiaddCouponSendUrl = 'http://gatewaydev2.jrdaimao.com/';

          break;
        case 'dev3':
          // 设置为DEV3环境的后端API地址
          this.apiBaseUrl = 'http://gatewaydev3.jrdaimao.com';
          this.apiLoginUrl = 'http://gatewaydev3.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewaydev3.jrdaimao.com';
          this.apiaddCouponSendUrl = 'http://gatewaydev3.jrdaimao.com/';

          break;
        case 'dev4':
          // 设置为DEV4环境的后端API地址
          this.apiBaseUrl = 'http://gatewaydev4.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewaydev4.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewaydev4.jrdaimao.com';
          this.apiaddCouponSendUrl = 'http://gatewaydev4.jrdaimao.com/';

          break;
        case 'uat':
          // 设置为UAT环境的后端API地址
          this.apiBaseUrl = 'http://gatewayuat.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewayuat.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewayuat.jrdaimao.com/';
          this.apiaddCouponSendUrl = 'http://gatewayuat.jrdaimao.com';

          break;
        case 'gray':
          // 设置为GRAY环境的后端API地址
          this.apiBaseUrl = 'http://gatewaygray.jrdaimao.com/';
          this.apiLoginUrl = 'http://gatewaygray.jrdaimao.com/';
          this.apiqueryCouponListUrl = 'http://gatewaygray.jrdaimao.com/';
          this.apiaddCouponSendUrl = 'http://gatewaygray.jrdaimao.com';

          break;
        // 添加其他环境的处理逻辑
      }
    },
    //满多少输入框限制保留两位小数
    validateDecimal1: function() {
      // 移除字符串中的非数字和小数点
      this.couponThresholdAmount = this.couponThresholdAmount.replace(/[^0-9.]/g, '');

      // 检查小数点的个数
      const decimalCount = this.couponThresholdAmount.split('.').length - 1;

      if (decimalCount > 1) {
        // 如果小数点个数大于1,则只保留第一个小数点前的内容
        this.couponThresholdAmount = this.couponThresholdAmount.replace(/(\d+)\.(\d+)\./, '$1.$2');
      }

      // 限制只能输入两位小数或正整数
      if (this.couponThresholdAmount !== '') {
        const parts = this.couponThresholdAmount.split('.');
        if (parts.length === 2 && parts[1].length > 2) {
          // 如果小数位数大于2,则截取前两位小数
          this.couponThresholdAmount = `${parts[0]}.${parts[1].slice(0, 2)}`;


        }
      }

    },
    //减多少输入框限制保留两位小数
    validateDecimal2: function() {
      // 移除字符串中的非数字和小数点
      this.couponAmount = this.couponAmount.replace(/[^0-9.]/g, '');

      // 检查小数点的个数
      const decimalCount = this.couponAmount.split('.').length - 1;

      if (decimalCount > 1) {
        // 如果小数点个数大于1,则只保留第一个小数点前的内容
        this.couponAmount = this.couponAmount.replace(/(\d+)\.(\d+)\./, '$1.$2');
      }

      // 限制只能输入两位小数或正整数
      if (this.couponAmount !== '') {
        const parts = this.couponAmount.split('.');
        if (parts.length === 2 && parts[1].length > 2) {
          // 如果小数位数大于2,则截取前两位小数
          this.couponAmount = `${parts[0]}.${parts[1].slice(0, 2)}`;


        }
      }

  },
    //切换直减券情况清空输入的满多少内容
    clearCouponThresholdAmount: function() {
      // 当切换到"直减券"时清空"满多少"字段
      if (this.couponType === '1') {
        this.couponThresholdAmount = '';
      }
    },
    //核心方法:登录/建券/发券
    createCoupon: function() {

      //判空处理 检查是否所有字段都已填写和符合要求
      if (!this.selectedEnvironment ) {
        alert('请选择环境。');return;}
      else if ( !this.couponName ) {
        alert('请输入优惠券名称。');return;  }
      else if ( !this.couponCategoryType ) {
        alert('请选择券类型。');  return; }
      else if (!this.couponType ) {
        alert('请请选择优惠券类型。');  return;  }
      else if ( !this.couponThresholdAmount && this.couponType === '0') {
        alert('请输入满多少。');
        return;}
      else if (!this.couponAmount) {
        alert('请输入减多少。');
        return;
      }


      let jwtTokenJson
//登录接口
      fetch(this.apiLoginUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          "platform": "operation",


        },
        body: JSON.stringify({areaCode:"86",phone:"",password:""}),
      })
        .then(response => {
          if (!response.ok) {
            throw new Error('Network response was not ok');
          }
          return response.json(); // 解析第一个POST请求的响应的JSON数据
        })
        .then(dataFromFirstRequest => {
          jwtTokenJson = dataFromFirstRequest;
          // 提取登录请求响应中的token
          const fieldValue = jwtTokenJson.data.jwtToken;

          // 构建headers,使用登录接口中的token
          const secondRequestHeaders = {
            'Content-Type': 'application/json',
            'platform': 'operation',
            'Authorization': `${fieldValue}`, // 使用登录请求的token
          };

          // 建券接口的body
          const requestData = {
            couponName: this.couponName,
            couponCategoryType: this.couponCategoryType,
            couponType: this.couponType,
            couponThresholdAmount: this.couponThresholdAmount,
            couponAmount: this.couponAmount,
            selectedEnvironment: this.selectedEnvironment ,// 将选定的环境作为参数传递给后端
            couponCount:"100",couponDesc:"测试规则说明",couponTag:"满123减2",topicCode:null,couponValidityStart:"2023-10-08 00:00:00",couponValidityEnd:"2028-10-08 23:59:59",couponUseDayType:0,couponUsePeriodType:0,couponActivityOverlayType:0,couponCouponOverlayType:0,applyCityType:1,applyStoreType:0,applyShopType:0,applyCategoryType:0,applyBrandType:0,applyCommodityType:0,overlaySameBatchFlag:0,applyCities:[""],platformTotalSubsidy:999999,platformSubsidyOrderRisk:"0",platformPercent:100,storePercent:0,merchantPercent:0,couponStatus:2,creator:"工具平台",creatorId:"805233020456869888"

          };
          // 发起建券请求,使用构建的headers
          return fetch(this.apiBaseUrl,
            {
              method: 'POST',
              headers: secondRequestHeaders,

              body: JSON.stringify(requestData)
            });
        })
        .then(response => {
          if (!response.ok) {
            throw new Error('Network response was not ok');
          }
          return response.json(); // 解析POST请求的响应的JSON数据
        })

        .then(data1 => {
          // 构建查询优惠券列表的headers,包括提取的字段值
          const threeRequestHeaders = {

            'Content-Type': 'application/json',
            'platform': 'operation',
            'Authorization': `${jwtTokenJson.data.jwtToken}`, // 使用第一个请求的字段值
          };

          // 发起查询优惠券列表请求,使用构建的headers
          return fetch(this.apiqueryCouponListUrl,
            {
              method: 'POST',
              headers: threeRequestHeaders,
              //查询最新的一条数据
              body: JSON.stringify({"couponName":null,"creator":"工具平台","page":1,"pageSize":1})
            });
        })
        .then(response => {
          if (!response.ok) {
            throw new Error('Network response was not ok');
          }
          return response.json(); // 解析POST请求的响应的JSON数据
        })
        .then(dataFromthreeRequest => {
          // 提取查询优惠券列表请求响应中的优惠券批次号
          const couponBatchNo = dataFromthreeRequest.data.list[0].couponBatchNo;

          // 构建发券请求的headers,包括提取的字段值
          const fourRequestHeaders = {
            'Content-Type': 'application/json',
            'platform': 'operation',
            'Authorization': `${jwtTokenJson.data.jwtToken}`, // 使用登录请求的字段值
          };

          // 发起发券请求,使用构建的headers
          return fetch(this.apiaddCouponSendUrl,
            {
              method: 'POST',
              headers: fourRequestHeaders
              ,
              body: JSON.stringify({couponSendName:"测试平台发券",couponSendWay:1,couponSendStart:"2023-10-08 20:06:41",couponSendEnd:"2028-10-10 20:06:47",dataType:1,couponSendUser:1,couponSendExplain:"平台发券",subsidyAmount:"100000",subsidyAmountPercent:"100",singleDaySubsidyAmount:"111111",singleDaySendCount:"222222",couponSendDetailsReqDataList:[{couponBatchNo:couponBatchNo,everyUsrTotalNum:"1",totalAmount:"30",everyUsrEveryDayNum:"1",couponValidityEnd:"2028-10-08 23:59:59"}],couponSendStatus:2,creator:"工具平台",creatorId:"792553435156627456"})
            });
        })
        .then(response => {
          if (response.ok) {
            // 处理成功响应
            alert('优惠券创建/发券成功!');
          } else {
            // 处理错误响应
            alert('优惠券创建/发券失败,请重试。');
          }
        })
        .catch(error => {
          // 处理请求错误
          alert('请求出错,请重试。');
          console.error(error);
        });
    }
  },
  created: function() {
    // 在Vue实例创建时处理初始环境设置
    this.handleEnvironmentChange();
  }
}

5.收益

将建券发券平均时间3分钟缩减到了5秒钟

https://element.eleme.io/#/zh-CN/component/installation

https://www.w3cschool.cn/fetch_api/fetch_api-x4lu2k4d.html
https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值