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

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'
                            })
                        }
                    })
                }
            })
        }
    })
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容