基於express+mongodb+pug的博客系統——后台篇


上一篇介紹了模板引擎pug.js的用法,這一篇就主要寫后台邏輯了。

后台的大部分的功能都有了,只是在已經登錄的狀態下,前台和后台的邏輯處理還不是很完善。

先上幾張圖吧,仿舊版的簡書,改了下UI,因為沒有簡書那么多內容,所以沒必要完全做成一樣的。

 

 

1.項目結構

app.js 是整個工程的入口

model 文件夾放連接數據庫的邏輯

public 文件夾里全是靜態資源

router 文件夾是各個模塊的路由文件,route.js是總入口

upload 里是上傳的圖像文件

views 里全是模板,layout.pug是最外層的框架模板,componentspages里則分別是公共組件和各個頁面的模板。

2.app.js

app.js代碼:

 app.js是整個工程的入口,這里沒什么問題,里面的模板引擎配置和靜態文件項配置在文檔里都有說明。需要注意的是靜態文件設置這里,最好使用path.join,因為我按照上面設置模板引擎的寫法去寫,始終會報錯,找不到對應的文件。

 3.router

 在這個文件夾里全是路由的相關配置

route.js

 

articleList.js

router部分被我根據業務相關,划分成了登錄、文章、管理三個部分。每個部分都會把他們相關的請求邏輯寫在一個js文件里,然后在最下面暴露出router接口,最后在route.js中統一分發處理。

在router.js里,會把所有的路由都掛在app這個對象上,然后暴露app,以便在入口文件app.js中使用。

另外在這里還用到了session來進行登錄狀態的保存處理,可以使用req.session.xxx來獲取或者新建並保存一個屬性。

這里唯一存在的問題就是在設置了maxAge之后,不管中途有沒有操作頁面,只要時間到了,都會清除掉cookie,不能做到只要頁面活躍時,cookie就不會過期。不知道是不是我哪設置的有問題。

 

login.js

登錄邏輯做的比較簡單,僅僅是獲取前台傳過來的值,然后與數據庫里的值做對比,並沒有做有效性校驗和加密處理等,在實際的項目中都應該加上的。

這里還用到了POST請求,對於POST請求,還需要單獨引入body-parser這個中間件,才能對POST傳入的值進行獲取處理。

4.model

model部分主要是負責連接數據庫,獲取並返回值。

connect.js

connect.js文件主要負責連接數據庫,並且將db對象暴露出去,這樣在其他需要的地方可以直接引用,而不用再次進行連接操作。

 

article_list.js文件代碼比較多,直接復制過來。

var mongoose = require('mongoose');

// 定義Schema
var articleSchema = new mongoose.Schema({
  author: String,
  createtime: String,
  updatetime: String,
  type: String,
  label: String,
  title: String,
  description: String,
  content: String,
  text: String,
  delta: Object,
  pv: Number,
  likes: Number,
  image: String
})
// 存入數據庫之前的操作
articleSchema.pre('save', function (next) {
  var date = new Date();
  if (this.isNew) {
    this.updatetime = this.createtime = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
  } else {
    this.updatetime = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
  }
  next()
});
// 定義model,關聯相關的表
var articleModel = mongoose.model('article_list', articleSchema);

function findArticle(option, callback) {
  articleModel.find(option, function (err, result) {
    if (err) console.log(err);
    // 渲染模板
    var data = {
      articleLists: result
    };

    callback(data)
  })
}

// 渲染文章列表
var renderArticleList = function (articleType, callback) {
  switch (articleType) {
    case 'all': findArticle({}, callback)
      break;
    case 'novel': findArticle({ type: '小說' }, callback)
      break;
    case 'it': findArticle({ type: '編程' }, callback)
      break;
    default: res.send('暫時沒有!')
  }
};

// 渲染文章詳情
var renderArticle = function (articleId, callback) {
  var articleId = mongoose.mongo.ObjectId(articleId)
  articleModel.find({ _id: articleId }, function (err, result) {
    if (err) console.log(err);

    callback(result[0])
  })
}

// 喜歡數增加
var addLike = function (req, res) {

}

// 文章管理列表分頁獲取數據
var renderManage = function (opt, callback) {
  var currentSize = (opt.currentPage - 1) * opt.pageSize;
  articleModel.find({}, function (err, result) {
    var data = {
      articleLists: result
    };
    callback(result)
  }).skip(currentSize).limit(opt.pageSize)
}
// 文章管理列表獲取總數
var getLength = function (callback) {
  articleModel.find({}, function (err, result) {
    callback(result.length)
  })
}

// 文章編輯保存
var saveArticle = function (article_opt, callback) {
  var newArticle = new articleModel(article_opt);
  if (article_opt.params_id) {
    var _id = article_opt.params_id
    articleModel.findOneAndUpdate({ _id: _id }, article_opt, function (err, result) {
      callback(result._id)
    })
  } else {
    newArticle.save(function (err, result) {
      callback(result._id)
    })
  }
}

// 文章刪除
var deleteArticle = function (articleId, callback) {
  articleModel.remove({_id: articleId}, function (err, result) {
    console.log(result)
    callback()
  })
}

var modelHome = {
  renderArticleList: renderArticleList,
  renderArticle: renderArticle,
  renderManage: renderManage,
  getLength: getLength,
  saveArticle: saveArticle,
  deleteArticle: deleteArticle
};

module.exports = modelHome;

凡是涉及到article_lists這個表的邏輯,都會寫在article_list.js里,不過這里應該是可以優化的,因為這里應該只處理model部分,而不應該有邏輯操作部分。

在使用mongoose這個庫連接mongoDB的時候需要注意,在定義model,關聯相關的表的時候, var articleModel = mongoose.model('article_list', articleSchema); 這里的article_list對應的是你數據庫里的表article_lists,數據庫里的表要多一個s。


在編輯文章的時候,除了新建文章之外,還可以直接修改已有的文章,所以這就涉及到數據的插值和更新,如果使用原生的mongoDB方法,可以很簡單的通過save()方法來實現,但是在mongoose中卻不行,mongoose中的save()方法和原生的insert()基本相同。

所以使用mongoose的時候需要分兩步,更新值使用findOneAndUpdate(),新建使用save()方法。

 

結語:

在這個版本里,還有一些功能沒有做,比如點贊之類,但大的功能都有了,不過剩下的我並不打算再寫了,再寫的時候肯定是重構了。

原因是寫到這里,自己能發現很多地方可以優化,還有最重要的一點是,express是一個輕量級的框架,他很靈活,但是很多東西需要借助第三方插件或者庫,這就給人帶來了很多麻煩。

第三方庫良莠不齊,在最初的選擇上面,你需要花很多功夫,選好了之后,你還得挨個去了解學習,挨個去踩坑,這都是很麻煩的事,所以並不建議大家直接在公司的重要項目里直接使用express這個框架。

當然如果只是一些比較簡單的頁面,比如活動頁或者一些不設計太多前后台邏輯交互的頁面,還是可以使用express的,因為它真的很簡單,你不需要會先去把es6搞明白,也不需要把node完全弄清楚。

只需要簡單的看看express官網嗎,就能很快上手做出一個具有前后台交互的東西出來。

代碼地址:https://github.com/Mcbai/blog

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM