VUE+Nodejs 商城项目练习项目(前台购物)

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

项目结构

在这里插入图片描述

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

帐号密码登录

在这里插入图片描述

扫码登录

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述在这里插入图片描述

部分代码
<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)

在这里插入图片描述

源代码
<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>

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

在这里插入图片描述在这里插入图片描述

源代码
<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)

在这里插入图片描述

源代码
<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>

我的订单

在这里插入图片描述在这里插入图片描述在这里插入图片描述

部分源代码
<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>

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

源代码地址

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

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要下载Vue Node.js MySQL项目,您需要按照以下步骤进行操作: 1. 首先,确保您已经安装了Node.js和MySQL数据库。如果没有,请前往它们的官方网站并按照说明进行安装。 2. 打开您的命令行终端,创建一个新的项目文件夹。您可以使用以下命令创建一个名为"my-project"的文件夹: ``` mkdir my-project ``` 3. 进入新创建的项目文件夹: ``` cd my-project ``` 4. 使用以下命令初始化一个新的Node.js项目: ``` npm init -y ``` 这将会自动生成一个默认的`package.json`文件。 5. 安装Vue.js。使用以下命令将Vue.js添加到您的项目中: ``` npm install vue ``` 6. 安装Express框架,用于构建服务器端应用。使用以下命令将Express添加到您的项目中: ``` npm install express ``` 7. 安装mysql模块,用于连接和操作MySQL数据库。使用以下命令将mysql模块添加到您的项目中: ``` npm install mysql ``` 8. 创建一个新的JavaScript文件,例如`app.js`,并打开它。 9. 在`app.js`中编写您的服务器端代码,包括Vue.js前端代码和与MySQL数据库的交互。您可以根据您的项目需求编写自定义的代码。 10. 保存`app.js`文件并返回终端。 11. 在终端中运行以下命令以启动服务器: ``` node app.js ``` 12. 当服务器启动成功后,您将看到一个成功的消息。此时,您可以在浏览器中访问`http://localhost:3000`来查看您的Vue Node.js MySQL项目。 总结一下,下载Vue Node.js MySQL项目的步骤包括:创建项目文件夹,初始化Node.js项目,安装Vue.js、Express和mysql模块,编写服务器端代码,启动服务器并在浏览器中查看项目。这样,您就可以成功下载和运行Vue Node.js MySQL项目了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值