Vue nodejs商城-订单模块

一、订单列表渲染

新建OrderConfirm.vue订单确认页面,添加路由

src/router/index.js添加路由

  1. import OrderConfirm from '@/views/OrderConfirm' // 订单确认页面
  2.  
  3. export default new Router({
  4.   routes: [
  5.     {
  6.       path: '/orderConfirm', // 订单确认页面路由
  7.       name: 'OrderConfirm',
  8.       component: OrderConfirm
  9.     }
  10.   ]
  11. })

src/views/OrderConfirm.vue 
要获取订单列表,不需要再重新写接口,只需要使用查询购物车列表的接口,提取出购物车列表。在渲染时页面时,判断选中的商品才显示
v-if="item.checked=='1'"
对于一些价格数字不要忘记格式化,使用过滤器对价格进行格式化。

  1. <!--列表渲染-->
  2. <ul class="cart-item-list">
  3.     <li v-for="item in cartList" v-if="item.checked=='1'">
  4.         <!-- 商品图片和商品名称 -->
  5.         <div class="cart-tab-1">
  6.             <div class="cart-item-pic">
  7.                 <img :src="'/static/'+item.productImage" :alt="item.productName">
  8.             </div>
  9.             <div class="cart-item-title">
  10.                 <div class="item-name">{{item.productName}}</div>
  11.             </div>
  12.         </div>
  13.         <!-- 商品单价 -->
  14.         <div class="cart-tab-2">
  15.             <div class="item-price">{{item.salePrice | currency('$')}}</div>
  16.         </div>
  17.         <!-- 商品数量 -->
  18.         <div class="cart-tab-3">
  19.             <div class="item-quantity">
  20.                 <div class="select-self">
  21.                     <div class="select-self-area">
  22.                         <span class="select-ipt">×{{item.productNum}}</span>
  23.                     </div>
  24.                 </div>
  25.                 <div class="item-stock item-stock-no">In Stock</div>
  26.             </div>
  27.         </div>
  28.         <!-- 商品总金额 -->
  29.         <div class="cart-tab-4">
  30.             <div class="item-price-total">{{(item.salePrice*item.productNum) | currency('$')}}</div>
  31.         </div>
  32.     </li>
  33. </ul>
  34.  
  35.  
  36. <!-- Price count -->
  37. <div class="price-count-wrap">
  38.     <div class="price-count">
  39.       <ul>
  40.         <li>
  41.           <span>Item subtotal:</span> <!-- 订单总金额 -->
  42.           <span>{{subTotal | currency('$')}}</span>
  43.         </li>
  44.         <li>
  45.           <span>Shipping:</span> <!-- 配送费 -->
  46.           <span>{{shipping | currency('$')}}</span>
  47.         </li>
  48.         <li>
  49.           <span>Discount:</span> <!-- 折扣 -->
  50.           <span>{{discount | currency('$')}}</span>
  51.         </li>
  52.         <li>
  53.           <span>Tax:</span> <!-- 税费 -->
  54.           <span>{{tax | currency('$')}}</span>
  55.         </li>
  56.         <li class="order-total-price">
  57.           <span>Order total:</span> <!-- 用户支付总金额 -->
  58.           <span>{{orderTotal | currency('$')}}</span>
  59.         </li>
  60.       </ul>
  61.     </div>
  62. </div>
  63.  
  64. import axios from 'axios'
  65. import {currency} from '@/util/currency.js' // 对价格格式化的通用方法
  66.  
  67. export default {
  68.     data(){
  69.       return {
  70.         shipping: 100, // 配送费
  71.         discount:200, // 折扣
  72.         tax:400, // 扣税
  73.  
  74.         subTotal:0, // 订单总金额(是购物车选中商品的总金额)
  75.  
  76.         orderTotal:0, // 总金额+配送费-折扣+税费 = orderTotal用户需要支付的金额,默认为0
  77.  
  78.         cartList:[] // 购物车列表
  79.       }
  80.     },
  81.     mounted(){
  82.       this.init();
  83.     },
  84.     filters:{ // 定义局部过滤器
  85.       currency:currency // currency.js传过来的本就是函数
  86.     },
  87.     methods:{
  88.       init(){
  89.         axios.get('/users/cartList').then((response)=>{ // 订单确认列表不需要再写接口,直接用购物车列表的接口,渲染页面时选取选中的商品作为订单确认的商品
  90.           let res= response.data;
  91.           this.cartList = res.result;
  92.  
  93.           this.cartList.forEach((item)=>{ // 遍历购物车商品,获取选中商品的总金额
  94.             if(item.checked == '1'){
  95.               this.subTotal += item.salePrice*item.productNum;
  96.             }
  97.           })
  98.  
  99.           this.orderTotal = this.subTotal+this.shipping-this.discount+this.tax; // 获取用户最终支付的金额,(总金额+配送费-折扣+税费)
  100.         })
  101.       }
  102.     }
  103. }

 

