-
Notifications
You must be signed in to change notification settings - Fork 0
Week18 完成 #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Week18 完成 #20
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| const express = require('express') | ||
| const bodyParser = require('body-parser') | ||
| const session = require('express-session') | ||
| const flash = require('connect-flash'); | ||
| const blogController = require('./controllers/blog.js') | ||
| const userController = require('./controllers/user.js') | ||
|
|
||
| const app = express() | ||
| const port = 5001 | ||
|
|
||
| app.set('view engine', 'ejs') | ||
| app.use(bodyParser.urlencoded({ extended: false })) | ||
| app.use(bodyParser.json()) | ||
| app.use(session({ | ||
| secret: 'keyboard cat', | ||
| resave: false, | ||
| saveUninitialized: true, | ||
| })) | ||
| app.use(flash()) | ||
| app.use(express.static(__dirname + '/public')); | ||
|
|
||
| app.use((req, res, next) => { | ||
| res.locals.userId = req.session.userId || null; | ||
| res.locals.errorMessage = req.flash('errorMessage'); | ||
| next(); | ||
| }) | ||
|
|
||
| app.get('/blog', blogController.init) | ||
| app.get('/article/:id', blogController.get) | ||
| app.get('/addArticle', blogController.addArticle) | ||
| app.get('/admin', blogController.admin) | ||
| app.get('/register', userController.register) | ||
| app.get('/login', userController.login) | ||
| app.get('/logout', userController.logout) | ||
| app.get('/update/:id', blogController.updateArticle) | ||
| app.get('/delete/:id', blogController.deleteArticle) | ||
|
|
||
| app.post('/article', blogController.handleAddArticle) | ||
| app.post('/login', userController.handleLogin) | ||
| app.post('/register', userController.handleRegister) | ||
| app.post('/update/:id', blogController.handleUpdateArticle) | ||
|
|
||
| app.listen(port, () => { | ||
| console.log(`App listening on port ${port}`) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "development": { | ||
| "username": "root", | ||
| "password": "Ss121549!", | ||
| "database": "test", | ||
| "host": "3.23.99.109", | ||
| "dialect": "mysql" | ||
| }, | ||
| "test": { | ||
| "username": "root", | ||
| "password": null, | ||
| "database": "database_test", | ||
| "host": "127.0.0.1", | ||
| "dialect": "mysql" | ||
| }, | ||
| "production": { | ||
| "username": "root", | ||
| "password": null, | ||
| "database": "database_production", | ||
| "host": "127.0.0.1", | ||
| "dialect": "mysql" | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 這個檔案要加進 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| const utilis = require('../utilis.js') | ||
| const db = require('../models') | ||
| const { Op } = require("sequelize"); | ||
| const User = db.User | ||
| const Article = db.Article | ||
| const Tag = db.Tags | ||
|
|
||
| const blogController = { | ||
| init: (req, res) => { | ||
| utilis.getUserInfoById(req.session.userId, (user) => { | ||
| Article.findAll({ | ||
| where: {isDeleted: 0}, | ||
| order:[['id', 'DESC']], | ||
| include: User, | ||
| include: Tag | ||
| }).then(articles => { | ||
| res.render('blog', { | ||
| user, | ||
| articles, | ||
| }) | ||
| }).catch(error => { | ||
| console.log(error) | ||
| res.redirect('/blog') | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| admin: (req, res) => { | ||
| if(!req.session.userId) return res.redirect('/blog') | ||
| utilis.getUserInfoById(req.session.userId, user => { | ||
| if(user.authType !== '1') return res.redirect('/blog') | ||
| Article.findAll({ | ||
| where: {isDeleted: 0}, | ||
| order:[['id', 'DESC']], | ||
| include: User | ||
| }).then(articles => { | ||
| res.render('admin',{ | ||
| user, | ||
| articles, | ||
| }) | ||
| }).catch(error => { | ||
| console.log(error) | ||
| res.redirect('/blog') | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| getAll: (req, res) => { | ||
| Article.findAll({ | ||
| where: {isDeleted: 0}, | ||
| include: User | ||
| }).then(articles => { | ||
| res.render('blog', { | ||
| articles: articles | ||
| }) | ||
| }).catch(error => { | ||
| console.log(error) | ||
| res.redirect('/blog') | ||
| }) | ||
| }, | ||
|
|
||
| get: (req, res) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 命名可以更清楚一點,比如說 |
||
| const id = req.params.id | ||
| Article.findByPk(id,{ | ||
| include: Tag | ||
| }).then(article => { | ||
| if(!article) { | ||
| console.log('Inavlid article Id') | ||
| res.redirect('/blog') | ||
| return | ||
| } | ||
| if(article.isDeleted === 1) return res.redirect('/blog') | ||
| res.render('readMore', { | ||
| user: article.UserId || 0, | ||
| article, | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| addArticle: (req, res) => { | ||
| const userId = req.session.userId | ||
| if(!userId) return res.redirect('/blog') | ||
| utilis.getUserInfoById(userId, user => { | ||
| if(user.authType !== '1') { | ||
| return res.redirect('/blog') | ||
| } | ||
| utilis.getAllTags(tags => { | ||
| res.render('addArticle', { | ||
| user, | ||
| tags, | ||
| }) | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| handleAddArticle: (req, res) => { | ||
| const {title, TagId, content} = req.body | ||
| const UserId = req.session.userId | ||
| if(!title || !TagId || !content) { | ||
| req.flash('errorMessage', '請填入所有欄位') | ||
| return res.redirect('/addArticle') | ||
| } | ||
| Article.create({ | ||
| UserId, | ||
| title, | ||
| TagId, | ||
| content, | ||
| }).then(newArticle => { | ||
| res.redirect('/blog') | ||
| }).catch(error => { | ||
| console.log(error) | ||
| req.flash('errorMessage', '新增文章失敗') | ||
| return res.redirect('/addArticle') | ||
| }) | ||
| }, | ||
|
|
||
| updateArticle: (req, res) => { | ||
| const userId = req.session.userId | ||
| const ArticleId = req.params.id | ||
| if(!userId) return res.redirect('/blog') | ||
| Article.findByPk(ArticleId, { | ||
| include: [User, Tag] | ||
| }).then(article => { | ||
| if(article.isDeleted === 1) return res.redirect('/blog') | ||
| Tag.findAll({ | ||
| where: { | ||
| id: {[Op.ne]:article.TagId} | ||
| } | ||
| }).then(tags => { | ||
| res.render('updateArticle', { | ||
| article, | ||
| user: article.User, | ||
| tags, | ||
| }) | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| handleUpdateArticle: (req, res) => { | ||
| const ArticleId = req.params.id | ||
| const {title, TagId, content} = req.body | ||
| if(!title || !TagId || !content) { | ||
| req.flash('errorMessage', '請填入所有欄位') | ||
| return res.redirect(`/update/${ArticleId}`) | ||
| } | ||
| Article.update({ | ||
| title, | ||
| TagId, | ||
| content, | ||
| },{where: {id: ArticleId}}).then(newArticle => { | ||
| res.redirect('/blog') | ||
| }).catch(error => { | ||
| console.log(error) | ||
| req.flash('errorMessage', '更新文章失敗') | ||
| return res.redirect(`/update/${ArticleId}`) | ||
| }) | ||
| }, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以稍微排版一下,比如說 handleUpdateArticle = (req, res) => {
const ArticleId = req.params.id
const { title, TagId, content } = req.body
if (!title || !TagId || !content) {
req.flash('errorMessage', '請填入所有欄位')
return res.redirect(`/update/${ArticleId}`)
}
Article.update(
{
title,
TagId,
content,
},
{ where: { id: ArticleId } }
)
.then((newArticle) => {
res.redirect('/blog')
})
.catch((error) => {
console.log(error)
req.flash('errorMessage', '更新文章失敗')
return res.redirect(`/update/${ArticleId}`)
})
} |
||
|
|
||
| deleteArticle: (req, res) => { | ||
| const ArticleId = req.params.id | ||
| const sessionUserId = req.session.userId | ||
| Article.findByPk(ArticleId).then(article => { | ||
| if(article.UserId !== sessionUserId){ | ||
| return res.redirect('/admin') | ||
| } | ||
| Article.update({ | ||
| isDeleted: 1, | ||
| },{where: {id: ArticleId}}).then(newArticle => { | ||
| res.redirect('/admin') | ||
| }).catch(error => { | ||
| console.log(error) | ||
| req.flash('errorMessage', '刪除文章失敗') | ||
| return res.redirect('/admin') | ||
| }) | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| module.exports = blogController | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| const db = require('../models') | ||
| const User = db.User | ||
| const Article = db.Article | ||
| const bcrypt = require('bcrypt'); | ||
| const saltRounds = 10; | ||
| const myPlaintextPassword = 's0/\/\P4$$w0rD'; | ||
| const someOtherPlaintextPassword = 'not_bacon'; | ||
|
|
||
| const userController = { | ||
| register: (req, res) => { | ||
| res.render('register') | ||
| }, | ||
|
|
||
| handleRegister: (req, res) => { | ||
| const {username, password, nickname} = req.body | ||
| if(!username || !password || !nickname) { | ||
| req.flash('errorMessage', '請填入所有欄位') | ||
| res.redirect('/register') | ||
| return | ||
| } | ||
|
|
||
| bcrypt.hash(password, saltRounds, (error, hash) => { | ||
| User.create( | ||
| { | ||
| username, | ||
| password: hash, | ||
| nickname, | ||
| } | ||
| ).then(user => { | ||
| req.session.userId = user.id; | ||
| res.redirect('/blog') | ||
| }).catch(error => { | ||
| req.flash('errorMessage', error) | ||
| res.redirect('/register') | ||
| }) | ||
| }) | ||
| }, | ||
|
|
||
| login: (req, res) => { | ||
| res.render('login') | ||
| }, | ||
|
|
||
| logout: (req,res) => { | ||
| req.session.userId = null | ||
| res.redirect('/blog') | ||
| }, | ||
|
|
||
| handleLogin: (req, res) => { | ||
| const {username, password} = req.body | ||
| if(!username || !password) { | ||
| req.flash('errorMessage', '請輸入帳號及密碼') | ||
| res.redirect('login') | ||
| return | ||
| } | ||
|
|
||
| User.findOne({ | ||
| where: { | ||
| username, | ||
| } | ||
| }).then(user => { | ||
| if(!user) { | ||
| req.flash('errorMessage', '請輸入正確帳號及密碼') | ||
| res.redirect('login') | ||
| return | ||
| } | ||
| bcrypt.compare(user.password, password.toString(), (error, result) => { | ||
| if(error) { | ||
| req.flash('errorMessage', '請輸入正確帳號及密碼') | ||
| res.redirect('login') | ||
| return | ||
| } | ||
| req.session.userId = user.id; | ||
| res.redirect('blog') | ||
| }); | ||
| }).catch(error => { | ||
| req.flash('errorMessage', error.Message) | ||
| res.redirect('login') | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| module.exports = userController |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| 'use strict'; | ||
| module.exports = { | ||
| up: async (queryInterface, Sequelize) => { | ||
| await queryInterface.createTable('Articles', { | ||
| id: { | ||
| allowNull: false, | ||
| autoIncrement: true, | ||
| primaryKey: true, | ||
| type: Sequelize.INTEGER | ||
| }, | ||
| userId: { | ||
| type: Sequelize.INTEGER | ||
| }, | ||
| title: { | ||
| type: Sequelize.STRING | ||
| }, | ||
| content: { | ||
| type: Sequelize.TEXT | ||
| }, | ||
| tagId: { | ||
| type: Sequelize.INTEGER | ||
| }, | ||
| isDeleted: { | ||
| type: Sequelize.STRING | ||
| }, | ||
| createdAt: { | ||
| allowNull: false, | ||
| type: Sequelize.DATE | ||
| }, | ||
| updatedAt: { | ||
| allowNull: false, | ||
| type: Sequelize.DATE | ||
| } | ||
| }); | ||
| }, | ||
| down: async (queryInterface, Sequelize) => { | ||
| await queryInterface.dropTable('Articles'); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
這個應該放在環境變數才對,如同 secret 字面上的意思