node.js ※ node之管理系统篇一【拓展后端知识如何生产我们写好的api文档】

connect连接数据库文件

// 使用mongoose模块
// 创建schema对象和创建连接都需要引用到mongoose模块
// 第一步
var mongoose = require('mongoose');
// 连接数据库
mongoose.connect(`mongodb://localhost/mjn`, {
    useNewUrlParser: true,
    useUnifiedTopology: true
});
// mongoose.connect第一个参数当中的mongodb表示连接本地数据库
// localhost表示数据库本地的一个域名
// localhost后面的:27017表示端口号默认端口号为27107,如果不写端口号则使用默认端口号
// 后面的mjn是数据库的名字
// 第二步
// var db = mongoose.connection;表示数据库的连接对象
var db = mongoose.connection;
// on表示监听事件,如果数据库连接错误就会触发打印数据库连接失败
db.on('error', function () {
    console.log("数据库连接失败!")
});
db.once('open', function () {
    console.log("数据库第一次连接成功!");
});

附带图片
在这里插入图片描述

userModel.js

// 创建schema对象和创建连接都需要引用到mongoose模块
var mongoose = require("mongoose")
// 第三步
// 创建schema对象  相当于创建数据库表的表头
var foodSchema = new mongoose.Schema({
    // 注意下列易犯错点
    // 如下我们要插入对数据操作时要写清除有表头,并且给清除表头的字符数据类型不然就会报错
    //例如你下面代码插入数据库内容的时候写了{name:"苹果",age:60,sex:"未知",boy:"男"}
    // 但是你在创建schema对象,创建数据库表头的时候没有定义boy属性并且定义清楚他的数据类型就会报错
    // 并且boy:"男"这条数据也无法写入数据库的表当中
    // require:true表示为必填项
    // name菜名
    name: {
        type: String,
        required: true
    },
    // price价格
    price: {
        type: String,
        required: true
    },
    // desc描述
    desc: {
        type: String,
        required: true
    },
    // img图片
    img:{
        type: String,
        required: false
    },
    // foodType食品类别
    foodType:{
        type: String,
        required: true
    },
    _id:{
        type: mongoose.Schema.Types.ObjectId,
        required: false
    },
});
// 第四步
// 将schema对象和数据集合进行关联
// 如果参数一这个集合是 你未创建的那么系统会默认帮你创建,并且如果参数一写的是单数形式英文单词,默认会给你变成复数
// mongoose.model("参数一填你要关联的集合名","参数二填上面创建的schema对象如上的foodSchema")
// 数据库相关的命名或者参数都不能写中文,比如数据库名,集合名不可以创建为中文
var foodModel = mongoose.model('foods', foodSchema);
// 因为我们后面对数据库的增删改查都需要用到数据模型foodModel所以我们需要将他暴露出去
module.exports = foodModel

图片资源
在这里插入图片描述

mongoose增删改查封装.js

// 1.添加菜品
var userModel = require("./userModel")
const foodModel = require("./userModel")
const router = require("../router/loginAndReg")
// 一:添加食品
var insertFood = async (obj, res) => {
    try {
        var result = await userModel.insertMany(obj)
        res.send(`{err:1,msg:"菜品添加成功,祝您用餐愉快!","添加的菜式":${result}}`)
    } catch (e) {
        res.send(`{err:-1,msg:"菜品添加失败,请重新添加!","添加失败的原因":${e}}`)
    }
}

// 二:查询全部菜品/或者模糊查找
var findFood = async function (obj, res) {
    if (arguments.length == 1) {
        try {
            var result = await userModel.find()
            res.send(`${result}`)
        } catch (e) {
            res.send(`{err:-1,msg:"菜品查询失败,请重新失败!","查询失败的原因":${e}}`)
        }
    } else {
        try {
            var result = await userModel.find(obj)
            if (!result[0]) {
                res.send(`您输入的菜,我们厨子还不会做哟`)
            } else {
                res.send(`${result}`)
            }
        } catch (e) {
            res.send(`{err:-1,msg:"菜品查询失败,请重新失败!","查询失败的原因":${e}}`)
        }
    }
}

