基于node.js开发商品列表接口

2017-12-25  本文已影响0人  飞飞廉

1.使用express框架开发商品列表查询接口

实现步骤

-安装mongoose

var mongoose=require('mongoose');
var Schema=mongoose.Schema;//Schema是一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力。schema可以理解为mongoose对表结构的定义
//schema不具备操作数据库的能力

var productSchema= new Schema({ //创建实体,字段和数据库的goods字段一致,如果不一致就插不进来数据,这就防止了数据库的乱插入。
    "productId":String,
    "productName":String,
    "salePrice":Number,
    "productImage":String
});

module.exports=mongoose.model('good',productSchema);//创建并导出实体,名为good,和数据库的goods匹配,实体方法是productSchema
    //Model是由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为。Model的每一个实例(instance)就是一个document。document可以保存到数据库和对数据库进行操作。

mongoose简要API:https://www.cnblogs.com/winyh/p/6682039.html

var express=require('express');
var router=express.Router();
var mongoose=require('mongoose');
var Goods= require('../models/goods');
//var Users= require('../models/users');

//链接数据库
mongoose.connect('mongodb://127.0.0.1:27017/mall');
//监听数据库是否链接成功
mongoose.connection.on('connected',()=>{
    console.log("mongodb connected success")
});
mongoose.connection.on('error',()=>{
    console.log("mongodb connected fail")
});
mongoose.connection.on('disconnected',()=>{
    console.log("mongodb connected disconnected")
});


router.get('/',(req,res,next)=>{
        //获取前端传来的参数req.param
    let sort=+req.param("sort");
    let page=+req.param("page");
    let pageSize=+req.param("pageSize");
    let skip=(page-1)*pageSize
    let priceLevel=req.param("priceLevel");
    let startPrice;
    let endPrice;

    //查询数据库
    let params;//查询字段
    //根据价格选择来设置合适的查询字段
    if(priceLevel !== "all"){
        switch(priceLevel){
            case "0":startPrice=0;endPrice=100;break;
            case "1":startPrice=100;endPrice=500;break;
            case "2":startPrice=500;endPrice=1000;break;
            case "3":startPrice=1000;endPrice=2000;break;
        }
         params={
        salePrice:{
            $gt:startPrice,
            $lte:endPrice
        }
    }
    }else{
       params={};
    }    
    let goodsModel=Goods.find(params);

    goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据
    goodsModel.exec((err,doc)=>{
        if(err){
            res.json({//返回json数据
                status:'1',
                msg:err.message
            })
        }else{
            res.json({
                status:'0',
                msg:'',
                result:{
                    count:doc.length,
                    list:doc//把查询到的数据返回给前端
                }
            })
        }
    })
    
})

module.exports=router;

思路:前端通过axios传过去参数params,后端接受并解析出来对应的页码page,页面数据条数pageSize,和排序参数sort,然后后端根据这些参数进行排序过滤和分页。
先是进行排序,然后用skip过滤掉前面几页的数据((page-1)*pageSize),最后用limit限制此页的数据。

//前端的views/goodsList.js
 getGoodList(flag){
        axios.get("/goods",{
          params:{
            page:this.page,
            pageSize:this.pageSize,
            sort:this.sortFlag?1:-1,
            priceLevel:this.priceChecked
          }
        }).then((result)=>{
            var res=result.data;
            this.goodsList=res.result.list;                 
     })
    },
//后端的routes/goods.js
router.get('/',(req,res,next)=>{
        //获取前端传来的参数req.param
    let sort=+req.param("sort");
    let page=+req.param("page");
    let pageSize=+req.param("pageSize");
    let skip=(page-1)*pageSize
    goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据
    goodsModel.exec({},(err,doc)=>{
        if(err){
            res.json({//返回json数据
                status:'1',
                msg:err.message
            })
        }else{
            res.json({
                status:'0',
                msg:'',
                result:{
                    count:doc.length,
                    list:doc//把查询到的数据返回给前端
                }
            })
        }
    })
    
})

module.exports=router;

4、滚动分页加载
采用插件vue-infinite-scroll
使用方法:https://segmentfault.com/a/1190000011693433

//引入
import infiniteScroll from 'vue-infinite-scroll'
directives: {infiniteScroll},
 <div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
  加载中...
</div>

loadMore中添加滚动10px后的处理方法。busy为true代表禁用无限滚动。

