├── public
├── image
│ ├── header-log.jpg
│ └── blog-header-log.jpg
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ ├── glyphicons-halflings-regular.woff2
│ └── glyphicons-halflings-regular.svg
├── js
│ ├── admin.js
│ ├── index.js
│ └── bootstrap.min.js
└── css
│ ├── admin.css
│ └── main.css
├── schemas
├── categories.js
├── users.js
└── contents.js
├── models
├── User.js
├── Content.js
└── Category.js
├── views
├── admin
│ ├── index.html
│ ├── page.html
│ ├── success.html
│ ├── category_add.html
│ ├── error.html
│ ├── cate_edit.html
│ ├── category_index.html
│ ├── user_admin.html
│ ├── content_index.html
│ ├── content_add.html
│ ├── content_edit.html
│ └── layout.html
└── main
│ ├── index.html
│ ├── content_view.html
│ └── layout.html
├── package.json
├── LICENSE
├── routers
├── main.js
├── api.js
└── admin.js
└── app.js
/public/image/header-log.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/image/header-log.jpg
--------------------------------------------------------------------------------
/public/image/blog-header-log.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/image/blog-header-log.jpg
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moaiqin/Nodejs-blog/HEAD/public/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/schemas/categories.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | //分类的表结构
3 | module.exports = new mongoose.Schema({
4 | //分类名称
5 | name:String
6 | });
--------------------------------------------------------------------------------
/models/User.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var userSchema = require('../schemas/users');
4 |
5 | module.exports = mongoose.model('User',userSchema);
--------------------------------------------------------------------------------
/models/Content.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var contentSchema = require('../schemas/contents');
3 |
4 | module.exports = mongoose.model('Content',contentSchema);
--------------------------------------------------------------------------------
/models/Category.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var categorySchema = require('../schemas/categories');
3 |
4 | module.exports = mongoose.model('Category',categorySchema);
--------------------------------------------------------------------------------
/public/js/admin.js:
--------------------------------------------------------------------------------
1 | function cateDelete(id){
2 | var deleBool = window.confirm('确定删除吗?');
3 | if(deleBool){
4 | window.location.href = '/admin/category/delete?_id='+id;
5 | }
6 | }
--------------------------------------------------------------------------------
/public/css/admin.css:
--------------------------------------------------------------------------------
1 | .admin-in-block{
2 | background: #eee;
3 | }
4 | .header-admin{
5 | margin-bottom: 0px;
6 | background-color: #ccc;
7 | }
8 | .breadcrumb{
9 | margin-bottom: 0;
10 | }
--------------------------------------------------------------------------------
/views/admin/index.html:
--------------------------------------------------------------------------------
1 | {% extends 'layout.html' %}
2 |
3 | {% block main %}
4 |
6 |
{{ content.title }}
7 |
8 | 作者:{{content.user.username}}
9 | 时间:{{content.date|date('Y-m-d H:i:s', -8*60)}}
10 | 阅读:{{content.views}}
11 | 评论:{{content.comment.length}}
12 |
13 |
{{content.description}}
14 |
17 |
18 | {% endfor %}
19 |
4 |
{{ content.title }}
5 |
6 | 作者:{{content.user.username}}
7 | 时间:{{content.date|date('Y-m-d H:i:s', -8*60)}}
8 | 阅读:{{content.views}}
9 | 评论:{{content.comment.length}}
10 |
11 |
{{content.content}}
12 |
13 |
59 | {% endblock %}
60 |
--------------------------------------------------------------------------------
/views/admin/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
33 |
34 | {% block main %}
35 | {% endblock %}
36 |
37 |
38 | {% if userInfo._id %}
39 |
40 |
41 | 用户信息
42 |
43 |
{{userInfo.username}}
44 | {% if userInfo.isAdmin %}
45 |
你好,你是管理员点击进入管理
46 | {% else %}
47 |
你好,欢迎光临我的博客
48 | {% endif %}
49 |
退出
50 |
51 | {% else %}
52 |
72 | {% endif %}
73 |
97 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/routers/api.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var User = require('../models/User');
4 | var Content = require('../models/Content');
5 |
6 | var responseData;
7 | router.use(function(req, res , next){
8 | //每次调用api下面的这个都被初始化,code为0
9 | responseData = {
10 | code:0,
11 | message:''
12 | };
13 | next();
14 | })
15 |
16 |
17 | router.post('/user/register',function(req, res, next) {
18 | var username = req.body.username;
19 | var password = req.body.password;
20 | var repassword = req.body.password2;
21 |
22 | //用户名是否为空;
23 | if(username === ''){
24 | responseData.code =1;
25 | responseData.message = '用户名不能为空';
26 | res.json(responseData);
27 | return;
28 | }
29 |
30 | //密码不能为空
31 | if(password === ''){
32 | responseData.code = 2;
33 | responseData.message = '密码不能为空';
34 | res.json(responseData);
35 | return;
36 | }
37 |
38 | //两次密码要一样
39 | if(password !== repassword){
40 | responseData.code = 3;
41 | responseData.message = '两次密码不一样';
42 | res.json(responseData);
43 | return;
44 | }
45 |
46 | User.findOne({
47 | username:username
48 | }).then(function(userinfo){
49 | if(userinfo){
50 | //表示有数
51 | responseData.code = 4;
52 | responseData.message = '用户名已经存在';
53 | res.json(responseData);
54 | return;
55 | }else{
56 | //表示没有数据
57 | var user = new User({
58 | username:username,
59 | password:password
60 | });
61 | return user.save();
62 | }
63 | }).then(function(newUserinfo){
64 | if(newUserinfo){
65 | responseData.message = '注册成功';
66 | res.json(responseData);
67 | }
68 | })
69 |
70 | })
71 |
72 | router.post('/user/login',function(req, res, next) {
73 | var username = req.body.username;
74 | var password = req.body.password;
75 | if(!username) {
76 | responseData.code = 1;
77 | responseData.message = '用户名不能为空';
78 | res.json(responseData);
79 | return;
80 | }
81 |
82 | if(!password) {
83 | responseData.code = 2;
84 | responseData.message ='密码不能为空';
85 | res.json(responseData);
86 | return;
87 | }
88 |
89 | User.findOne({
90 | username:username,
91 | password:password
92 | }).then(function(userinfo) {
93 |
94 | if(!userinfo){
95 | responseData.code = 3;
96 | responseData.message = '用户不存在或密码错误';
97 | res.json(responseData);
98 | return;
99 | }
100 | responseData.userInfo = {
101 | _id:userinfo._id,
102 | username:userinfo.username
103 | };
104 | //每次都会把cookies请求数据到服务端
105 | req.cookies.set('userInfo',JSON.stringify({
106 | _id:userinfo._id,
107 | username:userinfo.username,
108 | isAdmin:userinfo.isAdmin
109 | }));
110 | responseData.message = '登陆成功';
111 | res.json(responseData);
112 | })
113 | })
114 |
115 | router.get('/user/logout',function(req,res,next){
116 | req.cookies.set('userInfo', null);
117 | res.json(responseData);
118 | })
119 |
120 |
121 | /**
122 | * 评论提交
123 | * @type {[type]}
124 | */
125 |
126 | router.post('/comment/post',function(req, res, next){
127 | var contentId = req.body.contentId || '';
128 | var postData = {
129 | username:req.userInfo.username,
130 | userId:req.userInfo._id.toString(),
131 | postDate:new Date(),
132 | content:req.body.content
133 | }
134 | console.log(contentId)
135 |
136 | if(!req.body.content){
137 | responseData.message = '评论不能为空';
138 | responseData.code = 1;
139 | res.json(responseData);
140 | return;
141 | }
142 | //查找该条内容
143 | Content.findOne({
144 | _id:contentId
145 | }).then(function(content){
146 | //content是entity类型,有save方法
147 | content.comment.push(postData);
148 | return content.save();//返回的是保存之后的表
149 | }).then(function(newContent){
150 | if(newContent){
151 | responseData.message = '评论成功';
152 | responseData.data = newContent;
153 | res.json(responseData);
154 | }
155 | })
156 | });
157 |
158 |
159 | /**
160 | * 获取评论
161 | */
162 |
163 | router.get('/comment',function(req, res, next){
164 | var id = req.query.content || '';
165 | Content.findOne({
166 | _id:id
167 | }).then(function(contentInfo){
168 | console.log(contentInfo)
169 | responseData.data = contentInfo.comment;
170 | res.json(responseData);
171 | })
172 | })
173 |
174 |
175 | module.exports = router;
--------------------------------------------------------------------------------
/public/js/index.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var loginBox = $('#login');
3 | var logoutBox = $('#logout');
4 | var userBox = $('#user-info');
5 |
6 |
7 | $('.blog-nav li').on('click',function(){
8 | $('.blog-nav li').filter('.active').removeClass('active');
9 | $(this).addClass('active');
10 | })
11 | loginBox.find('a').on('click', function() {
12 | logoutBox.show();
13 | loginBox.hide();
14 | })
15 | logoutBox.find('a').on('click', function() {
16 | loginBox.show();
17 | logoutBox.hide();
18 | })
19 | loginBox.find('button').on('click',function() {
20 | $.ajax({
21 | type:'post',
22 | url:'/api/user/login',
23 | data:{
24 | username:loginBox.find('[name="username"]').val(),
25 | password:loginBox.find('[name="password"]').val()
26 | },
27 | dataType:'json',
28 | success:function(data){
29 | loginBox.find('.login-message').html(data.message);
30 | if(!data.code){
31 | window.location.reload();
32 | }
33 | }
34 | });
35 | });
36 | logoutBox.find('button').on('click',function() {
37 | var username = logoutBox.find('[name="username"]').val();
38 | var password = logoutBox.find('[name="password"]').val();
39 | var password2 = logoutBox.find('[name="password2"]').val();
40 | $.ajax({
41 | type:'post',
42 | url:'/api/user/register',
43 | data:{
44 | username:username,
45 | password:password,
46 | password2:password2
47 | },
48 | dataType:'json',
49 | success:function(data){
50 | logoutBox.find('.register-message').html(data.message);
51 | if(!data.code){
52 | setTimeout(function(){
53 | loginBox.show();
54 | logoutBox.hide();
55 | },1000)
56 | }
57 | }
58 |
59 | })
60 | });
61 |
62 | var commentList = $('.comment-page li');
63 | var curPage = $('.cur-page span');
64 | var start = 0;
65 | var limit = 4;
66 | var end = 0;
67 | var resData;
68 | var totalPage = 0;
69 | var page = 1;
70 |
71 | //和获取评论信息
72 | $.ajax({
73 | type:'get',
74 | url:'/api/comment',
75 | data:{
76 | content:$('#contentId').val()
77 | },
78 | dataType:'json',
79 | success:function(response){
80 | resData = response.data.reverse();
81 | renderView(response.data.reverse());
82 | }
83 | });
84 | commentList.eq(0).on('click',function(){
85 | page--;
86 | renderView(resData);
87 | });
88 | commentList.eq(1).on('click',function(){
89 | page++;
90 | renderView(resData);
91 | });
92 |
93 | function renderView(comments){
94 | if(comments.length === 0){
95 | $('.comment-page').hide();
96 | return;
97 | }else{
98 | $('.no-msg').hide();
99 | }
100 | var html = '';
101 | totalPage = Math.ceil(comments.length/limit);
102 | if(page<=1){
103 | page = 1;
104 | commentList.eq(0).html('
评论
16 | 一共有{{content.comment.length}}条评论 17 |