VUE+Nodejs mall project practice project (foreground shopping)

The learning of vue and node is basically over. This project is to imitate Taobao Mall for practice. Since it is the first practical project for novices to leave the video tutorial, there are still many problems in the code. Please give me more advice. All the pictures and codes in this article are only used for learning, not for commercial purposes. If there is any infringement, please contact me to delete! The code provided is for reference only

project structure

insert image description here

Login Page (@/view/shop/login.vue)

account password login

insert image description here

Scan code to log in

insert image description here

Registration page (@/view/shop/register.vue)

insert image description here

Homepage (@/view/shop/index.vue)

insert image description hereinsert image description here

part of the code

<template>
  <div class="home-container">
    <topnav :userinfo="userinfo"></topnav>
    <img src="../../assets/images/topImg.png" alt="" class="topImg" />
    <el-row :gutter="20" type="flex" justify="center" class="search-box">
      <el-col :span="4">
        <img src="../../assets/images/logo.png" alt="" />
      </el-col>
      <el-col :span="11">
        <el-input placeholder="请输入内容" clearable class="search-input" v-model="query">
          <el-button slot="append" class="search-btn">搜索</el-button>
        </el-input>
        <ul class="link-list">
          <li><a href="#">一淘现时抢购</a></li>
          <li><a href="#">手机</a></li>
          <li><a href="#">零食</a></li>
          <li><a href="#">剃须刀</a></li>
          <li><a href="#">卫衣男</a></li>
          <li><a href="#">沙发</a></li>
          <li><a href="#">女秋装</a></li>
          <li><a href="#">女裤</a></li>
          <li><a href="#">运动鞋女</a></li>
          <li><a href="#">彪马</a></li>
        </ul>
      </el-col>
    </el-row>
    <div class="header-nav">
      <ul class="nav-list">
        <li><a href="#">每日爆品1元起</a></li>
        <li><a href="#">聚划算</a></li>
        <li><a href="#">淘抢购</a></li>
        <li><a href="#">天猫超市</a></li>
      </ul>
    </div>
    <div class="main-container">
      <div class="main-top">
        <div class="main-left" @mouseleave.prevent="handleLeave" ref="mainLeft">
          <div
            :class="
              activeId == index
                ? 'active channel-container '
                : 'channel-container'
            "
            v-for="(item, index) in items"
            :key="index"
            @mouseover="handleOver(index)"
          >
            <div class="channel-left">
              <i :class="'iconfont '+item.icon"></i>
              <div class="category">{
    
    {
    
     item.category }}</div>
            </div>
            <div class="channel-right">
              <a href="#" v-for="idex in item.channel_simple" :key="idex.id">{
    
    {
    
    
                idex
              }}</a>
            </div>
          </div>
          <div
            class="channel-right-box"
            v-if="isRight"
            @mouseleave.prevent="handleLeave"
            :style="{height: scrollerHeight}"
          >
            <div class="right-item" v-for="item in rightBox" :key="item.id">
              <div class="right-item-title">{
    
    {
    
     item.main }}</div>
              <ul class="right-item-box">
                <li v-for="idx in item.goods" :key="idx.id">{
    
    {
    
     idx }}</li>
              </ul>
            </div>
          </div>
        </div>
        <div class="main-mid">
          <div class="main-mid-left">
            <el-carousel height="280px" class="top-item">
              <el-carousel-item v-for="(item, index) in banners" :key="index">
                <img :src="item" alt="" />
              </el-carousel-item>
            </el-carousel>
            <div class="small-title">
              <span>超值活动专区</span>
              <span>每天10点更新</span>
            </div>
            <div class="img-box">
              <img src="../../assets/images/midItem1.jpg" alt="" />
              <img src="../../assets/images/midItem2.jpg" alt="" />
            </div>
          </div>
          <div class="main-mid-right">
            <img
              src="../../assets/images/midItem3.jpg"
              alt=""
              class="top-item"
            />
            <img src="../../assets/images/midItem4.jpg" alt="" />
          </div>
        </div>

        <div class="main-right">
          <span class="right-first">我的淘宝</span>
          <ul class="item-box">
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
            <li><img src="../../assets/images/taobao.gif" alt=""></li>
          </ul>
          <ul class="message-box">
            <li class="item" v-for="(item, index) in messageList" :key="index">
              <span :class="`item-type-${item.tagType} item-tag`">{
    
    {
    
    
                item.tagName
              }}</span>
              <span class="item-info">{
    
    {
    
     item.tagContent }}</span>
            </li>
          </ul>
        </div>
      </div>
      <div class="main-bottom">
        <div class="bottom-title">猜你喜欢</div>
        <ul class="main-bottom-container">
          <li
            class="bottom-item"
            v-for="(item) in goodsList"
            :key="item.id"
          >
            <img :src="`http://127.0.0.1:3007/${item.picName}`" alt="" />
            <div class="goods-title">
              {
    
    {
    
     item.goodName+item.keyWord }}
            </div>
            <div class="price-box">
              <span></span>
              <span>{
    
    {
    
     item.priceNow }}</span>
              <span class="pass">{
    
    {
    
     item.priceAgo }}</span>
            </div>
            <div class="shopInfo">
              <i class="iconfont icon-dianpu"></i>
              {
    
    {
    
     item.shopName }}
            </div>
            <div class="item-footer">月销{
    
    {
    
     item.saleCount }}</div>
          </li>
        </ul>
        <el-pagination v-if="total > 5" background layout="prev, pager, next" :total="total">
        </el-pagination>
      </div>
    </div>
    <div class="main-footer">
      <div class="footer-item">
        <span class="item-link">联系客服</span>
        <span class="item-link">开放平台</span>
        <span class="item-link">法律声明</span>
        <span class="item-link">廉正举报</span>
        <span>Taobao.com版权所有 2003-现在</span>
        <span class="item-link">增值电信业务经营许可证:浙B2-20070195</span>
        <span class="item-link">浙公网安备 33010002000075</span>
      </div>
      <ul class="footer-item footer-item-2">
        <li class="item-link">阿里巴巴集团</li>
        <li class="item-link">淘宝网</li>
        <li class="item-link">天猫</li>
        <li class="item-link">聚划算</li>
        <li class="item-link">全球速卖通</li>
        <li class="item-link">阿里巴巴国际交易市场</li>
        <li class="item-link">1688</li>
        <li class="item-link">阿里妈妈</li>
        <li class="item-link">飞猪</li>
        <li class="item-link">阿里云计算</li>
        <li class="item-link">AIOS</li>
        <li class="item-link">阿里通信</li>
        <li class="item-link">高德</li>
        <li class="item-link">UC</li>
        <li class="item-link">友盟</li>
        <li class="item-link">虾米</li>
        <li class="item-link">阿里星球</li>
        <li class="item-link">钉钉</li>
        <li class="item-link">支付宝</li>
        <li class="item-link">达摩院</li>
      </ul>
    </div>
  </div>
</template>
<script>
import topnav from '@/components/topnav.vue'
export default {
    
    
  components: {
    
    
    topnav
  },
  data () {
    
    
    return {
    
    
      isRight: false,
      items: [],
      rightBox: [],
      activeId: null,
      banners: [
        require('../../assets/images/banner1.jpg'),
        require('../../assets/images/banner2.jpg'),
        require('../../assets/images/banner3.jpg')
      ],
      messageList: [
      ],
      total: 5,
      goodsList: [
      ],
      query: '',
      queryInfo: {
    
    
        page: 1,
        limit: 10
      },
      userinfo: {
    
    },
      showmenu: false
    }
  },
  created () {
    
    
    this.getChannel()
    this.getGoodsList()
    this.getMessage()
  },
  computed: {
    
    
    scrollerHeight () {
    
    
      return this.$refs.mainLeft.offsetHeight
    }
  },
  mounted () {
    
    
    this.userinfo = JSON.parse(sessionStorage.getItem('userinfo'))
  },
  methods: {
    
    
    handleOver (id) {
    
    
      this.activeId = id
      this.isRight = true
      this.rightBox = this.items[id].channem_detail
    },
    handleLeave () {
    
    
      this.activeId = null
      this.isRight = false
    },
    async getChannel () {
    
    
      const {
    
     data: res } = await this.$http.get('/shop/getChannel')
      if (res.code !== 200) return this.$message.error(res.msg)
      this.items = res.data
    },
    async getGoodsList () {
    
    
      const {
    
     data: res } = await this.$http.post('/shop/getGoods', this.queryInfo)
      if (res.code !== 200) return this.$message.error(res.msg)
      this.goodsList = res.data
    },
    async getMessage () {
    
    
      const {
    
     data: res } = await this.$http.get('/shop/getActivity')
      if (res.code !== 200) return this.$message.error(res.msg)
      this.messageList = res.data
    }
  }
}
</script>

User Center (@/view/shop/userInfo.vue)

insert image description here

source code

<template>
  <div class="home-container">
    <topnav :userinfo="userinfo"></topnav>
    <div class="header">
      <div class="header-container">
        <div class="logo">
          <div
            title="我的淘宝"
            href="//i.taobao.com/my_taobao.htm?nekot=1470211439696&amp;tracelog=newmytb_logodianji"
            class="tblogo"
          ></div>
        </div>
        <div class="nav">
          <ul class="nav-left">
            <li class="index">首页</li>
            <li>账户设置</li>
          </ul>
          <div class="nav-right">
            <el-input placeholder="请输入内容" v-model="input2">
              <template slot="append"> 搜索 </template>
            </el-input>
          </div>
        </div>
      </div>
    </div>
    <div class="main-body-container">
      <div class="main-body">
        <div class="nav-container">
          <dt class="main-body-title">全部功能</dt>
          <dd>我的购物车</dd>
          <dd>已买到的宝贝</dd>
          <dd>购买过的店铺</dd>
          <dd>我的发票</dd>
          <dd>我的收藏</dd>
          <dd>我的积分</dd>
          <dd>我的优惠信息</dd>
          <dd>评价管理</dd>
          <dd>退款维权</dd>
          <dd>我的足迹</dd>
          <dd>流量钱包</dd>
        </div>
        <div class="content-container">
          <div class="main-wrap">
            <div class="userBar">
              <div class="userInfo">
                <div class="basicInfo">
                  <div class="avatar" @mouseenter="editAvatar = true" @mouseleave="editAvatar = false">
                    <img :src="userDetail.userPic" alt="" />
                    <div class="mask" v-if="editAvatar">
                        <span>编辑资料</span>
                    </div>
                </div>
                  <div class="detail">
                    <span>{
    
    {
    
    userDetail.nickname}}</span><br />
                    <i class="iconfont">&#xe647;</i>
                  </div>
                </div>
                <ul class="stuffs">
                  <li>我的收货地址</li>
                  <li>我的优惠信息</li>
                  <li>我的支付宝</li>
                </ul>
              </div>
              <ul class="content">
                <li>待付款</li>
                <li>待发货</li>
                <li>待收货</li>
                <li>待评价</li>
                <li>退款</li>
              </ul>
            </div>
            <div class="goodsBar">
              <div class="title"><i class="iconfont">&#xe75f;</i>我的物流</div>
              <ul class="goodsContainer">
                <li class="goodsItem">
                  <img src="@/assets/images/goods.jpg" alt="" />
                  <div class="info">
                    <span class="status"
                      >您的快件已签收,签收人:同事(温馨提示您:戴口罩取快递,个您的快件已签收,签收人:同事(温馨提示您:戴口罩取快递,个您的快件已签收,签收人:同事(温馨提示您:戴口罩取快递,个</span
                    >
                    <span class="date">2022-09-26 11:57:43 查看物流明细</span>
                  </div>
                  <el-button class="confirmbtn">确认收货</el-button>
                </li>
              </ul>
            </div>
          </div>
          <div class="calendar-right">
            <div class="calendar-title">我的日历</div>
            <div class="calendar-body">
              <span class="day">{
    
    {
    
    day}}</span>
              <span class="week">{
    
    {
    
    week}}</span>
              <span class="date">{
    
    {
    
    year}}.{
    
    {
    
    month}}</span>
            </div>
            <div class="recommend">
              <img src="@/assets/images/recommend.jpg" alt="" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import topnav from '@/components/topnav.vue'
export default {
    
    
  components: {
    
    
    topnav
  },
  data () {
    
    
    return {
    
    
      editAvatar: false,
      userinfo: {
    
    },
      year: '',
      month: '',
      day: '',
      week: '',
      userDetail: {
    
    },
      showmenu: false,
      input2: ''
    }
  },
  created () {
    
    
    this.getNowDate()
  },
  mounted () {
    
    
    this.userinfo = JSON.parse(sessionStorage.getItem('userinfo'))
    this.getDetail(this.userinfo.id)
  },
  computed: {
    
    },
  methods: {
    
    
    getNowDate () {
    
    
      const timeOne = new Date()
      this.year = timeOne.getFullYear()
      this.month = timeOne.getMonth() + 1
      this.day = timeOne.getDate()
      this.month = this.month < 10 ? '0' + this.month : this.month
      this.day = this.day < 10 ? '0' + this.day : this.day
      this.week = timeOne.getDay()
      const weeks = ['日', '一', '二', '三', '四', '五', '六']
      this.week = '星期' + weeks[this.week]
    },
    async getDetail (id) {
    
    
      const {
    
     data: res } = await this.$http.post('/user/shopUserDetail', {
    
     id: id })
      if (res.code !== 200) return this.$message.error(res.msg)
      this.userDetail = res.data
      if (this.userDetail.userPic === null) {
    
    
        this.userDetail.userPic = '@/assets/images/user.png'
      } else {
    
    
        this.userDetail.userPic = `http://127.0.0.1:3007/${
      
      this.userDetail.userPic}`
      }
    }

  }
}
</script>

Shopping Cart (@/view/shop/shopcart.vue)

insert image description hereinsert image description here

source code

<template>
  <div class="home-container">
    <topnav :userinfo="userinfo"></topnav>
    <shopHeader></shopHeader>
    <div class="main-container">
      <div class="toptitle">
        <span class="cart-switch">购物车(全部{
    
    {
    
     itemCountUp }})</span>
        <div class="cart-sum">
          <span class="pay-text">已选商品(不含运费)</span>
          <span class="money">{
    
    {
    
     sumup === 0 ? sumup : "¥" + sumup }}</span>
          <el-button
            type="warning"
            class="btn-checkoutabled"
            :class="count === 0 ? 'btn-disabled' : ''"
            @click="handleSettlement"
            >结算</el-button
          >
        </div>
      </div>
      <div class="main-body">
        <div class="table-th">
          <div class="checkbox">
            <input
              class="CheckBoxShop"
              type="checkbox"
              name="select-all"
              v-model="allcheck"
              @change="handleCheckAll(allcheck)"
            />
            <span>全选</span>
          </div>
          <div class="th-item">商品信息</div>
          <div class="th-info"></div>
          <div class="th th-price">单价</div>
          <div class="th th-number">数量</div>
          <div class="th">金额</div>
          <div class="th">操作</div>
        </div>
        <div class="table-body">
          <div
            class="table-item"
            v-for="(item, index) in tableData"
            :key="index"
          >
            <div class="item-top">
              <input
                class="CheckBoxShop"
                type="checkbox"
                name="select-single"
                v-model="item.isChecked"
                @change="handleChecked(item.isChecked, index)"
              />
              <span>店铺:{
    
    {
    
     item.shopName }}</span>
            </div>
            <div class="item-bottom">
              <div
                class="item-content"
                :class="`${item.isChecked === true ? 'checkShop' : ''}`"
              >
                <ul
                  class="item-body"
                  v-for="(item2, idx2) in item.items"
                  :key="idx2"
                  :class="`${item2.isChecked === true ? 'checkedClass' : ''}`"
                >
                  <li class="checkbox">
                    <input
                      class="CheckBoxShop"
                      type="checkbox"
                      name="select-single"
                      v-model="item2.isChecked"
                      @change="handleItemChecked(index, idx2)"
                    />
                  </li>
                  <li class="item-info">
                    <img :src="`http://127.0.0.1:3007/${item2.imgSrc}`" alt="" />
                    <div class="info-title">
                      {
    
    {
    
     item2.title }}
                    </div>
                  </li>
                  <li class="item-detail">
                    <div class="t">
                      {
    
    {
    
     item2.type }}
                    </div>
                    <div class="b">{
    
    {
    
     item2.model }}</div>
                  </li>
                  <li class="item item-price">
                    <div class="price-original">{
    
    {
    
     item2.originalPrice }}
                    </div>
                    <div class="price-now">{
    
    {
    
     item2.nowPrice }}</div>
                  </li>
                  <li class="item">
                    <el-input-number
                      :min="1"
                      v-model="item2.number"
                    ></el-input-number>
                  </li>
                  <li class="item item-sum">
                    <span
                      >{
    
    {
    
     (item2.sum = item2.nowPrice * item2.number) }}</span
                    >
                  </li>
                  <li class="item-op">
                    <el-button type="text" class="opt-button"
                      >移入收藏夹</el-button
                    >
                    <el-button type="text" class="opt-button" @click="handleDelItem(item.id,item2.id)">删除</el-button>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="bottomopt">
        <div class="checkbox">
          <input
            class="CheckBoxShop"
            type="checkbox"
            name="select-all"
            v-model="allcheck"
            @change="handleCheckAll(allcheck)"
          />
          <span>全选</span>
          <span class="del-btn opt-btn">删除</span>
          <span class="opt-btn">移入收藏夹</span>
        </div>
        <div class="opt-r">
          <div class="cart-sum">
            已选商品<span class="number">{
    
    {
    
     count }}</span
            ></div>
          <div class="cart-sum">
            合计(不含运费):<span class="number">{
    
    {
    
    
              sumup === 0 ? sumup : "¥" + sumup
            }}</span>
          </div>
          <el-button
            type="warning"
            class="btn-checkoutabled"
            :class="count === 0 ? 'btn-disabled' : ''"
            @click="handleSettlement"
            >结算</el-button
          >
        </div>
      </div>
    </div>
    <mainFooter></mainFooter>
  </div>
</template>
<script>
import topnav from '@/components/topnav.vue'
import shopHeader from '@/components/header.vue'
import mainFooter from '@/components/footer.vue'
export default {
    
    
  components: {
    
    
    topnav,
    shopHeader,
    mainFooter
  },
  data () {
    
    
    return {
    
    
      userinfo: {
    
    },
      allcheck: false,
      count: 0,
      sumup: 0,
      tableData: []
    }
  },
  created () {
    
    
    this.userinfo = JSON.parse(sessionStorage.getItem('userinfo'))
  },
  mounted () {
    
    
    this.getTableData()
  },
  computed: {
    
    
    itemCountUp: function () {
    
    
      let count = 0
      this.tableData.forEach((item) => {
    
    
        count += item.items.length
      })
      return count
    }
  },
  methods: {
    
    
    handleChecked (isChecked, index) {
    
    
      if (isChecked) {
    
    
        this.tableData[index].items.forEach((i) => {
    
    
          i.isChecked = true
        })
      } else {
    
    
        this.tableData[index].items.forEach((i) => {
    
    
          i.isChecked = false
        })
      }
    },
    handleItemChecked (index, idx2) {
    
    
      let count = 0
      this.tableData[index].items.forEach((i) => {
    
    
        if (i.isChecked) {
    
    
          count = count + 1
        }
      })
      if (count === this.tableData[index].items.length) {
    
    
        this.tableData[index].isChecked = true
      } else {
    
    
        this.tableData[index].isChecked = false
      }
    },
    handleCheckAll (isChecked) {
    
    
      if (isChecked) {
    
    
        this.tableData.forEach((i1) => {
    
    
          i1.isChecked = true
          i1.items.forEach((i2) => {
    
    
            i2.isChecked = true
          })
        })
      } else {
    
    
        this.tableData.forEach((i1) => {
    
    
          i1.isChecked = false
          i1.items.forEach((i2) => {
    
    
            i2.isChecked = false
          })
        })
      }
    },
    handleSettlement () {
    
    
      const infoList = []
      this.tableData.forEach(info => {
    
    
        for (let i = 0; i < info.items.length; i++) {
    
    
          let temp = {
    
    }
          if (info.items[i].isChecked) {
    
    
            temp.shopId = info.id
            temp = Object.assign(temp, info.items[i])
            temp.order_sumup = this.sumup
            infoList.push(temp)
          }
        }
      })
      this.$router.push({
    
     path: '/settlement', query: {
    
     info: JSON.stringify(infoList) } })
    },
    async getTableData () {
    
    
      const {
    
     data: res } = await this.$http.post('/cart/getUserCart', {
    
     id: this.userinfo.id })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.tableData = res.data
    },
    handleDelItem (shopId, goodId) {
    
    
      this.$confirm('是否确认删除', '提示', {
    
    
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
    
    
          const {
    
     data: res } = await this.$http.post('/cart/delCartItem', {
    
    
            userId: this.userinfo.id,
            goodId: goodId,
            shopId: shopId
          })
          if (res.code !== 200) {
    
    
            return this.$message.error(res.msg)
          }
          this.$message.success('删除成功!')
          this.getTableData()
        })
        .catch(() => {
    
    })
    }
  },
  watch: {
    
    
    tableData: {
    
    
      handler (value) {
    
    
        this.count = 0
        this.sumup = 0
        for (var i = 0; i < value.length; i++) {
    
    
          value[i].items.forEach((item) => {
    
    
            if (item.isChecked === true) {
    
    
              this.count++
              this.sumup += item.sum
            }
          })
        }
        if (this.count === this.itemCountUp) {
    
    
          this.allcheck = true
        } else {
    
    
          this.allcheck = false
        }
      },
      deep: true
    }
  }
}
</script>

Submission page (@/view/shop/settlement.vue)

insert image description here

source code

<template>
  <div class="home-container">
    <topnav :userinfo="userinfo"></topnav>
    <div class="main-container">
      <div class="top">
        <img src="@/assets/images/taobao.gif" alt="" />
        <div class="step-container">
          <el-steps :space="200" :active="0" finish-status="success">
            <el-step title="查看购物车"></el-step>
            <el-step title="拍下商品"></el-step>
            <el-step title="付款到支付宝"></el-step>
            <el-step title="确认收货"></el-step>
            <el-step title="评价"></el-step>
          </el-steps>
        </div>
      </div>
      <div class="address-box">
        <h3>选择收货地址</h3>
        <ul class="address-container">
          <li class="address-item" v-for="(item,index) in addressList " :key="index" :class="item.default === true?'active':''" @click="handleAddress(index)">
            <div class="address-hd">{
    
    {
    
    item.province}}{
    
    {
    
    item.city}} {
    
    {
    
    item.receiver}}({
    
    {
    
    item.phone}})</div>
            <div class="address-bd">
              {
    
    {
    
    item.detailAddress}}
            </div>
            <div class="address-bd btn-modify" v-if="item.default === true" >修改</div>
            <div class="checkedMarker" v-if="item.default === true"></div>
          </li>
        </ul>
        <div class="address-btn">
          <div>显示全部地址</div>
          <div>管理收货地址</div>
        </div>
      </div>
      <div class="order-box">
        <h3>确认订单信息</h3>
        <div class="header-wrap">
          <div class="headerItem header-0">店铺宝贝</div>
          <div class="headerItem header-1">商品属性</div>
          <div class="headerItem header-2">单价</div>
          <div class="headerItem header-2">数量</div>
          <div class="headerItem header-2">优惠方式</div>
          <div class="headerItem header-2">小计</div>
        </div>
        <div class="order-container">
          <div class="order-item" v-for="(item,index) in itemInfo" :key="index">
            <div class="order-shop">
              <img
                src="//gw.alicdn.com/tfs/TB1CzD7SXXXXXXJaXXXXXXXXXXX-32-32.png"
                alt=""
                class="shopIcon"
              />
              <span>店铺:{
    
    {
    
    item.shopName}}</span>
            </div>
            <ul class="order-detail" v-for="(i2,idx) in item.itemList" :key="idx">
              <li class="detail-0">
                <img :src="`http://127.0.0.1:3007/${i2.imgSrc}`" alt="" />
                <div class="detail-title">
                  {
    
    {
    
    i2.title}}
                </div>
              </li>
              <li class="detail-1">
                <div class="t">
                  {
    
    {
    
    i2.type}}
                </div>
                <div class="b">{
    
    {
    
    i2.model}}</div>
              </li>
              <li class="detail-2">
                <span>{
    
    {
    
    i2.nowPrice}}</span>
              </li>
              <li class="detail-2">
                <span>{
    
    {
    
    i2.number}}</span>
              </li>
              <li class="detail-2">
                <span>爆款促销</span>
              </li>
              <li class="detail-2">
                <span class="itemsumup">{
    
    {
    
    i2.sum}}</span>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div class="realpay">
        <div class="paybox">
          <div class="line">
            <span class="title">实付款:</span>
            <span class="unit"></span>
            <span class="money">{
    
    {
    
    order_sumup}}</span>
          </div>
          <div class="line">
            <span class="title">寄送至:</span>
            <span class="address"
              >上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海</span
            >
          </div>
          <div class="line">
            <span class="title">收货人;</span>
            <span class="address">XXXXXX XXXXXX</span>
          </div>
        </div>
      </div>
      <div class="submit-btn">
        <el-button type="text" @click="back2Cart">返回购物车</el-button>
        <el-button type="error" class="submit-order" @click="handleSubmit">提交订单</el-button>
      </div>
    </div>
    <mainfooter></mainfooter>
  </div>
</template>
<script>
import topnav from '@/components/topnav.vue'
import mainfooter from '@/components/footer.vue'
export default {
    
    
  components: {
    
    
    topnav,
    mainfooter
  },

  data () {
    
    
    return {
    
    
      userinfo: {
    
    },
      addressList: [
        {
    
    
          province: '上海',
          city: '上海',
          receiver: 'XXX',
          detailAddress: '上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海',
          phone: 'XXXXXX',
          default: true
        },
        {
    
    
          province: '上海',
          city: '上海',
          receiver: 'XXX',
          detailAddress: '上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海',
          phone: 'XXXXXX',
          default: false
        },
        {
    
    
          province: '上海',
          city: '上海',
          receiver: 'XXX',
          detailAddress: '上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海上海',
          phone: 'XXXXXX',
          default: false
        }
      ],
      orderInfo: [],
      itemInfo: []
    }
  },
  created () {
    
    
    this.userinfo = JSON.parse(sessionStorage.getItem('userinfo'))
    this.orderInfo = JSON.parse(this.$route.query.info)
    this.handleOrderItem()
  },
  computed: {
    
    
    order_sumup: function () {
    
    
      let count = 0
      this.orderInfo.forEach((item) => {
    
    
        count += item.sum
      })
      return count
    }
  },
  methods: {
    
    
    back2Cart () {
    
    
      this.$router.push('/shopcart')
    },
    handleAddress (index) {
    
    
      this.addressList.forEach((item) => {
    
    
        item.default = false
      })
      this.addressList[index].default = true
    },
    handleOrderItem () {
    
    
      for (let i = 0; i < this.orderInfo.length; i++) {
    
    
        const temp = {
    
    }
        temp.shopName = this.orderInfo[i].shopName
        temp.itemList = []
        const index = this.itemInfo.findIndex(item => item.shopName === temp.shopName)
        if (index === -1) {
    
    
          temp.itemList.push(this.orderInfo[i])
          this.itemInfo.push(temp)
        } else {
    
    
          this.itemInfo[index].itemList.push(this.orderInfo[i])
        }
      }
      console.log(this.itemInfo)
    },
    async handleSubmit () {
    
    
      const {
    
     data: res } = await this.$http.post('/order/createOrder', {
    
     info: this.orderInfo, userId: this.userinfo.id })
      if (res.code !== 200) return this.$message.error(res.msg)
      this.$message.success('提交成功!')
      setTimeout(() => {
    
    
        this.$router.push('/shopcart')
      }, 1000)
    }
  }
}
</script>

My Order

insert image description hereinsert image description hereinsert image description here

partial source code

<template>
  <div class="home-container">
    <topnav :userinfo="userinfo"></topnav>
    <div class="header">
      <div class="header-container">
        <div class="logo">
          <div
            title="我的淘宝"
            href="//i.taobao.com/my_taobao.htm?nekot=1470211439696&amp;tracelog=newmytb_logodianji"
            class="tblogo"
          ></div>
        </div>
        <div class="nav">
          <ul class="nav-left">
            <li class="index">首页</li>
            <li>账户设置</li>
          </ul>
          <div class="nav-right">
            <el-input placeholder="请输入内容">
              <template slot="append"> 搜索 </template>
            </el-input>
          </div>
        </div>
      </div>
    </div>
    <div class="main-container">
      <userAside></userAside>
      <div class="main-body">
        <el-tabs v-model="activeName" @tab-click="handleClick">
          <el-tab-pane label="所有订单" name="first">
            <el-row>
              <el-col :span="8">
                <el-input placeholder="请输入内容">
                  <template slot="append"> 订单搜索 </template>
                </el-input></el-col
              >
            </el-row>
            <div class="table">
              <ul class="table-th-container">
                <li class="th-item">宝贝</li>
                <li class="th-2">单价</li>
                <li class="th-2">数量</li>
                <li class="th-3">商品操作</li>
                <li class="th-2">实付款</li>
                <li class="th-3">交易状态</li>
                <li class="th-3">交易操作</li>
              </ul>
              <ul class="table-content-container" v-if="orderlist.length!==0">
                <li
                  class="content-item"
                  v-for="(item, index) in orderlist"
                  :key="index"
                  :class="item.order_status === 0 ? 'opt-remain' : ''"
                >
                  <div class="item-title">
                    <input class="checkbox" type="checkbox" />
                    <span class="orderDate">{
    
    {
    
     item.createTime }}</span>
                    <span>订单号:{
    
    {
    
     item.orderNum }}</span>
                    <span class="shopName">{
    
    {
    
     item.shopName }}</span>
                  </div>
                  <div
                    class="item-body"
                    v-for="(i2, idx) in item.list"
                    :key="idx"
                  >
                    <div class="tbody item-detail">
                      <img :src="`http://127.0.0.1:3007/${i2.picName}`" alt="" />
                      <div class="detail-box">
                        <div class="detail-title">{
    
    {
    
     i2.goodName }}</div>
                        <div class="detail-model">
                          {
    
    {
    
     i2.model }}
                        </div>
                      </div>
                      <div class="item-price t-item">
                        <span class="originalPrice">{
    
    {
    
     i2.priceAgo }}</span>
                        <span>{
    
    {
    
     i2.price }}</span>
                      </div>
                      <div class="t-item">
                        <span>{
    
    {
    
     i2.number }}</span>
                      </div>
                      <div class="t-item t-item-opt">
                        <span>退货/退款</span>
                        <span>投诉卖家</span>
                        <span>运费险已出单</span>
                      </div>
                    </div>
                    <div class="tbody item-sum">
                      <span>{
    
    {
    
     i2.order_sumup }}</span>
                      <span class="note"> (含运费:¥0.00</span>
                    </div>
                    <div class="tbody item-status">
                      <span>快件已签收</span>
                      <span>订单详情</span>
                      <span>查看物流</span>
                    </div>
                  </div>
                  <div class="order-opt">
                    <el-button
                      type="primary"
                      class="btn-1"
                      v-if="item.order_status == 0 && item.is_deliver == 1"
                      @click="changeStatus(item.shopId, item.orderNum)"
                      >确认收货</el-button
                    >
                    <div class="btn-group">
                      <el-button
                        type="warning"
                        class="btn-1 btn-2 btn"
                        v-if="item.order_status == 0 && item.is_pay == 0"
                        @click="handlePay(item.shopId,item.orderNum)"
                        >立即付款</el-button
                      >
                      <el-button
                        type="warning"
                        class="btn-1 btn-2 btn"
                        v-if="item.order_status == 0 && item.is_pay == 1 && item.is_deliver == 0"
                        >催发货</el-button
                      >
                      <el-button
                        type="text"
                        class="btn"
                        v-if="item.order_status == 0 && item.is_pay == 0"
                        >关闭订单</el-button
                      >
                    </div>
                    <el-button
                      type="text"
                      class="btn-1"
                      v-if="item.order_status != 0"
                      >再次购买</el-button
                    >
                  </div>
                </li>
              </ul>
              <div class="nodata-box" v-else>
                <img src="@/assets/images/nodata.png" alt="" >
              </div>
            </div>
          </el-tab-pane>
          <el-tab-pane :label="'待付款 ' + orderStatus.ispay" name="second"
            >
            <div class="table">
              <ul class="table-th-container">
                <li class="th-item">宝贝</li>
                <li class="th-2">单价</li>
                <li class="th-2">数量</li>
                <li class="th-3">商品操作</li>
                <li class="th-2">实付款</li>
                <li class="th-3">交易状态</li>
                <li class="th-3">交易操作</li>
              </ul>
              <ul class="table-content-container" v-if="order2pay.length!==0">
                <li
                  class="content-item"
                  v-for="(item, index) in order2pay"
                  :key="index"
                  :class="item.order_status === 0 ? 'opt-remain' : ''"
                >
                  <div class="item-title">
                    <input class="checkbox" type="checkbox" />
                    <span class="orderDate">{
    
    {
    
     item.createTime }}</span>
                    <span>订单号:{
    
    {
    
     item.orderNum }}</span>
                    <span class="shopName">{
    
    {
    
     item.shopName }}</span>
                  </div>
                  <div
                    class="item-body"
                    v-for="(i2, idx) in item.list"
                    :key="idx"
                  >
                    <div class="tbody item-detail">
                      <img :src="`http://127.0.0.1:3007/${i2.picName}`" alt="" />
                      <div class="detail-box">
                        <div class="detail-title">{
    
    {
    
     i2.goodName }}</div>
                        <div class="detail-model">
                          {
    
    {
    
     i2.model }}
                        </div>
                      </div>
                      <div class="item-price t-item">
                        <span class="originalPrice">{
    
    {
    
     i2.priceAgo }}</span>
                        <span>{
    
    {
    
     i2.price }}</span>
                      </div>
                      <div class="t-item">
                        <span>{
    
    {
    
     i2.number }}</span>
                      </div>
                      <div class="t-item t-item-opt">
                        <span>退货/退款</span>
                        <span>投诉卖家</span>
                        <span>运费险已出单</span>
                      </div>
                    </div>
                    <div class="tbody item-sum">
                      <span>{
    
    {
    
     i2.order_sumup }}</span>
                      <span class="note"> (含运费:¥0.00</span>
                    </div>
                    <div class="tbody item-status">
                      <span>快件已签收</span>
                      <span>订单详情</span>
                      <span>查看物流</span>
                    </div>
                  </div>
                  <div class="order-opt">
                    <div class="btn-group">
                      <el-button
                        type="warning"
                        class="btn-1 btn-2 btn"
                        >立即付款</el-button
                      >
                      <el-button
                        type="text"
                        class="btn"
                        >关闭订单</el-button
                      >
                    </div>
                  </div>
                </li>
              </ul>
              <div class="nodata-box" v-else>
                <img src="@/assets/images/nodata.png" alt="" >
              </div>
            </div>

            </el-tab-pane
          >
          <el-tab-pane :label="'待收货 ' + orderStatus.isdeliver" name="third"
            >
            <div class="table">
              <ul class="table-th-container">
                <li class="th-item">宝贝</li>
                <li class="th-2">单价</li>
                <li class="th-2">数量</li>
                <li class="th-3">商品操作</li>
                <li class="th-2">实付款</li>
                <li class="th-3">交易状态</li>
                <li class="th-3">交易操作</li>
              </ul>
              <ul class="table-content-container" v-if="order2receive.length!==0">
                <li
                  class="content-item"
                  v-for="(item, index) in order2receive"
                  :key="index"
                  :class="item.order_status === 0 ? 'opt-remain' : ''"
                >
                  <div class="item-title">
                    <input class="checkbox" type="checkbox" />
                    <span class="orderDate">{
    
    {
    
     item.createTime }}</span>
                    <span>订单号:{
    
    {
    
     item.orderNum }}</span>
                    <span class="shopName">{
    
    {
    
     item.shopName }}</span>
                  </div>
                  <div
                    class="item-body"
                    v-for="(i2, idx) in item.list"
                    :key="idx"
                  >
                    <div class="tbody item-detail">
                      <img :src="`http://127.0.0.1:3007/${i2.picName}`" alt="" />
                      <div class="detail-box">
                        <div class="detail-title">{
    
    {
    
     i2.goodName }}</div>
                        <div class="detail-model">
                          {
    
    {
    
     i2.model }}
                        </div>
                      </div>
                      <div class="item-price t-item">
                        <span class="originalPrice">{
    
    {
    
     i2.priceAgo }}</span>
                        <span>{
    
    {
    
     i2.price }}</span>
                      </div>
                      <div class="t-item">
                        <span>{
    
    {
    
     i2.number }}</span>
                      </div>
                      <div class="t-item t-item-opt">
                        <span>退货/退款</span>
                        <span>投诉卖家</span>
                        <span>运费险已出单</span>
                      </div>
                    </div>
                    <div class="tbody item-sum">
                      <span>{
    
    {
    
     i2.order_sumup }}</span>
                      <span class="note"> (含运费:¥0.00</span>
                    </div>
                    <div class="tbody item-status">
                      <span>快件已签收</span>
                      <span>订单详情</span>
                      <span>查看物流</span>
                    </div>
                  </div>
                  <div class="order-opt">
                    <el-button
                      type="primary"
                      class="btn-1"
                      @click="changeStatus(item.shopId, item.orderNum)"
                      >确认收货</el-button
                    >
                  </div>
                </li>
              </ul>
              <div class="nodata-box" v-else>
                <img src="@/assets/images/nodata.png" alt="" >
              </div>
            </div>
            </el-tab-pane
          >
          <el-tab-pane label="待评价" name="fourth">定时任务补偿</el-tab-pane>
        </el-tabs>
      </div>
    </div>
  </div>
</template>
<script>
import topnav from '@/components/topnav.vue'
import userAside from '@/components/userAside.vue'
export default {
    
    
  components: {
    
    
    topnav,
    userAside
  },
  data () {
    
    
    return {
    
    
      userinfo: {
    
    },
      activeName: 'first',
      orderlist: [],
      orderStatus: {
    
    },
      order2pay: [],
      order2receive:[]
    }
  },
  created () {
    
    
    this.userinfo = JSON.parse(sessionStorage.getItem('userinfo'))
    this.getUserOrder()
    this.getOrderStatus()
  },
  computed: {
    
    },
  methods: {
    
    
    async getUserOrder () {
    
    
      const {
    
     data: res } = await this.$http.post('/order/getUserOrder', {
    
    
        id: this.userinfo.id
      })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.orderlist = res.data
    },
    async changeStatus (shopId, orderNum) {
    
    
      this.$confirm('是否确认收货?', '提示', {
    
    
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
    
    
          const {
    
     data: res } = await this.$http.post('/order/change2finish', {
    
    
            userId: this.userinfo.id,
            shopId: shopId,
            orderNum: orderNum
          })
          if (res.code !== 200) {
    
    
            return this.$message.error(res.msg)
          }
          this.getUserOrder()
          this.getOrderStatus()
        })
        .catch(() => {
    
    })
    },
    async getOrderStatus () {
    
    
      const {
    
     data: res } = await this.$http.post('/order/getOrderStatus', {
    
    
        id: this.userinfo.id
      })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.orderStatus = res.data
    },
    async get2payOrder () {
    
    
      const {
    
     data: res } = await this.$http.post('/order/get2payOrder', {
    
     id: this.userinfo.id })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.order2pay = res.data
    },
    async get2deliver () {
    
    
      const {
    
     data: res } = await this.$http.post('/order/get2receive', {
    
     id: this.userinfo.id })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.order2receive = res.data
    },
    handleClick (tab, event) {
    
    
      if (tab.name === 'second') {
    
    
        this.get2payOrder()
      } else if (tab.name === 'third') {
    
    
        this.get2deliver()
      }
    },
    async handlePay (shopId, orderNum) {
    
    
      const {
    
     data: res } = await this.$http.post('/order/change2deliver', {
    
    
        userId: this.userinfo.id,
        shopId: shopId,
        orderNum: orderNum
      })
      if (res.code !== 200) {
    
    
        return this.$message.error(res.msg)
      }
      this.getUserOrder()
      this.getOrderStatus()
    }
  }
}
</script>

Some pages have been written in the background part, so I replaced the test data with interfaces, and some pages have not yet.

source code address

https://gitee.com/lyy_97591/node_vue.git

Guess you like

Origin blog.csdn.net/qq_46258819/article/details/127242098