loadMore(){//加载更多数据
     this.busy=true;
     this.page++;
     this.getGoodList(true);//参数flag为true代表之前有数据,后边的分页数据需要拼接起来
   }

此时补充getGoodList函数

getGoodList(flag){
        axios.get("/goods",{
          params:{
            page:this.page,
            pageSize:this.pageSize,
            sort:this.sortFlag?1:-1,
            priceLevel:this.priceChecked
          }
        }).then((result)=>{
          var res=result.data;
           if(flag){//如果之前有加载的数据再请求时就拼接起来
            this.goodsList=this.goodsList.concat(res.result.list);
          }else{
            this.goodsList=res.result.list;
          } 
          //判断当数据小于一页的数量时就设为true,禁用无限滚动,若没小于请求完数据后就可以启用滚动了
          if(res.result.count<this.pageSize){
            this.busy=true; 
          }else{
            this.busy=false;
          }
                 
        }).catch((err)=>{
          console.log(err);
          this.busy=true;//如果抱错了就禁用无限滚动
        })
    },

通过priceChecked将priceLevel传到后端,priceLevel包含all,1,2,3,4
后端进行筛选处理

//查询数据库
    let params;//查询字段
    //根据价格选择来设置合适的查询字段
    if(priceLevel !== "all"){
        switch(priceLevel){
            case "0":startPrice=0;endPrice=100;break;
            case "1":startPrice=100;endPrice=500;break;
            case "2":startPrice=500;endPrice=1000;break;
            case "3":startPrice=1000;endPrice=2000;break;
        }
         params={
        salePrice:{
            $gt:startPrice,
            $lte:endPrice
        }
    }
    }else{
       params={};
    }    
    let goodsModel=Goods.find(params);

    goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据

首先在前端GoodList页面实现点击‘加入购物车按钮’将商品信息加入到数据库users表的cartList数组中。
前端点击函数:
通过axios发送post请求,请求路径是/goods/addCart,传的参数是productId

 addCart(productId){//加入购物车
      axios.post("/goods/addCart",{
        productId:productId
      }).then((res)=>{
        if(res.data.status==0){
          alert("加入成功");
        }else{
          alert("error:"+res.msg)
        }
      })
    }
  },

后端服务器处理:
首先找到users表中用户id的数据表doc1,对doc1的cartList进行遍历循环,如果某一个商品id和当前加入购物车的商品id(前端传进来的参数,通过req.body解析)一样的话,就说明这个购物车已经存在了,exist设为true,只需要把cartList中的这个商品的productNum++即可,然后保存doc1。如果遍历完了exist并没有设为true(初始值为false),说明这个商品之前并没有加进购物车,所以接下来先找到Goods中的这个商品doc2,找到之后给这个商品添加两个字段checked和productNum用以记录是否被选中和商品数量,然后将doc2push进doc1的cartList数组中,最后保存。(注意设置checked和productNum时在model实体good中如果没有这两个字段的话是插入不进去的,所以需要在models下的good.js中补充这两个字段)

router.post('/addCart', (req, res, next) => {
    let exist = false;
    let userId = "100000077";
    let productId = req.body.productId;

    let params = { userId: userId };

    let usersModel = Users.findOne(params);

    usersModel.exec((err1, doc1) => {
        doc1.cartList.forEach((item) => {
            if (item.productId == productId) {
                exist = true;
                item.productNum++;
                doc1.save((err, doc) => {
                    if (err) {
                        res.json({
                            status: '1',
                            msg: err.message
                        })
                    } else {
                        res.json({
                            status: '0',
                            result: 'sucess'
                        })
                    }
                })
            }
        })

        if (!exist) {
            let good = Goods.findOne({ productId: productId }, (err2, doc2) => {
                if (err2) {
                    res.json({
                        status: '1',
                        msg: err2.message
                    })
                } else {
                    console.log(doc2)
                    doc2.checked = 1;
                    doc2.productNum = 1;
                    doc1.cartList.push(doc2);

                    doc1.save((err, doc) => {
                        if (err) {
                            res.json({
                                status: '1',
                                msg: err.message
                            })
                        } else {
                            res.json({
                                status: '0',
                                result: 'sucess'
                            })
                        }
                    })
                }
            })
        }
    })
})
上一篇下一篇

猜你喜欢

热点阅读