VUE+Nodejs 商城项目练习项目

文章目录

      • 项目结构
      • 登录页面(@/view/shop/login.vue)
        • 帐号密码登录
        • 扫码登录
      • 注册页面(@/view/shop/register.vue)
      • 首页(@/view/shop/index.vue)
        • 部分代码
      • 用户中心(@/view/shop/userInfo.vue)
        • 源代码
      • 购物车(@/view/shop/shopcart.vue)
        • 源代码
      • 提交页面(@/view/shop/settlement.vue)
        • 源代码
      • 我的订单
        • 部分源代码

vue和node的学习基本已经结束了,本项目是模仿淘宝商城进行练习,由于是新手脱离视频教程的第一个实践项目所以代码上面还有很多问题,请多指教。本文章所有的图片以及代码等仅作为学习使用,不作为商业目的,如有侵权请联系我删除!所提供的代码仅供参考

项目结构

VUE+Nodejs 商城项目练习项目_第1张图片

登录页面(@/view/shop/login.vue)

帐号密码登录

VUE+Nodejs 商城项目练习项目_第2张图片

扫码登录

VUE+Nodejs 商城项目练习项目_第3张图片

注册页面(@/view/shop/register.vue)

VUE+Nodejs 商城项目练习项目_第4张图片

首页(@/view/shop/index.vue)

VUE+Nodejs 商城项目练习项目_第5张图片

部分代码

<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>

用户中心(@/view/shop/userInfo.vue)

VUE+Nodejs 商城项目练习项目_第6张图片

源代码

<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&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>

购物车(@/view/shop/shopcart.vue)

VUE+Nodejs 商城项目练习项目_第7张图片VUE+Nodejs 商城项目练习项目_第8张图片

源代码

<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>

提交页面(@/view/shop/settlement.vue)

VUE+Nodejs 商城项目练习项目_第9张图片

源代码

<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>

我的订单

VUE+Nodejs 商城项目练习项目_第10张图片VUE+Nodejs 商城项目练习项目_第11张图片VUE+Nodejs 商城项目练习项目_第12张图片

部分源代码

<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&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>

有些页面后台部分写了一些所以测试的数据我替换成接口了,有些页面还没有。

你可能感兴趣的:(VUE,vue.js,前端,javascript)