二、创建订单功能实现

(1)点击支付跳转到支付页面,支付是由第三方做的集成的支付,没办法模拟复杂的支付场景,现在只做点击支付创建订单和跳转到成功页面,支付功能省略掉。 

(2)
生成的订单里面有订单生成的时间,首先需要有对时间格式化的函数方法。

时间格式化server/util/util.js

  1. /**
  2.  * Created by jacksoft on 17/4/26.
  3.  * 直接对Date对象原型添加方法
  4.  */
  5. Date.prototype.Format = function (fmt) {
  6.   var o = {
  7.     "M+": this.getMonth() + 1, //月份
  8.     "d+": this.getDate(), //日
  9.     "h+": this.getHours(), //小时
  10.     "m+": this.getMinutes(), //分
  11.     "s+": this.getSeconds(), //秒
  12.     "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  13.     "S": this.getMilliseconds() //毫秒
  14.   };
  15.   if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  16.   for (var k in o)
  17.     if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  18.   return fmt;
  19. }
  20.  
  21. module.exports = {};

 

订单生成接口 server/routes/users.js
订单生成是将订单信息(包含订单Id/订单总金额/地址信息/下单的商品信息/订单状态/订单创建时间等)存入数据库。

  1. require('./../util/util'); // 引入格式化函数
  2.  
  3. // 创建订单功能
  4. router.post('/payMent', function(req,res,next){
  5.     // 前端传参:订单的地址id;订单最终的总金额
  6.     var userId = req.cookies.userId,
  7.         addressId = req.body.addressId,
  8.         orderTotal = req.body.orderTotal;
  9.     User.findOne({userId:userId}, function(err,doc){
  10.         if(err){
  11.             res.json({
  12.                 status:'1',
  13.                 msg:err.message,
  14.                 result:''
  15.             })
  16.         }else{
  17.             var address = '',goodsList = [];
  18.             // 获取当前用户的地址信息
  19.             doc.addressList.forEach((item)=>{
  20.                 if(addressId == item.addressId){
  21.                     address = item;
  22.                 }
  23.             })
  24.             // 获取当前用户的购物车的购买商品
  25.             doc.cartList.filter((item)=>{
  26.                 if(item.checked == '1'){
  27.                     goodsList.push(item);
  28.                 }
  29.             })
  30.  
  31.             //创建订单Id
  32.             var platform = '622'; // 平台系统架构码
  33.             var r1 = Math.floor(Math.random()*10);
  34.             var r2 = Math.floor(Math.random()*10);
  35.  
  36.             var sysDate = new Date().Format('yyyyMMddhhmmss'); // 系统时间:年月日时分秒
  37.             var orderId = platform+r1+sysDate+r2; // 21位
  38.  
  39.             // 订单创建时间
  40.             var createDate = new Date().Format('yyyy-MM-dd hh:mm:ss');
  41.  
  42.             // 生成订单
  43.             var order = {
  44.                 orderId:orderId, // 订单id
  45.                 orderTotal:orderTotal, // 订单总金额(直接拿前端传过来的参数)
  46.                 addressInfo:address, // 地址信息
  47.                 goodsList:goodsList, // 购买的商品信息
  48.                 orderStatus:'1', // 订单状态,1成功
  49.                 createDate:createDate // 订单创建时间
  50.             }
  51.  
  52.             // 订单信息存储到数据库
  53.             doc.orderList.push(order);
  54.  
  55.             doc.save(function (err1,doc1) {
  56.                 if(err1){
  57.                     res.json({
  58.                         status:"1",
  59.                         msg:err.message,
  60.                         result:''
  61.                     });
  62.                 }else{
  63.                     // 返回订单的id和订单的总金额给前端,下一个页面要用到
  64.                     res.json({
  65.                         status:"0",
  66.                         msg:'',
  67.                         result:{
  68.                             orderId:order.orderId,
  69.                             orderTotal:order.orderTotal
  70.                         }
  71.                     });
  72.                 }
  73.             });
  74.         }
  75.     })
  76. })

 