// 三:删除菜品
var delFood = async function (_id) {
    // Object.prototype.toString.call()
var result= await userModel.deleteOne({_id},function(err){console.log(err);})
return result
}


// 四:修改菜品
var xiuGai=async function(_id,data){
    var result= await userModel.updateOne({_id},data)
    return result
}

// 五:分页查询
var FenYe=async function(page,pageSize){
    // 先查出所有数据
    var allFood=await userModel.find()
    // 然后得出查询结果数组的长度
    var allCount=await allFood.length
    // 每一页的数据
    var result=await userModel.find().skip((page-1)*pageSize).limit(pageSize-0)
    return {result,allCount,page}
}

// 六:分类查询
var FenLei=async function(foodType){
var result=await userModel.find({foodType})
return result
}

// 七:模糊搜索
var MoHu=async function(kw){
    // 通过正则表达式匹配相关的关键字,如下是我们定义的正则
    var regex=new RegExp(kw)
    // $regex表示可以写一个正则表达式
    // name:{$regex:regex}表示如果数据库内部所有数据中,如果name属性满足有关键字为kw的就会查找到
// 现在我们使用并集查询配合正则去实现name和foodType同时都有的模糊搜索封装
var result=await userModel.find({$or:[{name:{$regex:regex}},{foodType:{$regex:regex}}]})
return result
}
module.exports = {
    insertFood,
    findFood,
    delFood,
    xiuGai,
    FenYe,
    FenLei,
    MoHu
}

foodRouter.js

var express = require("express")
var userModel = require("../mongoose模块的使用/userModel")
var router = express.Router()
var {insertFood,findFood,delFood,xiuGai,FenYe,FenLei,MoHu} = require("../mongoose模块的使用/mongoose增删改查封装")



// 接口文档注释
/**
* @api {post} http://localhost:3210/api/add 这个是管理平台添加菜品的接口
 * @apiName add
 * @apiGroup Food
* @apiParam {String} name name这个参数是用来表示菜名的
* @apiParam {String} price price这个参数是用来表示菜品的价格
* @apiParam {String} desc desc这个参数是用来表示对菜品的相关描述用的
* @apiParam {String} img img这个参数是用来表示菜品的照片
* @apiParam {String} foodType foodType这个参数是用来描述这个菜品的分类
* @apiSuccess {String} err err表示返回的是状态码
* @apiSuccess {String} msg msg表示返回的是查询信息
 */
// 1.添加菜品
router.post("/add", (req, res) => {
    //接收数据
    var {name,price,desc,img,foodType} = req.body
    //处理数据 ,插入数据库
    //返回数据
    userModel.insertMany({name,price,desc,img,foodType})
        .then(function (data) {
            res.send(`{err:1,msg:"添加菜品成功,祝您用餐愉快!","您添加的菜为":${data}}`)
        }, function (sb) {
            res.send({
                err: -1,
                msg: "添加菜品失败,请重新添加!"
            })
        })
})

// 这个接口如果传入数据库的某个信息,就会根据新信息去查找
// 如果不传入数据库已有的信息,就查找整个数据库
// 二:查询菜品
router.post("/cha", (req, res) => {
    console.log("1", req.body);
    findFood(req.body, res)
})

// 三.删除菜品
router.post("/del", (req, res) => {
    var {_id} = req.body
    delFood(_id)
    .then((data) => {
            res.send(`菜品删除成功!`)
        })
        .catch((err) => {
            console.log(err);
            res.send("菜品删除失败!")
        })
})

// 修改数据
router.post("/xg",(req,res)=>{
    var {_id,name,price,img,desc,foodType}=req.body
    xiuGai(_id,{name,price,img,desc,foodType})
    .then(()=>{
        res.send({err:0,msg:"修改成功!"})
    })
    .catch((err)=>{
        res.send({err:-1,msg:"修改失败请重试!"})
    })
})

