首页 > 开发 > JS > 正文

node和vue实现商城用户地址模块

2024-05-06 16:47:02
字体:
来源:转载
供稿:网友

本文为大家分享了node和vue商城用户地址模块的实现,供大家参考,具体内容如下

server/models/user.js

var mongoose = require('mongoose')var userSchema = mongoose.Schema({  "userId":String,  // 用户Id  "userName":String, // 用户名  "userPwd":String, // 用户密码  "orderList":Array, // 订单列表  "cartList":[ // 购物车列表    {      "productId": String, // 商品Id      "productName": String, // 商品名称      "salePrice":String, // 商品价格      "productImage":String, // 图片地址      "checked":String, // 是否选中      "productNum":String // 商品数量    }  ],  "addressList":[ // 用户地址列表   {    "addressId": String,    "userName": String,    "streetName": String,    "postCode": Number,    "tel": Number,    "isDefault": Boolean   }  ]}); // 通过module.exports进行输出,这样才能加载到 三个参数分别是 模型名,userSchema名,管理数据库集合名module.exports = mongoose.model("User",userSchema,"users");

server/routes/users.js

var express = require('express');var router = express.Router(); var User = require('./../models/user'); /* GET users listing. */router.get('/', function(req, res, next) { res.send('respond with a resource');}); router.get('/test', function(req, res, next) { res.send('test');}); // 登录router.post('/login', function(req, res, next) { // 获取前端传过来的参数 post方式用req.Body形式获取参数 var param = {  userName:req.body.userName,  userPwd:req.body.userPwd } User.findOne(param, function(err,doc) {  if(err){   res.json({    status:"1",    msg:err.message   });  }else{    if(doc){     res.cookie("userId",doc.userId,{ // 将用户信息存入cookie      path:'/',      maxAge: 1000*60*60     });      res.cookie("userName",doc.userName, {      path:'/',      maxAge: 1000*60*60     });     // req.session.user = doc; // 将用户信息存入session     res.json({      status:'0',      msg:'',      result:{       userName:doc.userName      }     })    }  } });}); // 登出接口router.post("/logout", function (req,res,next) { res.cookie("userId", "", { // 登出将userId设置为""  path:"/",  maxAge:-1 // 设置位过期 }) res.json({  status:"0",  msg:'',  result:'' })}) // 校验用户信息router.get("/checkLogin", function (req,res,next) {  if(req.cookies.userId){   res.json({    status:'0',    msg:'',    result: req.cookies.userName || '' // 获取cookeie req.cookies.属性   });  }else{ // 取不到就说明当前没有登录   res.json({    status:'1',    msg:'未登录',    result:''   });  }}) // 查询当前用户的购物车数据router.get("/cartList", function (req,res,next) { var userId = req.cookies.userId; console.log(userId); User.findOne({userId:userId}, function (err,doc) {   if(err){    res.json({     status:'1',     msg:err.message,     result:''    });   }else{     if(doc){      res.json({       status:'0',       msg:'',       result:doc.cartList      });     }   } });}); // 购物车删除router.post("/cartDel", function (req,res,next) { // 获取浏览器的cookie 以及用户传递过来的参数 productId var userId = req.cookies.userId,productId = req.body.productId; User.update({  userId:userId },{  $pull:{   'cartList':{    'productId':productId   }  } }, function (err,doc) {  if(err){   res.json({    status:'1',    msg:err.message,    result:''   });  }else{   res.json({    status:'0',    msg:'',    result:'suc'   });  } });}); //修改购物车商品数量router.post("/cartEdit", function (req,res,next) { var userId = req.cookies.userId,   // 获取用户客户端的userId   productId = req.body.productId, // 获取用户传的参数商品id   productNum = req.body.productNum, // 获取用户传的参数商品id   checked = req.body.checked;    // 获取用户传的参数是否选中 User.update({  "userId":userId,  "cartList.productId":productId},{  "cartList.$.productNum":productNum,  "cartList.$.checked":checked, }, function (err,doc) {  if(err){   res.json({    status:'1',    msg:err.message,    result:''   });  }else{   res.json({    status:'0',    msg:'',    result:'suc'   });  } })}); // 商品全选不选router.post("/editCheckAll", function (req,res,next) { var userId = req.cookies.userId,   checkAll = req.body.checkAll?'1':'0'; User.findOne({userId:userId}, function (err,user) {  if(err){   res.json({    status:'1',    msg:err.message,    result:''   });  }else{   if(user){    user.cartList.forEach((item)=>{     item.checked = checkAll;    })    user.save(function (err1,doc) {      if(err1){       res.json({        status:'1',        msg:err1,message,        result:''       });      }else{       res.json({        status:'0',        msg:'',        result:'suc'       });      }    })   }  } });}); // 用户地址模块开始-----------------------------------------------------------------------------------------------// 查询用户地址接口router.get("/addressList", function (req,res,next) { var userId = req.cookies.userId; User.findOne({userId:userId}, function (err,doc) {  if(err){   res.json({    status:'1',    msg:err.message,    result:''   });  }else{   res.json({    status:'0',    msg:'',    result:doc.addressList   });  } })}); // 设置默认地址router.post("/setDefault", function (req,res,next) { var userId = req.cookies.userId,   addressId = req.body.addressId; if(!addressId){  res.json({   status:'1003',   msg:'addressId is null',   result:''  }); }else{  User.findOne({userId:userId}, function (err,doc) {   if(err){    res.json({     status:'1',     msg:err.message,     result:''    });   }else{    var addressList = doc.addressList;    addressList.forEach((item)=>{     if(item.addressId == addressId){       item.isDefault = true;     }else{      item.isDefault = false;     }    });     doc.save(function (err1,doc1) {     if(err){      res.json({       status:'1',       msg:err.message,       result:''      });     }else{       res.json({        status:'0',        msg:'',        result:''       });     }    })   }  }); }}); // 删除地址接口 router.post("/delAddress", function (req,res,next) { var userId = req.cookies.userId,addressId = req.body.addressId; User.update({  userId:userId },{  $pull:{ // 删除子文档元素   'addressList':{    'addressId':addressId   }  } }, function (err,doc) {   if(err){    res.json({      status:'1',      msg:err.message,      result:''    });   }else{    res.json({     status:'0',     msg:'',     result:''    });   } });});// 用户地址模块开始-----------------------------------------------------------------------------------------------  module.exports = router;

vue 前端部分

src/router/index.js 路由

import Vue from 'vue'import Router from 'vue-router'import GoodsList from './../views/GoodsList.vue'import Cart from '@/views/Cart.vue'import Address from '@/views/Address'Vue.use(Router); export default new Router({  routes: [    {      path: '/',      name: 'GoodsList',      component:GoodsList    },    {      path: '/cart',      name: 'Cart',      component:Cart    },    {      path: '/address',      name: 'Address',      component:Address    }  ]})

src/views/Address.vue

<template>  <div>   <nav-header></nav-header>   <nav-bread>    <span>Address</span>   </nav-bread>   <div class="checkout-page">    <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">     <defs>      <symbol id="icon-add" viewBox="0 0 31 32">       <title>add</title>       <path class="path1" d="M30.745 15.152h-14.382v-14.596c0-0.308-0.243-0.557-0.543-0.557s-0.543 0.249-0.543 0.557v14.596h-14.665c-0.3 0-0.543 0.249-0.543 0.557s0.243 0.557 0.543 0.557h14.665v15.177c0 0.307 0.243 0.557 0.543 0.557s0.543-0.249 0.543-0.557v-15.177h14.382c0.3 0 0.543-0.249 0.543-0.557s-0.243-0.557-0.543-0.557z"></path>      </symbol>      <symbol id="icon-ok" viewBox="0 0 32 32">       <title>ok</title>       <path class="path1" d="M14.084 20.656l-7.845-9.282c-1.288-1.482-3.534-1.639-5.016-0.351s-1.639 3.534-0.351 5.016l10.697 12.306c1.451 1.669 4.057 1.623 5.448-0.096l18.168-22.456c1.235-1.527 0.999-3.765-0.528-5.001s-3.765-0.999-5.001 0.528l-15.573 19.337z"></path>      </symbol>      <symbol id="icon-edit" viewBox="0 0 32 32">       <title>edit</title>       <path class="path1" d="M28.287 8.51l-4.805-4.806 0.831-0.831c0.472-0.472 1.086-0.777 1.564-0.777 0.248 0 0.452 0.082 0.622 0.253l3.143 3.144c0.539 0.54 0.133 1.529-0.524 2.186l-0.831 0.831zM26.805 9.992l-1.138 1.138-4.805-4.806 1.138-1.138 4.805 4.806zM24.186 12.612l-14.758 14.762-4.805-4.806 14.758-14.762 4.805 4.806zM7.379 28.288l-4.892 1.224 1.223-4.894 3.669 3.67zM31.123 4.011l-3.143-3.144c-0.567-0.567-1.294-0.867-2.103-0.867-1.036 0-2.174 0.52-3.045 1.391l-20.429 20.436c-0.135 0.134-0.23 0.302-0.276 0.487l-2.095 8.385c-0.089 0.355 0.017 0.736 0.276 0.995 0.198 0.198 0.461 0.307 0.741 0.307 0.085 0 0.171-0.010 0.254-0.031l8.381-2.096c0.185-0.047 0.354-0.142 0.487-0.276l20.43-20.436c1.409-1.41 2.042-3.632 0.524-5.15v0z"></path>      </symbol>      <symbol id="icon-del" viewBox="0 0 32 32">       <title>delete</title>       <path class="path1" d="M11.355 4.129v-2.065h9.29v2.065h-9.29zM6.194 29.935v-23.742h19.613v23.742h-19.613zM30.968 4.129h-8.258v-3.097c0-0.569-0.463-1.032-1.032-1.032h-11.355c-0.569 0-1.032 0.463-1.032 1.032v3.097h-8.258c-0.569 0-1.032 0.463-1.032 1.032s0.463 1.032 1.032 1.032h3.097v24.774c0 0.569 0.463 1.032 1.032 1.032h21.677c0.569 0 1.032-0.463 1.032-1.032v-24.774h3.097c0.569 0 1.032-0.463 1.032-1.032s-0.463-1.032-1.032-1.032v0z"></path>       <path class="path2" d="M10.323 9.806c-0.569 0-1.032 0.463-1.032 1.032v14.452c0 0.569 0.463 1.032 1.032 1.032s1.032-0.463 1.032-1.032v-14.452c0-0.569-0.463-1.032-1.032-1.032z"></path>       <path class="path3" d="M16 9.806c-0.569 0-1.032 0.463-1.032 1.032v14.452c0 0.569 0.463 1.032 1.032 1.032s1.032-0.463 1.032-1.032v-14.452c0-0.569-0.463-1.032-1.032-1.032z"></path>       <path class="path4" d="M21.677 9.806c-0.569 0-1.032 0.463-1.032 1.032v14.452c0 0.569 0.463 1.032 1.032 1.032s1.032-0.463 1.032-1.032v-14.452c0-0.569-0.463-1.032-1.032-1.032z"></path>      </symbol>      <symbol id="icon-clock" viewBox="0 0 32 32">       <title>clock</title>       <path class="path1" d="M29.333 16c0-7.364-5.97-13.333-13.333-13.333s-13.333 5.97-13.333 13.333c0 7.364 5.97 13.333 13.333 13.333s13.333-5.97 13.333-13.333v0 0 0 0 0 0zM0 16c0-8.837 7.163-16 16-16s16 7.163 16 16c0 8.837-7.163 16-16 16s-16-7.163-16-16zM14.667 14.667v1.333h2.667v-10.667h-2.667v9.333zM24 18.667h1.333v-2.667h-10.667v2.667h9.333z"></path>      </symbol>      <symbol id="icon-question" viewBox="0 0 32 32">       <title>question</title>       <path class="path1" d="M16 2.56c7.411 0 13.44 6.029 13.44 13.44s-6.029 13.44-13.44 13.44c-7.411 0-13.44-6.029-13.44-13.44s6.029-13.44 13.44-13.44zM16 0c-8.822 0-16 7.178-16 16s7.178 16 16 16c8.822 0 16-7.178 16-16s-7.178-16-16-16z"></path>       <path class="path2" d="M16 22.080c-1.059 0-1.92 0.861-1.92 1.92s0.861 1.92 1.92 1.92c1.059 0 1.92-0.861 1.92-1.92s-0.861-1.92-1.92-1.92z"></path>       <path class="path3" d="M12.16 12.48c0.706 0 1.28-0.574 1.28-1.28 0-1.412 1.148-2.56 2.56-2.56s2.56 1.148 2.56 2.56c0 1.412-1.148 2.56-2.56 2.56-0.706 0-1.28 0.574-1.28 1.28v3.84c0 0.706 0.574 1.28 1.28 1.28s1.28-0.574 1.28-1.28v-2.723c2.224-0.575 3.84-2.616 3.84-4.957 0-2.823-2.297-5.12-5.12-5.12s-5.12 2.297-5.12 5.12c0 0.706 0.574 1.28 1.28 1.28z"></path>      </symbol>     </defs>    </svg>    <div class="container">     <div class="checkout-addr">      <div class="page-title-normal">       <h2 class="page-title-h2"><span>check out</span></h2>      </div>      <!-- process step -->      <div class="check-step">       <ul>        <li class="cur"><span>Confirm</span> address</li>        <li><span>View your</span> order</li>        <li><span>Make</span> payment</li>        <li><span>Order</span> confirmation</li>       </ul>      </div>       <!-- address list -->      <div class="page-title-normal checkout-title">       <h2><span>Shipping address</span></h2>      </div>      <div class="addr-list-wrap">       <div class="addr-list">        <ul>         <li v-for="(item,index) in addressListFilter" :key="index" v-bind:class="{'check':checkIndex==index}" @click="checkIndex=index;selectedAddrId=item.addressId">          <dl>           <dt>{{item.userName}}</dt>           <dd class="address">{{item.streetName}}</dd>           <dd class="tel">{{item.tel}}</dd>          </dl>          <div class="addr-opration addr-del">           <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="addr-del-btn" @click="delAddressConfirm(item.addressId)">            <svg class="icon icon-del"><use xlink:href="#icon-del" rel="external nofollow" ></use></svg>           </a>          </div>          <div class="addr-opration addr-set-default">           <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="addr-set-default-btn" v-if="!item.isDefault" @click="setDefault(item.addressId)"><i>Set default</i></a>          </div>          <div class="addr-opration addr-default" v-if="item.isDefault">Default address</div>         </li>         <li class="addr-new">          <div class="add-new-inner">           <i class="icon-add">            <svg class="icon icon-add"><use xlink:href="#icon-add" rel="external nofollow" ></use></svg>           </i>           <p>Add new address</p>          </div>         </li>        </ul>       </div>        <div class="shipping-addr-more">        <a class="addr-more-btn up-down-btn" href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="expand" v-bind:class="{'open':limit>3}">         more         <i class="i-up-down">          <i class="i-up-down-l"></i>          <i class="i-up-down-r"></i>         </i>        </a>       </div>      </div>       <!-- shipping method-->      <div class="page-title-normal checkout-title">       <h2><span>Shipping method</span></h2>      </div>      <div class="shipping-method-wrap">       <div class="shipping-method">        <ul>         <li class="check">          <div class="name">Standard shipping</div>          <div class="price">Free</div>          <div class="shipping-tips">           <p>Once shipped,Order should arrive in the destination in 1-7 business days</p>          </div>         </li>        </ul>       </div>      </div>      <div class="next-btn-wrap">       <router-link class="btn btn--m btn--red" v-bind:to="{path:'orderConfirm',query:{'addressId':selectedAddrId}}">Next</router-link>      </div>     </div>    </div>   </div>   <modal :mdShow="isMdShow" @close="closeModal">    <p slot="message">     您是否确认要删除此地址?    </p>    <div slot="btnGroup">      <a class="btn btn--m" href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="delAddress">确认</a>      <a class="btn btn--m btn--red" href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="isMdShow=false">取消</a>    </div>   </modal>   <nav-footer></nav-footer>  </div></template><style></style><script> import NavHeader from './../components/NavHeader' import NavFooter from './../components/NavFooter' import NavBread from './../components/NavBread' import Modal from './../components/Modal' import {currency} from './../util/currency' import axios from 'axios' export default{   data(){     return{       limit:3,       checkIndex:0, // 默认选中第一个地址       selectedAddrId:'',       addressList:[],       isMdShow:false,       addressId:''     }   },   mounted(){     this.init();   },   computed:{    addressListFilter(){ // 动态计算,默认显示3条地址数据     return this.addressList.slice(0,this.limit); // 默认显示3条数据    }   },  components:{    NavHeader,    NavFooter,    NavBread,    Modal   },   methods:{     init(){       axios.get("/users/addressList").then((response)=>{ // 获取用户地址列表         let res = response.data;         this.addressList = res.result;         this.selectedAddrId = this.addressList[0].addressId;         for(var i=0;i<this.addressList.length;i++){           if(this.addressList[i].isDefault){             this.checkIndex = i;           }         }       });     },     expand(){ // 展开和收起地址列表       if(this.limit==3){        this.limit = this.addressList.length;       }else{        this.limit = 3;       }     },     setDefault(addressId){ // 设置默认地址       axios.post("/users/setDefault",{        addressId:addressId       }).then((response)=>{         let res = response.data;         if(res.status=='0'){           console.log("set default");           this.init();         }       })     },     closeModal(){ // 管理删除地址提示弹框       this.isMdShow = false;     },     delAddressConfirm(addressId){ // 弹出模态框 选中删除的地址      this.isMdShow = true;      this.addressId = addressId;     },     delAddress(){ // 删除该地址      axios.post("/users/delAddress",{       addressId:this.addressId      }).then((response)=>{        let res = response.data;        if(res.status=="0"){         console.log("del suc");         this.isMdShow = false;         this.init();        }      })     }   } }</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到JavaScript/Ajax教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表