Vue项目流程7,交易页面,提交订单,支付页面,利用element UI 以及 QRCode 完成微信支付,弹出框按钮的相关工作,个人中心以及子路由我的订单

交易页面

1、静态组件及路由跳转
2、获取交易页数据
(1)接口

//获取用户地址信息  地址:/api/user/userAddress/auth/findUserAddressList   请求方式:GET  参数:无
export const reqAddressInfo = ()=> requests({url:'/user/userAddress/auth/findUserAddressList',method:'GET'})

//获取商品清单  地址:/api/order/auth/trade   请求方式:GET   参数:无
export const reqOrderInfo = ()=> requests({url:'/order/auth/trade',method:'GET'})

(2)新建小仓库trade.js书写vuex三连环

import {reqAddressInfo,reqOrderInfo} from '@/api/index'
const state ={
    adress:[],
    orderInfo:[]
}
const mutations ={
    GETUSERADDRESS(state,adress){
        state.adress == adress
    },
    GETORDERINFO(state,orderInfo){
        state.orderInfo = orderInfo
    }
}
const actions ={
    //获取用户地址信息
    async getUserAddress({commit}){
        let result = await reqAddressInfo()
        if(result.code == 200){
            commit('GETUSERADDRESS',result.data)
        }
    },
    //获取商品清单
    async getOrderInfo({commit}){
        let result = await reqOrderInfo()
        if(result.code == 200){
            commit('GETORDERINFO',result.data)
        }
    }
}
const getters ={}
export default {
    state,
    mutations,
    actions,
    getters
}

(3)路由跳转时派发action,即交易页面挂载完毕

mounted(){
  this.$store.dispatch('getUserAddress')
  this.$store.dispatch('getOrderInfo')
}

3、映射数据

  ...mapState({
    addressInfo:state => state.trade.address,
    orderInfo:state => state.trade.orderInfo
  }),

4、展示数据

  //提交订单时的地址
  userDefaultAddress(){
    return this.addressInfo.find(item=> item.isDefault == 1) || {} 
  }

5、给地址添加点击事件,点击时边框变红并设置为默认地址

//修改默认地址
      changeDefault(address,addressInfo){
        //全部的isDefault为0
        addressInfo.forEach(item => item.isDefault = 0);
        address.isDefault = 1
      }

find:查找数组中符合条件的元素返回作为最终结果

提交订单

1、路由跳转
2、点击提交订单时,还需要向服务器发起一次请求并将支付的信息传递给服务器
(1)接口

 //提交订单  地址:/api/order/auth/submitOrder?tradeNo={tradeNo}   请求方式:POST   参数:有
export const reqSubmitOrder = (tradeNo,data)=> requests({url:`/order/auth/submitOrder?tradeNo=${tradeNo}`,data,method:'POST'})

(2)组件内调用请求函数

  1. 将api文件夹里面全部请求函数统一引入在main.js文件中
//统一引入api文件夹里的全部请求函数
import * as API from '@/api'
  1. 全局事件总线所有API挂载到Vue原型上
Vue.prototype.$API = API

支付页面

1、静态组件
2、使用编程式路由跳转
3、在组件内调用请求函数

  //提交订单
  async submitOrder(){
    //需要带参
    let {tradeNo} = this.orderInfo
    let data = {
      consignee:this.userDefaultAddress.consignee,
      consigneeTel:this.userDefaultAddress.phoneNum,
      deliveryAddress:this.userDefaultAddress.fullAddress,
      paymentWay:'ONLINE',
      orderComment:this.msg,
      orderDetailList:this.orderInfo.detailArrayList
    }
    let result = await this.$API.reqSubmitOrder(tradeNo,data)
    if(result.code == 200){
      this.orderId = result.data
      //路由跳转+传参
      this.$router.push('/pay?orderId='+this.orderId)
    }else{
      alert(result.data)
    }
  }

4、数据展示orderId
5、拿着orderId向服务器发请求获取订单信息
(1)接口

//获取支付信息  地址:/api/payment/weixin/createNative/{orderId}  请求方式:GET   参数:有
export const reqPayInfo = (orderId)=> requests({url:`/payment/weixin/createNative/${orderId}`,method:'GET'})

(2)在ThePay组件挂载完毕之后发请求

mounted(){
  this.getPayInfo()
},
methods:{
  async getPayInfo(){
    let result = await this.$API.reqPayInfo(this.orderId)
    //如果成功在组件当中存储支付信息
    if(result.code == 200){
      this.payInfo = result.data
    }
  }
}

别在生命周期函数中async

6、展示信息

微信支付