//    分页查询
router.post("/fy",(req,res)=>{
    var page=req.body.page||1//查询的第几页数据
    var pageSize=req.body.pageSize||2//每页多少天数据
    console.log(page,pageSize);
    FenYe(page,pageSize)
    .then((data)=>{
        var {result,allCount,page}=data
        // maxPage为最大页数.
        var maxPage=Math.ceil(allCount/page)
        res.send({err:0,msg:"查询成功!",result,allCount,maxPage})
    })
    .catch((err)=>{
        res.send({err:-1,msg:"查询失败请重试!"})
    })
})

//    分类查询
// 分类查询的数据可能很多,所以后面我们需要和分页查询做关联.
router.post("/fl",(req,res)=>{
var {foodType}=req.body
FenLei(foodType)
 .then((data)=>{
        res.send({err:0,msg:"分类查询成功!",list:data})
    })
    .catch((err)=>{
        res.send({err:-1,msg:"分类查询失败,请重试!"})
    })
})


//    模糊搜索/部分关键字或则关键字查询。
// 接口作用,比如我输入一个字,我们去数据库搜索有没有和关键字相关的数据内容.
// 由于模糊搜索,非常有可能一个关键字查询出很多条数据,所以我们要和分页接口做关联.
router.post("/mh",(req,res)=>{
    // kw是你要传入关键字的,字段属性名
    var {kw}=req.body||""
    MoHu(kw)
    .then((data)=>{
        if(data.length!=0){
            res.send({err:0,msg:"关键字查询成功!",list:data})
        }else{
            res.send({err:0,msg:"关键字查询失败,您搜索的菜品我们厨子还不会做呢★.★"})
        }
        
    })
    .catch((err)=>{
        res.send({err:-1,msg:"关键字查询失败,请重试!"})
    })
})


module.exports = router

在这里插入图片描述

server.js

var express=require("express")
var bodyParser=require("body-parser")
var path=require("path")
var fs=require("fs")
var app=express()
// post数据的解析
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(express.static(path.join("./public")))
// 把暴露的函数赋值给了connect变量
require("./mongoose模块的使用/connect")
// 如果connect文件不是用函数封装并且没有抛出,打印connect这个变量会出undefined,这样引入表示直接执行一次connect这个js文件的代码
// 抛出/暴露,是为了多次使用,比如函数,多次调用
// 我们做了函数封装并且做了模块暴露
// 如果用作函数封装的时候我们需要用变量去接,然后变量()才能调用函数
var userRouter=require("./router/loginAndReg")
var upLoad=require("./router/upLoad")
var foodRouter=require("./router/foodRouter")
app.use("/api",userRouter)
// app.use("/api",upLoad)
app.use("/api",foodRouter)
app.listen(3210,()=>{
    console.log("服务器端口号3210已经成功开启!","佛祖保佑无我写的代码一切安好无bug");
})

apidoc.json

{
    "name": "帅气的张亿同学为你们留下的api使用文档",
    "version": "0.1.0",
    "description": "千万别羡慕我超级帅,可以迷倒万千女性的那种帅。",
    "title": "叽叽歪歪的★★",
    "url" : "http://localhost:3210"
  }

在这里插入图片描述

管理系统的需求分析以及apidoc插件生成接口文档

// 管理平台功能需求
// 1.添加菜品
// 2.删除菜品
// 3.修改菜品
// 4.查询菜品
//    分页查询
//    模糊查询
//    分类查询


// 通过apidoc  插件生成接口文档
// 将代码注释(必须符合规范)变成接口

// 接口文档注释插件补充知识
/**
 * @api {get} /user/:id Request User information
 * @apiName GetUser
 * @apiGroup User
 *
 * @apiParam {Number} id Users unique ID.
 *
 * @apiSuccess {String} firstname Firstname of the User.
 * @apiSuccess {String} lastname  Lastname of the User.
 */

//  1. * @api {get} /user/:id Request User information→这段api注释表示你发起的请求是什么请求,以及接口路径,还有你对这个接口的注释
// 使用注释模板注释的使用实例如下👇
// * @api {get} http://localhost:3210/api/add 这个是管理平台添加菜品的接口

// 2. * @apiName GetUser  这段api注释表示你的接口叫什么名字
// 使用注释模板注释的使用实例如下👇
//  * @apiName add

