35,提交订单页

Cart.vue

<template>
  <div class="cart container">
    <header>
      <i class="iconfont icon-fanhui" @click="$router.back()"></i>
      <span>购物车</span>
      <span @click="isNavBar" v-text="isNavStatus ? '完成' : '编辑'"></span>
    </header>
    <section v-if="list.length">
      <div class="cart-title">
        <van-checkbox @click="checkAllFn" :value="isCheckedAll"></van-checkbox>
        <span>商品</span>
      </div>
      <ul>
        <li v-for="(item, index) in list" :key="index">
          <div class="check">
            <van-checkbox
              @click="checkItem(index)"
              v-model="item.checked"
            ></van-checkbox>
          </div>
          <h2>
            <img :src="item.goods_imgUrl" alt="" />
          </h2>
          <div class="goods">
            <div class="goods-title">
              <span>{{ item.goods_name }}</span>
              <i
                class="iconfont icon-lajitong"
                @click="delGoodsFn(item.id)"
              ></i>
            </div>
            <div class="goods-price">¥{{ item.goods_price }}</div>
            <van-stepper
              @change="changeNum($event, item)"
              v-model="item.goods_num"
              integer
            />
          </div>
        </li>
      </ul>
    </section>
    <section v-else>
      没有购物车数据
      <router-link to="/home">去首页逛逛吧</router-link>
    </section>
    <footer v-if="list.length">
      <div class="radio">
        <van-checkbox @click="checkAllFn" :value="isCheckedAll"></van-checkbox>
      </div>
      <div class="total" v-show="!isNavStatus">
        <div>
          共有
          <span class="total-active">{{ total.num }}</span>
          件商品
        </div>
        <div>
          <span>总计:</span>
          <span class="total-active"
            >¥{{ total.price.toFixed(2) }} + 0茶币</span
          >
        </div>
      </div>
      <div class="order" v-if="isNavStatus" @click="delGoodsFn">删除</div>
      <div class="order" v-else @click="goOrder">去结算</div>
    </footer>
  </div>
</template>