1、编程式导航
2、elementUI使用
安装:cnpm install --save element-ui
按需加载:
(1)借助babel-plugin-component,所以需要安装
cnpm install babel-plugin-component -D
(2)将babel.config.js文件修改一下,加入以下内容

  'plugins': [
    [
      'component',
      {
        'libraryName': 'element-ui',
        'styleLibraryName': 'theme-chalk'
      }
    ]

在main.js文件中全局注册想要的组件
重启项目
引入注册:
(1)main.js文件里引入import {MessageBox} from 'element-ui'
(2)注册

Vue.prototype.$msgbox = MessageBox
Vue.prototype.$alert = MessageBox.alert

使用:

  //弹出框
  open(){
    this.$alert('HTML',{
      dangerouslyUseHTMLString:true,
      center:true,
      //是否显示取消按钮
      showCancelButton:true,
      //取消按钮的文本内容
      cancelButtonText:'支付遇见问题',
      confirmButtonText:'已完成支付',
      //是否保留右上角取消按钮
      showClose:false
    })
  }

React(Vue):antd[PC端]----antd-mobile[移动端]
Vue:ElementUI[PC端]----vant[移动端]

3、利用插件生成二维码
安装:cnpm i qrcode --save
引入: import QRCode from 'qrcode'
使用:

   //生成二维码(地址)
    let url = await QRCode.toDataURL(this.payInfo.codeUrl)
    this.$alert(`<img src=${url} />`,'请你微信支付',{

4、二维码生成之后需要知道成功或失败,如果支付成功就路由跳转如果支付失败弹出提示信息,所以此时需要向服务器发请求。
(1)接口

//获取订单支付状态  地址:/api/payment/weixin/queryPayStatus/{orderId}  请求方式:GET   参数:有
export const reqPayStatus = (orderId)=>requests({url:`/payment/weixin/queryPayStatus/${orderId}`,method:'GET'})

(2)支付成功页面的静态组件已经路由配置
(3)发请求

if(!this.timer){
  this.timer = setInterval( async ()=>{
    //发请求获取用户状态
    let result = await this.$API.reqPayStatus(this.orderId)
    console.log(result);
    if(result.code==200){
      //第一步:清除定时器
      clearInterval(this.timer)
      this.timer = null
      //第二步:保存支付成功返回的code
      this.code = result.code
      //第三步:关闭弹出框
      this.$msgbox.close()
      //第四步:跳转到下一个路由
      this.$router.push('/paysuccess')
    }
  },1000)
}

(4)弹出框按钮的相关工作,在element UI 方法里添加beforeClose属性

  //关闭弹出框的配置 第一参数:取消或完成  第二参数:当前组件实例  第三参数:关闭弹出框的方法
  beforeClose:(type,instance,done)=>{
    if(type=='cancel'){
      alert('请联系qq账号 3165281613')
      //清除定时器
      clearInterval(this.timer)
      this.timer = null
      //关闭弹出框
      done()
    }else{
      //判断是否真的支付了
      if(this.code == 200){
        //清除定时器
        clearInterval(this.timer)
        this.timer = null
        done()
        //路由跳转
        this.$router.push('/paysuccess')
      }
    }

此时需要使用到定时器,当用户没有支付即服务器返回的是未支付成功,此时需要一直向服务器发送请求,直到支付完成或是取消支付

个人中心

1、静态展示以及路由跳转,即从支付成功页面点击查看订单跳转到个人中心页面
2、将个人中心右侧展示拆分成两个子路由,在center文件夹内新建myOrder和groupOrder文件夹
3、注册子路由并且设置访问center时自动访问myorder

//二级路由
children:[
    {
        path:'myorder',
        component:MyOrder,
    },
    {
        path:'grouporder',
        component:GroupOrder,
    },
    {
        path:'/center',
        redirect:'/center/myorder'
    }
]

4、声名式导航

<dd>
  <router-link to="/center/myorder">我的订单</router-link>
</dd>
<dd>
  <router-link to="/center/grouporder">团购订单</router-link>
</dd>

我的订单

1、接口,获取我的订单列表

//获取个人中心的数据  地址:/api/order/auth/{page}/{limit}  请求方式:GET   参数:有
export const reqMyOrderList = (page,limit)=>requests({url:`/order/auth/${page}/${limit}`,method:'GET'})

2、在MyOrder组件挂载完毕或是点击页码后发送请求

  data(){
    return{
    //当前第几页
    page:1,
    //每一页展示个数
    limit:3,
    //存储我的订单的数据
    myOrder:{}
    }
  },
  mounted(){
    //获取我的订单的数据的方法
    this.getData()
  },
  methods:{
    //获取我的订单的数据
    async getData(){
      //结构参数
      const{page,limit} = this
      let result = await this.$API.reqMyOrderList(page,limit)
      if(result.code == 200){
        this.myOrder = result.data
      }
    }
  }

3、数据展示

  <div class="orders">
    <table class="order-item" v-for="order in myOrder.records" :key="order.id">
      <thead>
        <tr>
          <th colspan="5">
            <span class="ordertitle"
              >{{order.createTime}} 订单编号:{{order.outTradeNo}}
              <span class="pull-right delete"
                ><img src="../images/delete.png" /></span
            ></span>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(cart,index) in order.orderDetailList" :key="cart.id">
          <td width="60%">
            <div class="typographic">
              <img :src="cart.imgUrl" style="width:100px;height:100px;"/>
              <a href="#" class="block-text">{{cart.skuName}}</a
              >
              <span>x1</span>
              <a href="#" class="service">售后申请</a>
            </div>
          </td>
          <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="8%" class="center">{{order.consignee}}</td>
          <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="13%" class="center">
            <ul class="unstyled">
              <li>总金额¥{{order.totalAmount}}</li>
              <li>在线支付</li>
            </ul>
          </td>
          <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="8%" class="center">
            <a href="#" class="btn">{{order.orderStatusName}}</a>
          </td>
          <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="13%" class="center">
            <ul class="unstyled">
              <li>
                <a href="mycomment.html" target="_blank">评价|晒单</a>
              </li>
            </ul>
          </td>
        </tr>
      </tbody>
    </table>
  </div>

4、设置分页器

  <div class="choose-order">
    <!-- 分页器 -->
    <PagiNation
    :pageNo="page"
    :pageSize="limit"
    :total="myOrder.total"
    :continues="5"
    @getPageNo="getPageNo"
    />
  </div>
//获取点击哪一页
getPageNo(page){
  //修改组件响应式数据
  this.page = page
  this.getData()
}

面试题:是否封装过组件?即可回答封装过如分页器、日历

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小婵婵不怕鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值