// 3. * @apiGroup User  这段api注释表示你的接口属于什么分组
// 使用注释模板注释的使用实例如下👇我们将它设置为食物分组Food
// * @apiGroup Food

// 4. * @apiParam {Number} id Users unique ID.   这段api注释表示你写的这个接口需要那几个参数,参数分别是什么,需要几个参数我们就把这段代码写几遍
// @apiParam {Number}中的Number表示你这个接口的参数要填的是什么数据类型,比如String等等
// 使用注释模板注释的使用实例如下👇【因为这个接口需要用到五个参数,他们分别是name,price,desc,img,foodType】,我们每一个参数都要写一次api注释模板
// * @apiParam {String} name name这个参数是用来表示菜名的
// * @apiParam {String} price price这个参数是用来表示菜品的价格
// * @apiParam {String} desc desc这个参数是用来表示对菜品的相关描述用的
// * @apiParam {String} img img这个参数是用来表示菜品的照片
// * @apiParam {String} foodType foodType这个参数是用来描述这个菜品的分类

// 5. * @apiSuccess {String} firstname Firstname of the User.这段api注释表示你写的这个接口访问之后会返回什么。比如返回的是对象
// 使用注释模板注释的使用实例如下👇
// * @apiSuccess {String} err err表示返回的是状态码
// * @apiSuccess {String} msg msg表示返回的是查询信息

// 我们写完这些api接口注释模板之后,把代码合并起来放在我们接口的上面

// 如下综合实力(我们将注释放在了接口的上方)👇

// 接口文档注释
/**
* @api {get} http://localhost:3210/api/add 这个是管理平台添加菜品的接口
 * @apiName add
 * @apiGroup Food
* @apiParam {String} name name这个参数是用来表示菜名的
* @apiParam {String} price price这个参数是用来表示菜品的价格
* @apiParam {String} desc desc这个参数是用来表示对菜品的相关描述用的
* @apiParam {String} img img这个参数是用来表示菜品的照片
* @apiParam {String} foodType foodType这个参数是用来描述这个菜品的分类
* @apiSuccess {String} err err表示返回的是状态码
* @apiSuccess {String} msg msg表示返回的是查询信息
 */


//  我们在接口上写好了注释后,我们就开始下载这个插件
// 在cmd当中输入
// npm install apidoc -g
// 进行全局安装apidoc插件

// 接着我们创建一个 apidoc.json 的文件注意是apidoc.json的文件一个字母都不能错必须是apidoc.json
// 把apidoc.json的文件夹建立在和你的服务器同级的位置
// 建立好apidoc.json文件之后把如下👇代码复制到apidoc.json文件上

// {
//     "name": "example",
//     "version": "0.1.0",
//     "description": "apiDoc basic example",
//     "title": "Custom apiDoc browser title",
//     "url" : "https://api.github.com/v1"
//   }

// 声明一下上面赋值的代码如何修改
// name填的是你的api文档叫什么名字,比如我们填"帅气的某某某为你们留下的api使用文档"
// description填的是你的api文档的描述,比如我们写"千万别羡慕我超级帅,以及迷倒万千女性的那身材与腹肌。"
// title,写标题,你可以随便写
// url写你服务器的地址比如"http://localhost:3210"

// 安装完成并且对apidoc.json文件内部的信息修改好之后,我们就可以使用如下👇编译指令👇
// 如下的指令一定要在apidoc.json文件的目录下打开cmd执行
// apidoc -i myapp/ -o apidoc/ -t mytemplate/
// apidoc -i myapp/ -o apidoc/ -t mytemplate/指令的意思,
// myapp/表示的是你写注释的文件夹位置,如上我们的例子是把注释写在了foodRouter.js的文件下
// 因为foodRouter.js属在于router文件目录下,所以我们要填相对于apidoc.json文件的路径./router
// -o右边的写的是aip文档的导出目录,如果目录不存在它会自动帮你新建一个目录
// apidoc -i ./router -o ./doc

在这里插入图片描述
如上生成了index.html文件打开index.html文件里面就是我们生产的接口文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值