<script>
import { Toast } from "mint-ui";
import http from "@/common/api/request.js";
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
export default {
  name: "Cart",
  data() {
    return {
      isNavStatus: false,
      checked: true,
    };
  },
  computed: {
    ...mapState({
      list: (state) => state.cart.list,
      selectList: (state) => state.cart.selectList,
    }),
    ...mapGetters(["isCheckedAll", "total"]),
    goodsList() {
      return this.selectList.map((id) => {
        return this.list.find((v) => v.id == id);
      });
    },
  },
  created() {
    this.getData();
  },
  methods: {
    ...mapMutations(["cartList", "checkItem", "initOrder"]),
    ...mapActions(["checkAllFn", "delGoodsFn"]),
    async getData() {
      let res = await http.$axios({
        url: "/api/selectCart",
        method: "post",
        headers: {
          token: true,
        },
      });

      res.data.forEach((v) => {
        v["checked"] = true;
      });

      this.cartList(res.data);
    },
    //点击编辑|完成
    isNavBar() {
      this.isNavStatus = !this.isNavStatus;
    },
    //修改数量
    changeNum(value, item) {
      //当前 购物车商品的 id以及  修改后的数量==》传递给后端
      //value 就是修改后的数量
      //item.id 就是购物车商品的id
      http.$axios({
        url: "/api/updateNum",
        method: "post",
        headers: {
          token: true,
        },
        data: {
          id: item.id,
          num: value,
        },
      });
    },
    //去结算
    goOrder() {
      if (!this.selectList.length) {
        Toast("请至少选择一件商品");
        return;
      }

      let newList = [];
      this.list.forEach((item) => {
        this.selectList.filter((v) => {
          if (v == item.id) {
            newList.push(item);
          }
        });
      });

      //生成一个订单
      http
        .$axios({
          url: "/api/addOrder",
          method: "post",
          headers: {
            token: true,
          },
          data: {
            arr: newList,
          },
        })
        .then((res) => {
          if (!res.success) return;
          //存储订单号
          this.initOrder(res.data);
          //进入提交订单页面
          this.$router.push({
            path: "/order",
            query: {
              detail: JSON.stringify(this.selectList),
              goodsList: JSON.stringify(this.goodsList),
            },
          });
        });
    },
  },
};
</script>
<style scoped lang="less">
header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 1.173333rem;
  color: #fff;
  background-color: #b0352f;
  i {
    padding: 0 0.4rem;
    font-size: 0.586666rem;
  }
  span {
    padding: 0 0.4rem;
    font-size: 0.426666rem;
  }
}
section {
  background-color: #f5f5f5;
  .cart-title {
    display: flex;
    padding: 0.533333rem;
    span {
      padding: 0 0.4rem;
      font-weight: 500;
      font-size: 0.48rem;
    }
  }
  ul {
    display: flex;
    flex-direction: column;
    li {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.16rem 0.533333rem;
      margin: 0.213333rem 0;
      background-color: #fff;
      .check {
        padding-right: 0.373333rem;
      }
      .goods {
        display: flex;
        flex-direction: column;
        padding-left: 0.4rem;
        font-size: 0.32rem;
        .goods-title {
          display: flex;
          i {
            font-size: 0.586666rem;
          }
        }
        .goods-price {
          padding: 0.08rem 0;
          color: #b0352f;
        }
        ::v-deep .van-stepper {
          text-align: right;
        }
      }
      img {
        width: 1.973333rem;
        height: 1.973333rem;
      }
    }
  }
}
footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 1.28rem;
  border-top: 0.053333rem solid #ccc;
  .radio {
    padding: 0 0.4rem;
  }
  .total {
    flex: 1;
    font-size: 0.32rem;
    .total-active {
      color: #b0352f;
    }
  }
  .order {
    width: 3.2rem;
    line-height: 1.28rem;
    color: #fff;
    text-align: center;
    font-size: 0.426666rem;
    background-color: #b0352f;
  }
}
</style>

新建Order.vue

<template>
  <div class="order container">
    <header>
      <i class="iconfont icon-fanhui" @click="$router.back()"></i>
      <span>提交订单</span>
      <i class="iconfont icon-kefu"></i>
    </header>
    <section>
      <div class="path">
        <h3 class="path-title">收货信息</h3>
        <div class="path-content" @click="goPath">
          <div>
            <span>{{ path.name }}</span>
            <span>{{ path.tel }}</span>
          </div>
          <div>
            <span>{{ path.province }}</span>
            <span>{{ path.city }}</span>
            <span>{{ path.county }}</span>
            <span>{{ path.addressDetail }}</span>
          </div>
        </div>
      </div>
      <div class="payment">
        <div class="payment-title">支付方式:</div>
        <van-radio-group v-model="radioPayment">
          <van-radio name="wx">微信支付</van-radio>
          <van-radio name="ali">支付宝支付</van-radio>
        </van-radio-group>
      </div>
      <div class="goods">
        <ul>
          <li v-for="(item, index) in goodsList" :key="index">
            <div>
              <img :src="item.goods_imgUrl" alt="" />
            </div>
            <div class="goods-content">
              <h4>{{ item.goods_name }}</h4>
              <div class="goods-total">
                <span>¥{{ item.goods_price }}</span>
                <span>x{{ item.goods_num }}</span>
              </div>
            </div>
          </li>
        </ul>
      </div>
    </section>
    <footer>
      <div class="order-total">
        <span>共</span>
        <b>{{ total.num }}</b>
        <span>件,</span>
        <span>总金额:</span>
        <em>¥{{ total.price }}</em>
      </div>
      <div class="order-topay" @click="goPayment">提交订单</div>
    </footer>
  </div>
