node mysql和koa_node+koa2+mysql搭建博客后台
本文将详细讲解使用node+koa2+mysql搭建博客后台的全过程。
开发环境
node 8.3.0及以上
npm 5.3.0及以上
mysql 5.7.21
具体的环境配置可查看我的上一篇文章
准备工作
npm下载pm2(进程守护),并设置全局变量
创建博客需要的数据库与表
开启mysql并创建数据库test: create database test;
切换到数据库testuse tests;,输入命令创建以下数据表:
//系统管理员表 t_user
CREATE TABLE `t_user` (
`uid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL COMMENT '姓名',
`password` varchar(50) NOT NULL COMMENT '密码',
`create_time` datetime NOT NULL COMMENT '注册时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_delete` tinyint(1) DEFAULT '0',
PRIMARY KEY (`uid`),
UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
//笔记本表 t_note
CREATE TABLE `t_note` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL COMMENT '笔记本名',
`uid` int(11) NOT NULL COMMENT 'uid',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_delete` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
//博客记录表 t_blog
CREATE TABLE `t_blog` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL COMMENT '标题',
`uid` int(11) DEFAULT '1' COMMENT 'uid',
`content` text COMMENT '内容',
`create_time` datetime NOT NULL COMMENT '注册时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`note_id` varchar(45) DEFAULT NULL,
`publish` tinyint(4) DEFAULT '0' COMMENT '是否发布',
`brief` text,
`is_delete` tinyint(1) DEFAULT '0' COMMENT '是否删除',
`ext_info` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
//图片上传记录表 t_img
CREATE TABLE `t_img` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL COMMENT 'uid',
`create_time` datetime NOT NULL COMMENT '注册时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`name` varchar(40) DEFAULT NULL,
`is_delete` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
复制代码
node后台目录创建及npm包安装
创建项目文件夹server,进入文件夹后初始化项目npm init。
在项目下创建以下文件夹和文件
安装以下依赖包:
koa node框架
koa-bodyparser 表单解析中间件
koa-router 路由框架
koa-session 基于koa的session模块
mysql 数据库
md5 md5加密
async-busboy 带文件的表单解析模块
is 数据格式校验插件
node连接mysql
db/index.js配置文件如下:
var mysql = require('mysql');
let config = {
host : 'localhost',
user : 'root',
password : '123456',
database : 'test',
port:3306,
multipleStatements: true//允许多条sql同时执行
};
let pool = mysql.createPool(config);
let query = (sql, values) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
reject(err)
} else {
connection.query(sql, values, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.end()
})
}
})
})
};
module.exports = {
query
}
复制代码
其他配置
框架公用方法,包括参数校验、登录态校验等。config/index.js
路由 Rouer
以上配置完成后,便可以开始写设计路由了。
引入相关配置
const router = require('koa-router')();
const Utils = require('../utils');
const Tips = require('../utils/tip');
const db = require('../db');
复制代码
根据表设计路由
user表 -> user.js 管理员管理,可登录、查询登录态、退出登录
note表 -> note.js 笔记本管理,可添加、修改、删除,查询笔记本列表
blog表 -> blog.js 博客管理 可添加、修改、删除、查询博客列表。每篇博客必须关联对应的笔记本。可根据笔记本查询博客列表
img表 -> img.js 图片管理,可上传、删除、查询图片列表
具体路由部分实现内容
注意:所有的删除操作均为将表字段is_delete设置为1即可,方便恢复数据
user.js 管理员
登录
router.post('/oa/login', async (ctx, next) => {
let data = Utils.filter(ctx.request.body, ['name', 'password']);
let res = Utils.formatData(data,[
{key:'name',type:'string'},
{key:'password',type:'string'}
]);
if(!res) return ctx.body = Tips[1007];
let { name, password } = data;
let sql = 'SELECT uid FROM t_user WHERE name=? and password=? and is_delete=0', value = [name, md5(password)];
await db.query(sql, value).then(res => {
if (res && res.length > 0) {
let val = res[0];
let uid = val['uid']
ctx.session.uid = uid;
ctx.cookies.set('uid', uid, {
maxAge:86400000,
httpOnly: true
});
ctx.body = {...Tips[0],data:{uid}};
} else {
ctx.body = Tips[1006];
}
}).catch(e => {
ctx.body = Tips[1002];
})
});
复制代码查询登录信息
router.get('/oa/user/auth', async (ctx, next) => {
let uid = ctx.session.uid;
let sql = 'SELECT name,uid,nick_name FROM t_user WHERE uid=? AND is_delete=0', value = [uid];
await db.query(sql, value).then(res => {
if (res && res.length > 0) {
ctx.body = { ...Tips[0], data: res[0] };
} else {
ctx.body = Tips[1005];
}
}).catch(e => {
ctx.body = Tips[1005];
})
});
复制代码
note.js 笔记本管理
创建笔记本
router.post('/oa/user/addNote',async (ctx,next)=>{
let data = Utils.filter(ctx.request.body, ['name']);
let {name} = data, uid = ctx.session.uid;
let res = Utils.formatData(data, [
{key: 'name', type: 'string'}
]);
if (! res) return ctx.body = Tips[1007];
let create_time = Utils.formatCurrentTime();
let sql = `INSERT INTO t_note(name,uid,create_time) VALUES(?,?,?)`,
value = [name, uid, create_time];
await db.query(sql, value).then(res => {
let {insertId: id} = res;
if (id) {
ctx.body = {
...Tips[0],
data: {
id
}
}
} else {
ctx.body = Tips[1002]
}
}).catch(e => {
if(+e.errno === 1062){//笔记本不能重复
ctx.body = {
code: 1010,
msg: '笔记本已存在!'
};
}else{
ctx.body = Tips[1002]
}
})
});
复制代码(分页)查询笔记本列表
router.get('/oa/user/myNote', async (ctx, next) => {
let data = Utils.filter(ctx.request.query, ['pageSize', 'pageNum', 'type']), uid = ctx.session.uid;
let res = Utils.formatData(data, [
{key: 'type', type: 'number'},
]);
if (! res) return ctx.body = Tips[1007];
let {pageSize = 15, pageNum = 1, type = 0} = data;
pageSize = Number(pageSize);
pageNum = Number(pageNum);
let offset = (pageNum - 1) * pageSize;
let sql1 = `SELECT count(1) FROM t_note WHERE uid=${uid} AND is_delete=0;`,
sql= `SELECT name,id,create_time,update_time FROM t_note WHERE uid=${uid} AND is_delete=0 ORDER BY create_time DESC`;
if(+type === 1){
sql += ` limit ${offset},${pageSize};`
}
await db.query(sql1+sql).then(async result => {
let res1 = result[0],res2 = result[1],total = 0,list = []
if(res1 && res1.length >0 && res2 && res2.length >0){
total = res1[0]['count(1)']
list = res2
}
ctx.body = {
...Tips[0],
data: {
list,
pageSize,
total
}
};
}).catch(e => {
ctx.body = Tips[1002];
})
});
复制代码
blog.js 博客
创建博客
router.post('/oa/user/addBlog', async (ctx, next) => {
let data = Utils.filter(ctx.request.body, ['title', 'content', 'tag_id', 'note_id', 'brief', 'publish', 'create_time']),
uid = ctx.session.uid;
let res = Utils.formatData(data, [
{key: 'note_id', type: 'number'},
{key: 'title', type: 'string'},
{key: 'brief', type: 'string'},
{key: 'content', type: 'string'},
{key: 'publish', type: 'number'}
]);
if (! res) return ctx.body = Tips[1007];
let {title = '无标题', content = '', note_id = '', brief = '', publish = 0, create_time = ''} = data;
create_time = Utils.formatCurrentTime(create_time);
let sql = `INSERT INTO t_blog(title,content,note_id,create_time,uid,brief,publish) VALUES (?,?,?,?,?,?,?)`,
value = [title, content, note_id, create_time, uid, brief, publish];
await db.query(sql, value).then(async res => {
let {insertId: id} = res;
ctx.body = {
...Tips[0],
data: {id}
}
}).catch(e => {
ctx.body = Tips[1002];
});
});
复制代码分页查询博客,与笔记本列表查询类似
img.js 图片管理
上传图片
router.post('/oa/user/upFiles', async (ctx, next) => {
try {
let data = await asyncBusboy(ctx.req), uid = ctx.session.uid;
let { files = [] } = data;
if(files.length === 0) return ctx.body = Tips[1002];
let file = files[0];
let { mimeType = '', filename, path: filepath } = file;
if(mimeType.indexOf('image') === -1) return ctx.body = Tips[1002];
let name = Date.now() + '.' + filename.split('.').pop();
let savePath = path.join(__dirname, `../../img/${name}`);
try {
let create_time = Utils.formatCurrentTime();
let sql = 'INSERT INTO t_user_img(name,uid,create_time) VALUES (?,?,?)', value = [name, uid, create_time];
await db.query(sql, value).then(res => {
let img = fs.readFileSync(filepath);
fs.writeFileSync(savePath, img);
fs.unlinkSync(filepath);//清除缓存文件
ctx.body = {
...Tips[0], data: { name }
};
}).catch(() => {
ctx.body = Tips[1002];
})
} catch (e) {
ctx.body = Tips[1005];
}
} catch (e) {
ctx.body = Tips[1002];
}
});
复制代码
2.删除图片
router.post('/oa/user/removeImg', async (ctx, next) => {
let data = Utils.filter(ctx.request.body, ['name']), uid = ctx.session.uid;
let res = Utils.formatData(data, [
{ key: 'name', type: 'string' }
]);
if (!res) return ctx.body = Tips[1007];
let { name } = data;
let sql = 'UPDATE t_user_img set is_delete=1 WHERE name=? AND uid=?;', value = [name, uid];
await db.query(sql, value).then(res => {
fs.unlinkSync(path.join(__dirname, `../../img/${name}`));//清除缓存文件
ctx.body = Tips[0];
}).catch(() => {
ctx.body = Tips[1002];
})
});
复制代码图片列表查询同笔记本列表查询
路由统一管理
router/index.js将所有的路由集成并挂载至app.js
router/index.js
const user = require('./user');
const note = require('./note');
const blog = require('./blog');
const img = require('./img');
module.exports = function(app){
app.use(user.routes()).use(user.allowedMethods());
app.use(note.routes()).use(note.allowedMethods());
app.use(blog.routes()).use(blog.allowedMethods());
app.use(img.routes()).use(img.allowedMethods());
}
复制代码
app.js(对需要登录的路由统一管理)
const http = require('http');
const koa = require('koa');
const etag = require('koa-etag');
const session = require('koa-session');
const bodyParser = require('koa-bodyparser');
const errorHandler = require('koa-error');
const compress = require('koa-compress');
const PORT = process.env.PORT || 8080;
const koaBody = require('koa-body');
const app = new koa();
const Utils = require('./utils');
const router = require('./router');
app.keys = ['session@&'];
app.use(session({
key: 'abc::sess',
maxAge: 86400000,
overwrite: true,
httpOnly: true,
signed: true,
rolling: false
}, app));
app.use(koaBody());
app.use(async(ctx, next) => {
let {url = ''} = ctx;
if(url.indexOf('/oa/user/') >-1){//需要校验登录态
let check = Utils.checkLogin(ctx);
if(check.code != 0) return ctx.body = check;
}
await next();
});
app.use(errorHandler());
app.use(bodyParser());
app.use(etag());
// compressor
app.use(compress({
filter: contentType => /text|javascript/i.test(contentType),
threshold: 2048
}));
router(app);
http.createServer(app.callback()).listen(PORT);
log('server is running on port: %s', PORT);
复制代码
以上便是后台搭建全过程,点此查看后台源码。
node mysql和koa_node+koa2+mysql搭建博客后台相关推荐
- node+koa2+mysql搭建博客后台
本文将详细讲解使用node+koa2+mysql搭建博客后台的全过程. 开发环境 node 8.3.0及以上 npm 5.3.0及以上 mysql 5.7.21 具体的环境配置可查看我的上一篇文章 准 ...
- mysql与citespace_CiteSpace与MySQL数据库的连接-科学网—博客.PDF
CiteSpace与MySQL数据库的连接-科学网-博客.PDF CiteSpace与MySQL数据库的连接 1,2 3 李杰 ,陈超美 1.上海海事大学海洋科学与工程学院 2.上海海事大学科技情报研 ...
- 基于SSM+SpringBoot+MySQL+Vue前后端分离的博客论坛系统
项目运行截图 系统首页 技术描述 开发工具: idea/eclipse 数据库: mysql Jar包仓库: Maven 前段框架: vue/ElementUI/echart 后端框架: spring ...
- 建站规划—基于私有化gitlab/node+hexo搭建博客网站
目录 概述 建站方案及成本 建站方案 成本 低成本替代方案 概述 本合辑(建站合辑)将介绍如何基于私有化gitlab+pages+Hexo搭建博客网站,由于域名备案周期较长,因此更新可能较慢.根据功能 ...
- Ghost 搭建博客小记
前言 点击 我用 Ghost 搭建的博客 查看成品示例. 早就听说 Ghost 的大名了,不过一直都是处于观望状态.主要是想等 Ghost 各方面再成熟一些,所以迟迟没有行动.最近听闻 Ghost 已 ...
- Vue、Node全栈项目~面向小白的博客系统~
个人博客系统 前言 ❝ 代码质量问题轻点喷(去年才学的前端),有啥建议欢迎联系我,联系方式见最下方,感谢! 页面有啥bug也可以反馈给我,感谢! 这是一套包含前后端代码的个人博客系统,欢迎各位提出建议 ...
- 详解Hexo搭建博客的底层原理
文章目录 前言 Github page Hexo 工作原理 每次部署的流程 模板引擎--Hexo怎样生成HTML 数据填充 配置文件中的数据 配置文件中数据的使用 总结 前言 在2021年初对照着攻略 ...
- 《全栈营销之如何制作个人博客》之二:php环境安装及个人博客后台搭建 让你的博客跑起来...
上一节我们讲了个人博客用什么开发语言,用什么CMS系统,从这一节我们就开始真正的干货,这一节我们讨论一下PHP环境的安装,及个人博客后台的搭建,让你的博客在正常的PHP环境中运行起来,你就可以进行后台 ...
- 使用Docker 实现微服务并搭建博客,一文全掌握
转载自 使用Docker 实现微服务并搭建博客,一文全掌握 Docker 是一个容器工具,提供虚拟环境.很多人认为,它改变了我们对软件的认识. 本文,通过搭建一个博客的例子,来介绍如何使用Docke ...
最新文章
- Linux 磁盘挂载
- apk修改strings.xml后重新打包出错
- [NOIP2014] 解方程
- 如何在window上把你的项目提交到github
- MySQL 常见索引的使用场景与区别(SQL小技巧)
- vue ----vue-cli
- 深度学习基础(三)—— 权值矩阵的初始化
- JavaEE学习14(应用)--用户自动登陆
- Java拦截器实现拦截controller方法
- 想批量转换音频?来试试这几个会议录音转文字软件
- Jquery Uploadify之Java获取动态传参参数
- 在线定时任务表达式生成连接
- 一款超好用的开源密码管理器?
- 文字下划线从中间往两头延伸动画
- Python3 歌词解析的练习
- 急性心机梗护理查房PPT模板
- POJ 1584 计算几何 凸包
- 话说13款浏览器哪个好?
- TIMO 后台管理系统 v2.0 发布,带来全新的项目结构,支持前后台模块分离部署!...
- echarts主题配置