src/views/OrderConfirm.vue
传参要传订单的地址id和订单的总金额
订单的地址id从订单页面的路由获取参数id http://localhost:8080/#/orderConfirm?addressId=100001 100001,
this.$route.query.addressId
成功时跳转到订单成功页面
this.$router.push({path:'/orderSuccess?orderId='+res.result.orderId})

  1. // 点击支付按钮
  2. payMent(){ // 点击支付
  3.  
  4.     // 从路由那里获取到订单地址的id
  5.     // http://localhost:8080/#/orderConfirm?addressId=100001
  6.     var addressId = this.$route.query.addressId;
  7.  
  8.     axios.post('/users/payMent',{
  9.       addressId:addressId,
  10.       orderTotal:this.orderTotal
  11.     }).then((response)=>{
  12.       let res = response.data;
  13.       if(res.status == '0'){
  14.         console.log('order created success');
  15.  
  16.         // 路由跳转到订单成功页面
  17.         this.$router.push({
  18.           path:'/orderSuccess?orderId='+res.result.orderId
  19.         })
  20.       }
  21.     })
  22. }

点击支付按钮,请求成功,返回生成的订单Id(orderId)和订单总金额(orderTotal)。订单Id=6221201801252245492,622=平台架构码/1=随机数r1/20180125224549=年月日时分秒/2=随机数r2

跳转到订单成功页面
 

订单生成存储到了数据库

三、订单成功页面

新建订单成功页面组件src/views/orderSuccess.vue,添加页面路由

src/router/index.js

  1. import OrderSuccess from '@/views/OrderSuccess' // 订单成功页面
  2.  
  3. export default new Router({
  4.   routes: [
  5.     {
  6.       path: '/orderSuccess', // 订单成功頁面
  7.       name: 'OrderSuccess',
  8.       component: OrderSuccess
  9.     }
  10.   ]
  11. })

后端接口server/routes/users.js,根据前端传的订单Id查询订单信息

  1. //根据订单Id查询订单信息
  2. router.get("/orderDetail", function (req,res,next) {
  3.     var userId = req.cookies.userId,
  4.         orderId = req.param("orderId"); // 前端传过来的订单id
  5.     User.findOne({userId:userId}, function (err,userInfo) {
  6.         if(err){
  7.             res.json({
  8.                 status:'1',
  9.                 msg:err.message,
  10.                 result:''
  11.             });
  12.         }else{
  13.             var orderList = userInfo.orderList; // orderList订单列表
  14.             if(orderList.length>0){ // 说明有订单
  15.                 var orderTotal = 0;
  16.                 // 遍历订单列表,根据订单id得到该订单总金额orderTotal
  17.                 orderList.forEach((item)=>{
  18.                     if(item.orderId == orderId){
  19.                         orderTotal = item.orderTotal;
  20.                     }
  21.                 });
  22.                 if(orderTotal>0){
  23.                     res.json({
  24.                         status:'0',
  25.                         msg:'',
  26.                         result:{
  27.                             orderId:orderId,
  28.                             orderTotal:orderTotal
  29.                         }
  30.                     })
  31.                 }else{
  32.                     res.json({
  33.                         status:'120002',
  34.                         msg:'无此订单',
  35.                         result:''
  36.                     });
  37.                 }
  38.             }else{
  39.                 res.json({
  40.                     status:'120001',
  41.                     msg:'当前用户未创建订单',
  42.                     result:''
  43.                 });
  44.             }
  45.         }
  46.     })
  47. });

前端页面初始化时get请求,传参订单id,返回订单的总金额渲染页面。订单的id从路由获取,http://localhost:8080/#/orderSuccess?orderId=6221201801252245492 中的orderIdthis.$route.query.orderId

  1. <p>
  2.     <span>Order ID:{{orderId}}</span>
  3.     <span>Order total:{{orderTotal|currency('$')}}</span>
  4. </p>
  5. export default {
  6.     data(){
  7.       return {
  8.         orderId:'', // 订单id
  9.         orderTotal:0 // 订单总金额
  10.       }
  11.     },
  12.     mounted(){
  13.       // 从路由那里获取到订单id
  14.       // http://localhost:8080/#/orderSuccess?orderId=6221201801252245492
  15.       var orderId = this.$route.query.orderId;
  16.       console.log("orderId:"+orderId);
  17.  
  18.       if(!orderId){
  19.         return;
  20.       }
  21.       axios.get("/users/orderDetail",{
  22.         params:{
  23.           orderId:orderId
  24.         }
  25.       }).then((response)=>{
  26.         let res = response.data;
  27.         if(res.status == '0'){
  28.           this.orderId = orderId;
  29.           this.orderTotal = res.result.orderTotal;
  30.         }
  31.       })
  32.     },
  33.     filters:{ // 定义局部过滤器
  34.       currency:currency // currency.js传过来的本就是函数
  35.     }
  36. }

 

posted on 2018-06-28 04:42  gisery  阅读(6310)  评论(0编辑  收藏  举报