</template>
<script>
import { Toast } from "vant";
import http from "@/common/api/request.js";
import { mapState, mapGetters, mapMutations } from "vuex";
import bus from "@/common/bus.js";
import qs from "qs";
export default {
  data() {
    return {
      radioPayment: "wx",
      path: {},
      item: [],
      total: {
        price: 0,
        num: 0,
      },
    };
  },
  computed: {
    ...mapState({
      order_id: (state) => state.order.order_id,
      selectList: (state) => state.cart.selectList,
    }),
    ...mapGetters(["defaultPath"]),
  },
  created() {
    this.goodsList = JSON.parse(this.$route.query.goodsList);
    this.selectAddress();
  },
  activated() {
    bus.$on(
      "selectPath",
      function (data) {
        this.path = JSON.parse(data);
      }.bind(this)
    );
    //选中的商品id号
    this.item = JSON.parse(this.$route.query.detail);
    this.goodsList = JSON.parse(this.$route.query.goodsList);
    this.selectOrder();
  },
  methods: {
    ...mapMutations(["initData", "initOrder"]),
    //查询地址
    selectAddress() {
      http
        .$axios({
          url: "/api/selectAddress",
          method: "post",
          headers: {
            token: true,
          },
        })
        .then((res) => {
          this.initData(res.data);
          //有默认收货地址
          if (this.defaultPath.length) {
            this.path = this.defaultPath[0];
          } else {
            this.path = res.data[0];
          }
        });
    },
    //查询订单
    selectOrder() {
      http
        .$axios({
          url: "/api/selectOrder",
          method: "post",
          headers: {
            token: true,
          },
          data: {
            orderId: this.order_id,
          },
        })
        .then((res) => {
          this.initOrder(res.data);

          this.total = {
            price: res.data[0].goods_price,
            num: res.data[0].goods_num,
          };
        });
    },
    //选择收货地址
    goPath() {
      this.$router.push({
        path: "/path",
        query: {
          type: "select",
        },
      });
    },
    //提交订单
    goPayment() {
      //判断是否选择了收货地址
      if (!this.path) return Toast("请填写收货地址");

      //发送请求==》1.修改订单状态2.删除购物车的数据
      http
        .$axios({
          url: "/api/submitOrder",
          method: "post",
          headers: {
            token: true,
          },
          data: {
            orderId: this.order_id,
            shopArr: this.selectList,
          },
        })
        .then((res) => {
          let newArr = [];
          this.goodsList.forEach((v) => {
            newArr.push(v.goods_name);
          });

          //支付传递的参数
          let dataOrder = {
            orderId: this.order_id,
            name: newArr.join(""),
            price: this.total.price,
          };

          if (res.success) {
            //去支付
            http
              .$axios({
                url: "/api/payment",
                method: "post",
                headers: {
                  token: true,
                  "Content-Type": "application/x-www-form-urlencoded",
                },
                //qs是增加安全性的序列化
                data: qs.stringify(dataOrder),
              })
              .then((res) => {
                if (res.success) {
                  //打开支付宝支付的页面
                  window.location.href = res.paymentUrl;
                }
              });
          }
        });
    },
  },
};
</script>

<style lang='less' scoped>
header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 1.173333rem;
  color: #fff;
  background-color: #b0352f;
  i {
    padding: 0 0.4rem;
    font-size: 0.586666rem;
  }
  span {
    font-weight: 300;
    font-size: 0.48rem;
  }
}
section {
  background-color: #f7f7f7;
  .path-title {
    padding: 0.4rem;
    font-size: 0.48rem;
  }
  .path-content {
    padding: 0.16rem 0.4rem;
    font-size: 0.373333rem;
    background-color: #ffffff;
    span {
      padding-right: 0.16rem;
    }
  }
  .payment {
    padding: 0.16rem 0.4rem;
    margin-top: 0.4rem;
    font-size: 0.426666rem;
    background-color: #ffffff;
    .van-radio-group {
      display: flex;
      padding: 0.16rem 0;
      .van-radio {
        padding-right: 0.266666rem;
      }
    }
  }
  .goods {
    padding: 0.16rem 0.4rem;
    margin-top: 0.4rem;
    font-size: 0.426666rem;
    background-color: #ffffff;
    ul {
      width: 100%;
      li {
        display: flex;
        width: 100%;
        img {
          width: 1.973333rem;
          height: 1.973333rem;
        }
        .goods-content {
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          padding-left: 0.4rem;
          .goods-total {
            display: flex;
            justify-content: space-between;
          }
        }
      }
    }
  }
}
footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 1.2rem;
  border-top: 1px solid #ccc;
  .order-total {
    font-size: 0.426666rem;
    span {
      padding: 0 0.16rem;
    }
    b {
      color: #b0352f;
    }
    em {
      font-size: 0.48rem;
      color: #b0352f;
    }
  }
  .order-topay {
    width: 3.2rem;
    line-height: 1.2rem;
    color: #fff;
    font-size: 0.426666rem;
    text-align: center;
    background-color: #b0352f;
  }
}
</style>

配置路由

 {
      path: "/order",
      name: "Order",
      meta: {
          keepAlive: true
      },
      component: () =>
        import("../views/Order.vue"),
    },

 mutations-tpes.js

//订单
export const INIT_OREDER= 'initOrder'

 order.js

import {INIT_OREDER} from './mutations-types.js'
export default{
    state:{
        list:[],
        order_id : localStorage.getItem('tea_orderId') || ''
    },
    mutations:{
        [INIT_OREDER]( state , orderId ){
            state.list = orderId;
            //存储订单号
            state.order_id = orderId[0].order_id;
            
            //设置一个id号
            localStorage.setItem('tea_orderId',orderId[0].order_id);
        }
    }
}
//生成一个订单
router.post("/api/addOrder", function (req, res, next) {
  //token
  let token = req.headers.token;
  let tokenObj = jwt.decode(token);
  //前端给后端的数据
  let goodsArr = req.body.arr;
  //生成订单号order_id,规则:时间戳 + 6为随机数
  function setTimeDateFmt(s) {
    return s < 10 ? "0" + s : s;
  }
  function randomNumber() {
    const now = new Date();
    let month = now.getMonth() + 1;
    let day = now.getDate();
    let hour = now.getHours();
    let minutes = now.getMinutes();
    let seconds = now.getSeconds();
    month = setTimeDateFmt(month);
    day = setTimeDateFmt(day);
    hour = setTimeDateFmt(hour);
    minutes = setTimeDateFmt(minutes);
    seconds = setTimeDateFmt(seconds);
    let orderCode =
      now.getFullYear().toString() +
      month.toString() +
      day +
      hour +
      minutes +
      seconds +
      Math.round(Math.random() * 1000000).toString();
    return orderCode;
  }
  /*
    未支付:1
    待支付:2
    支付成功:3
    支付失败:4 | 0
    */
  //商品列表名称
  let goodsName = [];
  //订单商品总金额
  let goodsPrice = 0;
  //订单商品总数量
  let goodsNum = 0;
  //订单号
  let orderId = randomNumber();

  goodsArr.forEach((v) => {
    goodsName.push(v.goods_name);
    goodsPrice += v.goods_price * v.goods_num;
    goodsNum += parseInt(v.goods_num);
  });
  //查询当前用户
  connection.query(
    `select * from user where tel = ${tokenObj.tel}`,
    function (error, results) {
      //用户id
      let uId = results[0].id;
      connection.query(
        `insert into store_order (order_id,goods_name,goods_price,goods_num,order_status,uId) values ('${orderId}','${goodsName}','${goodsPrice}','${goodsNum}','1',${uId})`,
        function () {
          connection.query(
            `select * from store_order where uId = ${uId} and order_id='${orderId}'`,
            function (err, result) {
              res.send({
                data: {
                  success: true,
                  code: 200,
                  data: result,
                },
              });
            }
          );
        }
      );
    }
  );
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值