Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .sequelizerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

const path = require('path');

module.exports = {
config: path.join(__dirname, 'database/config.json'),
'migrations-path': path.join(__dirname, 'database/migrations'),
'seeders-path': path.join(__dirname, 'database/seeders'),
'models-path': path.join(__dirname, 'app/model'),
};
51 changes: 6 additions & 45 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,9 @@
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const { User } = require('./models');
const { Pagination } = require('./app/service/utils/pagination');
const { MessageFormatter } = require('./app/service/utils/messageFormatter');

module.exports = app => {
app.passport.use(
new LocalStrategy(
{
usernameField: 'account',
passwordField: 'password',
passReqToCallback: true,
},
async (req, account, password, cb) => {
try {
const user = await User.findOne({ where: { account } });
if (!user) {
return cb(null, false, { message: '帳號錯誤' });
}
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
return cb(null, false, { message: '密碼錯誤' });
}
return cb(null, user);
} catch (err) {
return cb(err);
}
}
)
);

app.passport.serializeUser(async (ctx, user) => {
return user.id;
});

app.passport.deserializeUser(async (ctx, id) => {
try {
const user = await User.findByPk(id);

if (!user) {
return null;
}

return user;
} catch (err) {
return null;
}
});
app.context.utils = {
MessageFormatter,
Pagination,
};
};
10 changes: 5 additions & 5 deletions app/controller/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,31 @@ module.exports = app => {

async getMessages() {
const { ctx, service } = this;
const [ data, pagination, page ] = await service.user.getMessages();
const [ data, pagination, page ] = await service.board.getMessages();
await ctx.render('message', { data, pagination, page });
}

async postMessage() {
const { ctx, service } = this;
await service.user.postMessage();
await service.board.postMessage();
await ctx.redirect('/message');
}

async editMessage() {
const { ctx, service } = this;
const [ data, page ] = await service.user.editMessage();
const [ data, page ] = await service.board.editMessage();
await ctx.render('message_edit', { data, page });
}

async putMessage() {
const { ctx, service } = this;
await service.user.putMessage();
await service.board.putMessage();
await ctx.redirect('/message');
}

async deleteMessage() {
const { ctx, service } = this;
await service.user.deleteMessage();
await service.board.deleteMessage();
await ctx.redirect('/message');
}
};
Expand Down
37 changes: 0 additions & 37 deletions app/extend/helper.js

This file was deleted.

6 changes: 3 additions & 3 deletions app/middleware/login.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const { User } = require('../../models');

const bcrypt = require('bcryptjs');

module.exports = options => {
return async function login(ctx, next) {
try {
const { account, password } = ctx.request.body;
const user = await User.findOne({ where: { account } });
const user = await ctx.model.User.findOne({ where: { account } });
if (!user) { throw new Error('帳號錯誤'); }
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) { throw new Error('密碼錯誤'); }
const { id } = user;
ctx.session.user = id;
ctx.session.userId = id;
await next();
} catch (err) {
ctx.throw(400, err.message);
Expand Down
31 changes: 31 additions & 0 deletions app/model/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// app/model/message.js
'use strict';

module.exports = app => {
const { INTEGER, STRING, DATE } = app.Sequelize;

const Message = app.model.define('message', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: false,
},
userId: INTEGER,
comment: STRING,
// createdAt: DATE,
createdAt: {
type: DATE,
defaultValue: app.Sequelize.literal('CURRENT_TIMESTAMP'),
},
}, {
tableName: 'Messages', // 指定表名
});

Message.associate = models => {
// 定义关联关系
Message.belongsTo(app.model.User, { foreignKey: 'userId' });
};

return Message;
};

22 changes: 22 additions & 0 deletions app/model/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// app/model/user.js
'use strict';

module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const User = app.model.define('User', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
account: STRING, // assuming account is equivalent to STRING in the original code
password: STRING, // assuming password is equivalent to STRING in the original code
}, {
tableName: 'Users', // 指定表名
});

User.associate = models => {
// define association here
User.hasMany(app.model.Message, { foreignKey: 'userId' });
};

return User;
};

41 changes: 19 additions & 22 deletions app/schedule/update_cache.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const { Message } = require('../../models');

module.exports = {
schedule: {
Expand All @@ -10,41 +9,39 @@ module.exports = {
const updateLength = await app.redis.llen('update');
if (updateLength > 0) {
for (let i = 0; i < updateLength; i += 50) {
const redisData = await app.redis.lpop('update', 50);
const updateFromRedis = redisData.map(element => JSON.parse(element));
for (const update of updateFromRedis) {
await Message.create({
id: update.data.id,
userId: update.data.userId,
comment: update.data.comment,
createdAt: update.createdAt,
});
}
const redisUpdateMessage = await app.redis.lpop('update', 50);
const updateFromRedis = redisUpdateMessage.map(element => JSON.parse(element));
const bulkInsertData = updateFromRedis.map(update => ({
id: update.data.id,
userId: update.data.userId,
comment: update.data.comment,
createdAt: update.createdAt,
}));
await ctx.model.Message.bulkCreate(bulkInsertData);
}
}

const editLength = await app.redis.llen('edit');
if (editLength > 0) {
for (let i = 0; i < editLength; i += 50) {
const redisData = await app.redis.lpop('edit', 50);
const editFromRedis = redisData.map(element => JSON.parse(element));
for (const edit of editFromRedis) {
const message = await Message.findByPk(edit.messageId);
await message.update({
const redisEditMessage = await app.redis.lpop('edit', 50);
const editFromRedis = redisEditMessage.map(element => JSON.parse(element));
const updatePromises = editFromRedis.map(async edit => {
const message = await ctx.model.Message.findByPk(edit.messageId);
return message.update({
comment: edit.comment,
});
}
});
await Promise.all(updatePromises);
}
}

const deleteLength = await app.redis.llen('delete');
if (deleteLength > 0) {
for (let i = 0; i < deleteLength; i += 50) {
const redisData = await app.redis.lpop('delete', 50);
for (const dele of redisData) {
const message = await Message.findByPk(dele);
await message.destroy();
}
const redisDeleteMessage = await app.redis.lpop('delete', 50);
const deleteIds = redisDeleteMessage.map(deleteItem => Number(deleteItem));
await ctx.model.Message.destroy({ where: { id: deleteIds } });
}
}
},
Expand Down
Loading