阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      express 博客项目的逻辑

      文件结构如下

      • app.js
      • mongoose 做表结构和表模型
      • api.js
      • main.js
      • admin.js

      app.js 文件如下

      //加载express模块
      var express = require('express');
      //加载模板处理模块
      var swig = require('swig');
      //加载数据库模块
      var mongoose = require('mongoose');
      //加载body-parser,用来处理post提交过来的数据
      var bodyParser = require('body-parser');
      //加载cookies模块
      var Cookies = require('cookies');
      //创建app应用 => NodeJS Http.createServer();
      var app = express();
      
      var User = require('./models/User');
      
      //设置静态文件托管
      //当用户访问的url以/public开始,那么直接返回对应__dirname + '/public'下的文件
      app.use( '/public', express.static( __dirname + '/public') );
      
      //配置应用模板
      //定义当前应用所使用的模板引擎
      //第一个参数:模板引擎的名称,同时也是模板文件的后缀,第二个参数表示用于解析处理模板内容的方法
      app.engine('html', swig.renderFile);
      //设置模板文件存放的目录,第一个参数必须是views,第二个参数是目录
      app.set('views', './views');
      //注册所使用的模板引擎,第一个参数必须是 view engine,第二个参数和app.engine这个方法中定义的模板引擎的名称(第一个参数)是一致的
      app.set('view engine', 'html');
      //在开发过程中,需要取消模板缓存
      swig.setDefaults({cache: false});
      
      //bodyparser设置
      app.use( bodyParser.urlencoded({extended: true}) );
      
      //设置cookie
      app.use( function(req, res, next) {
          req.cookies = new Cookies(req, res);
      
          //解析登录用户的cookie信息
          req.userInfo = {};
          if (req.cookies.get('userInfo')) {
              try {
                  req.userInfo = JSON.parse(req.cookies.get('userInfo'));
      
                  //获取当前登录用户的类型,是否是管理员
                  User.findById(req.userInfo._id).then(function(userInfo) {
                      req.userInfo.isAdmin = Boolean(userInfo.isAdmin);
                      next();
                  })
              }catch(e){
                  next();
              }
      
          } else {
              next();
          }
      } );
      
      /*
      * 根据不同的功能划分模块
      * */
      app.use('/admin', require('./routers/admin'));
      app.use('/api', require('./routers/api'));
      app.use('/', require('./routers/main'));
      
      //监听http请求
      mongoose.connect('mongodb://localhost:27018/blog', function(err) {
          if (err) {
              console.log('数据库连接失败');
          } else {
              console.log('数据库连接成功');
              app.listen(8081);
          }
      });
      

      mongoose 做表结构和表模型

      参见文件:mongoose做表结构和表模型

      文件如下

      routers/admin.js
      routers/api.js
      routers/main.js
      

      api.js

      var express = require('express');
      var router = express.Router();
      var User = require('../models/User');
      var Content = require('../models/Content');
      
      //统一返回格式
      var responseData;
      
      router.use( function(req, res, next) {
          responseData = {
              code: 0,
              message: ''
          }
      
          next();
      } );
      
      /*
      * 用户注册
      *   注册逻辑
      *
      *   1.用户名不能为空
      *   2.密码不能为空
      *   3.两次输入密码必须一致
      *
      *   1.用户是否已经被注册了
      *       数据库查询
      *
      * */
      router.post('/user/register', function(req, res, next) {
      
          var username = req.body.username;
          var password = req.body.password;
          var repassword = req.body.repassword;
      
          //用户是否为空
          if ( username == '' ) {
              responseData.code = 1;
              responseData.message = '用户名不能为空';
              res.json(responseData);
              return;
          }
          //密码不能为空
          if (password == '') {
              responseData.code = 2;
              responseData.message = '密码不能为空';
              res.json(responseData);
              return;
          }
          //两次输入的密码必须一致
          if (password != repassword) {
              responseData.code = 3;
              responseData.message = '两次输入的密码不一致';
              res.json(responseData);
              return;
          }
      
          //用户名是否已经被注册了,如果数据库中已经存在和我们要注册的用户名同名的数据,表示该用户名已经被注册了
          User.findOne({
              username: username
          }).then(function( userInfo ) {
              if ( userInfo ) {
                  //表示数据库中有该记录
                  responseData.code = 4;
                  responseData.message = '用户名已经被注册了';
                  res.json(responseData);
                  return;
              }
              //保存用户注册的信息到数据库中
              var user = new User({
                  username: username,
                  password: password
              });
              return user.save();
          }).then(function(newUserInfo) {
              responseData.message = '注册成功';
              res.json(responseData);
          });
      });
      
      /*
      * 登录
      * */
      router.post('/user/login', function(req, res) {
          var username = req.body.username;
          var password = req.body.password;
      
          if ( username == '' || password == '' ) {
              responseData.code = 1;
              responseData.message = '用户名和密码不能为空';
              res.json(responseData);
              return;
          }
      
          //查询数据库中相同用户名和密码的记录是否存在,如果存在则登录成功
          User.findOne({
              username: username,
              password: password
          }).then(function(userInfo) {
              if (!userInfo) {
                  responseData.code = 2;
                  responseData.message = '用户名或密码错误';
                  res.json(responseData);
                  return;
              }
              //用户名和密码是正确的
              responseData.message = '登录成功';
              responseData.userInfo = {
                  _id: userInfo._id,
                  username: userInfo.username
              }
              req.cookies.set('userInfo', JSON.stringify({
                  _id: userInfo._id,
                  username: userInfo.username
              }));
              res.json(responseData);
              return;
          })
      
      });
      
      /*
      * 退出
      * */
      router.get('/user/logout', function(req, res) {
          req.cookies.set('userInfo', null);
          res.json(responseData);
      });
      
      /*
      * 获取指定文章的所有评论
      * */
      router.get('/comment', function(req, res) {
          var contentId = req.query.contentid || '';
      
          Content.findOne({
              _id: contentId
          }).then(function(content) {
              responseData.data = content.comments;
              res.json(responseData);
          })
      });
      
      /*
      * 评论提交
      * */
      router.post('/comment/post', function(req, res) {
          //内容的id
          var contentId = req.body.contentid || '';
          var postData = {
              username: req.userInfo.username,
              postTime: new Date(),
              content: req.body.content
          };
      
          //查询当前这篇内容的信息
          Content.findOne({
              _id: contentId
          }).then(function(content) {
              content.comments.push(postData);
              return content.save();
          }).then(function(newContent) {
              responseData.message = '评论成功';
              responseData.data = newContent;
              res.json(responseData);
          });
      });
      
      module.exports = router;
      

      main.js

      let express     = require('express');
      let router      = express.Router();
      
      let Category    = require('../models/Category');
      let Content     = require('../models/Content');
      
      let data;
      
      /*
      * 处理通用的数据
      * */
      router.use(function (req, res, next) {
          data = {
              userInfo: req.userInfo,
              categories: []
          }
      
          Category.find().then(function(categories) {
              data.categories = categories;
              next();
          });
      });
      
      /*
      * 首页
      * */
      router.get('/', function(req, res, next) {
      
          data.category = req.query.category || '';
          data.count = 0;
          data.page = Number(req.query.page || 1);
          data.limit = 10;
          data.pages = 0;
      
          let where = {};
          if (data.category) {
              where.category = data.category
          }
      
          Content.where(where).count().then(function(count) {
      
              data.count = count;
              //计算总页数
              data.pages = Math.ceil(data.count / data.limit);
              //取值不能超过pages
              data.page = Math.min( data.page, data.pages );
              //取值不能小于1
              data.page = Math.max( data.page, 1 );
      
              let skip = (data.page - 1) * data.limit;
      
              return Content.where(where).find().limit(data.limit).skip(skip).populate(['category', 'user']).sort({
                  addTime: -1
              });
      
          }).then(function(contents) {
              data.contents = contents;
              res.render('main/index', data);
          })
      });
      
      router.get('/view', function (req, res){
      
          let contentId = req.query.contentid || '';
      
          Content.findOne({
              _id: contentId
          }).then(function (content) {
              data.content = content;
      
              content.views++;
              content.save();
      
              res.render('main/view', data);
          });
      
      });
      
      module.exports = router;
      

      admin.js

      var express = require('express');
      var router = express.Router();
      
      var User = require('../models/User');
      var Category = require('../models/Category');
      var Content = require('../models/Content');
      
      router.use(function(req, res, next) {
          if (!req.userInfo.isAdmin) {
              //如果当前用户是非管理员
              res.send('对不起,只有管理员才可以进入后台管理');
              return;
          }
          next();
      });
      
      /**
       * 首页
       */
      router.get('/', function(req, res, next) {
          res.render('admin/index', {
              userInfo: req.userInfo
          });
      });
      
      /*
      * 用户管理
      * */
      router.get('/user', function(req, res) {
      
          /*
          * 从数据库中读取所有的用户数据
          *
          * limit(Number) : 限制获取的数据条数
          *
          * skip(2) : 忽略数据的条数
          *
          * 每页显示2条
          * 1 : 1-2 skip:0 -> (当前页-1) * limit
          * 2 : 3-4 skip:2
          * */
      
          var page = Number(req.query.page || 1);
          var limit = 10;
          var pages = 0;
      
          User.count().then(function(count) {
      
              //计算总页数
              pages = Math.ceil(count / limit);
              //取值不能超过pages
              page = Math.min( page, pages );
              //取值不能小于1
              page = Math.max( page, 1 );
      
              var skip = (page - 1) * limit;
      
              User.find().limit(limit).skip(skip).then(function(users) {
                  res.render('admin/user_index', {
                      userInfo: req.userInfo,
                      users: users,
      
                      count: count,
                      pages: pages,
                      limit: limit,
                      page: page
                  });
              });
      
          });
      
      });
      
      /*
      * 分类首页
      * */
      router.get('/category', function(req, res) {
      
          var page = Number(req.query.page || 1);
          var limit = 10;
          var pages = 0;
      
          Category.count().then(function(count) {
      
              //计算总页数
              pages = Math.ceil(count / limit);
              //取值不能超过pages
              page = Math.min( page, pages );
              //取值不能小于1
              page = Math.max( page, 1 );
      
              var skip = (page - 1) * limit;
      
              /*
              * 1: 升序
              * -1: 降序
              * */
              Category.find().sort({_id: -1}).limit(limit).skip(skip).then(function(categories) {
                  res.render('admin/category_index', {
                      userInfo: req.userInfo,
                      categories: categories,
      
                      count: count,
                      pages: pages,
                      limit: limit,
                      page: page
                  });
              });
      
          });
      
      });
      
      /*
      * 分类的添加
      * */
      router.get('/category/add', function(req, res) {
          res.render('admin/category_add', {
              userInfo: req.userInfo
          });
      });
      
      /*
      * 分类的保存
      * */
      router.post('/category/add', function(req, res) {
      
          var name = req.body.name || '';
      
          if (name == '') {
              res.render('admin/error', {
                  userInfo: req.userInfo,
                  message: '名称不能为空'
              });
              return;
          }
      
          //数据库中是否已经存在同名分类名称
          Category.findOne({
              name: name
          }).then(function(rs) {
              if (rs) {
                  //数据库中已经存在该分类了
                  res.render('admin/error', {
                      userInfo: req.userInfo,
                      message: '分类已经存在了'
                  })
                  return Promise.reject();
              } else {
                  //数据库中不存在该分类,可以保存
                  return new Category({
                      name: name
                  }).save();
              }
          }).then(function(newCategory) {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '分类保存成功',
                  url: '/admin/category'
              });
          })
      
      });
      
      /*
      * 分类修改
      * */
      router.get('/category/edit', function(req, res) {
      
          //获取要修改的分类的信息,并且用表单的形式展现出来
          var id = req.query.id || '';
      
          //获取要修改的分类信息
          Category.findOne({
              _id: id
          }).then(function(category) {
              if (!category) {
                  res.render('admin/error', {
                      userInfo: req.userInfo,
                      message: '分类信息不存在'
                  });
              } else {
                  res.render('admin/category_edit', {
                      userInfo: req.userInfo,
                      category: category
                  });
              }
          })
      
      });
      
      /*
      * 分类的修改保存
      * */
      router.post('/category/edit', function(req, res) {
      
          //获取要修改的分类的信息,并且用表单的形式展现出来
          var id = req.query.id || '';
          //获取post提交过来的名称
          var name = req.body.name || '';
      
          //获取要修改的分类信息
          Category.findOne({
              _id: id
          }).then(function(category) {
              if (!category) {
                  res.render('admin/error', {
                      userInfo: req.userInfo,
                      message: '分类信息不存在'
                  });
                  return Promise.reject();
              } else {
                  //当用户没有做任何的修改提交的时候
                  if (name == category.name) {
                      res.render('admin/success', {
                          userInfo: req.userInfo,
                          message: '修改成功',
                          url: '/admin/category'
                      });
                      return Promise.reject();
                  } else {
                      //要修改的分类名称是否已经在数据库中存在
                      return Category.findOne({
                          _id: {$ne: id},
                          name: name
                      });
                  }
              }
          }).then(function(sameCategory) {
              if (sameCategory) {
                  res.render('admin/error', {
                      userInfo: req.userInfo,
                      message: '数据库中已经存在同名分类'
                  });
                  return Promise.reject();
              } else {
                  return Category.update({
                      _id: id
                  }, {
                      name: name
                  });
              }
          }).then(function() {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '修改成功',
                  url: '/admin/category'
              });
          })
      
      });
      
      /*
      * 分类删除
      * */
      router.get('/category/delete', function(req, res) {
      
          //获取要删除的分类的id
          var id = req.query.id || '';
      
          Category.remove({
              _id: id
          }).then(function() {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '删除成功',
                  url: '/admin/category'
              });
          });
      
      });
      
      /*
      * 内容首页
      * */
      router.get('/content', function(req, res) {
      
          var page = Number(req.query.page || 1);
          var limit = 10;
          var pages = 0;
      
          Content.count().then(function(count) {
      
              //计算总页数
              pages = Math.ceil(count / limit);
              //取值不能超过pages
              page = Math.min( page, pages );
              //取值不能小于1
              page = Math.max( page, 1 );
      
              var skip = (page - 1) * limit;
      
              Content.find().limit(limit).skip(skip).populate(['category', 'user']).sort({
                  addTime: -1
              }).then(function(contents) {
                  res.render('admin/content_index', {
                      userInfo: req.userInfo,
                      contents: contents,
      
                      count: count,
                      pages: pages,
                      limit: limit,
                      page: page
                  });
              });
      
          });
      
      });
      
      /*
       * 内容添加页面
       * */
      router.get('/content/add', function(req, res) {
      
          Category.find().sort({_id: -1}).then(function(categories) {
              res.render('admin/content_add', {
                  userInfo: req.userInfo,
                  categories: categories
              })
          });
      
      });
      
      /*
      * 内容保存
      * */
      router.post('/content/add', function(req, res) {
      
          //console.log(req.body)
      
          if ( req.body.category == '' ) {
              res.render('admin/error', {
                  userInfo: req.userInfo,
                  message: '内容分类不能为空'
              })
              return;
          }
      
          if ( req.body.title == '' ) {
              res.render('admin/error', {
                  userInfo: req.userInfo,
                  message: '内容标题不能为空'
              })
              return;
          }
      
          //保存数据到数据库
          new Content({
              category: req.body.category,
              title: req.body.title,
              user: req.userInfo._id.toString(),
              description: req.body.description,
              content: req.body.content
          }).save().then(function(rs) {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '内容保存成功',
                  url: '/admin/content'
              })
          });
      
      });
      
      /*
      * 修改内容
      * */
      router.get('/content/edit', function(req, res) {
      
          var id = req.query.id || '';
      
          var categories = [];
      
          Category.find().sort({_id: 1}).then(function(rs) {
      
              categories = rs;
      
              return Content.findOne({
                  _id: id
              }).populate('category');
          }).then(function(content) {
      
              if (!content) {
                  res.render('admin/error', {
                      userInfo: req.userInfo,
                      message: '指定内容不存在'
                  });
                  return Promise.reject();
              } else {
                  res.render('admin/content_edit', {
                      userInfo: req.userInfo,
                      categories: categories,
                      content: content
                  })
              }
          });
      
      });
      
      /*
       * 保存修改内容
       * */
      router.post('/content/edit', function(req, res) {
          var id = req.query.id || '';
      
          if ( req.body.category == '' ) {
              res.render('admin/error', {
                  userInfo: req.userInfo,
                  message: '内容分类不能为空'
              })
              return;
          }
      
          if ( req.body.title == '' ) {
              res.render('admin/error', {
                  userInfo: req.userInfo,
                  message: '内容标题不能为空'
              })
              return;
          }
      
          Content.update({
              _id: id
          }, {
              category: req.body.category,
              title: req.body.title,
              description: req.body.description,
              content: req.body.content
          }).then(function() {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '内容保存成功',
                  url: '/admin/content/edit?id=' + id
              })
          });
      
      });
      
      /*
      * 内容删除
      * */
      router.get('/content/delete', function(req, res) {
          var id = req.query.id || '';
      
          Content.remove({
              _id: id
          }).then(function() {
              res.render('admin/success', {
                  userInfo: req.userInfo,
                  message: '删除成功',
                  url: '/admin/content'
              });
          });
      });
      
      module.exports = router;
      
      目录
      本文目录
      目录