美文网首页
基于node.js开发商品列表接口

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

作者: 飞飞廉 | 来源:发表于2017-12-25 10:44 被阅读0次

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

    • 安装mongoose,对mongodb的封装,提供了增删改查的API,方便对数据库进行操作。
    • 创建model 实体,更mongodb数据库进行关联。
    • 创建路由 通过路由调model实体,通过model 实体的API来查询数据库
      -给予mongoose实现商品列表的查询功能。
    实现步骤

    -安装mongoose

    • 1、在server下建一个models文件夹,在models下建goods.js,代码如下:

    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

    • 2、在routes下创建文件goods.js

    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;
    
    • 3、分页功能实现

    思路:前端通过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;//如果抱错了就禁用无限滚动
            })
        },
    
    • 5、价格过滤

    通过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限制多少条数据
    
    • 6、加入购物车功能实现

    首先在前端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'
                                })
                            }
                        })
                    }
                })
            }
        })
    })
    

    相关文章

      网友评论

          本文标题:基于node.js开发商品列表接口

          本文链接:https://www.haomeiwen.com/subject/hfjqgxtx.html