【nodejs】大事件后台管理项目(三)——layui前端布局
作者:互联网
5. 文章管理
5.1 新建 ev_articles 表
CREATE TABLE `my_db_01`.`Untitled` (
`Id` int(0) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL COMMENT '文章标题',
`content` text NOT NULL COMMENT '文章内容',
`cover_img` varchar(255) NOT NULL COMMENT '封面图片',
`pub_date` varchar(255) NOT NULL COMMENT '文章发表日期',
`state` varchar(255) NOT NULL COMMENT '文章发布状态',
`is_delete` tinyint(255) NOT NULL DEFAULT 0 COMMENT '0未删除,1相反',
`cate_id` int(0) NOT NULL COMMENT '分类id',
`author_id` int(0) NOT NULL COMMENT '作者id',
PRIMARY KEY (`Id`),
UNIQUE INDEX(`Id`)
) COMMENT = '文章表';
5.2 发布新文章
5.2.0 实现步骤
- 初始化路由模块
- 初始化路由处理函数模块
- 使用 multer 解析表单数据
- 验证表单数据
- 实现发布文章的功能
5.2.1 初始化路由模块
- 创建
/router/article.js
路由模块,并初始化如下的代码结构:
// 导入 express
const express = require('express')
// 创建路由对象
const router = express.Router()
// 发布新文章
router.post('/add', (req, res) => {
res.send('ok')
})
// 向外共享路由对象
module.exports = router
- 在
app.js
中导入并使用文章的路由模块:
// 导入并使用文章路由模块
const articleRouter = require('./router/article')
// 为文章的路由挂载统一的访问前缀 /my/article
app.use('/my/article', articleRouter)
5.2.2 初始化路由处理函数模块
- 创建
/router_handler/article.js
路由处理函数模块,并初始化如下的代码结构:
// 发布新文章的处理函数
exports.addArticle = (req, res) => {
res.send('ok')
}
- 修改
/router/article.js
中的代码如下:
const express = require('express')
const router = express.Router()
// 导入文章的路由处理函数模块
const article_handler = require('../router_handler/article')
// 发布新文章
router.post('/add', article_handler.addArticle)
module.exports = router
5.2.3 使用 multer 解析表单数据
注意:使用
express.urlencoded()
中间件无法解析multipart/form-data
格式的请求体数据。
当前项目,推荐使用 multer 来解析
multipart/form-data
格式的表单数据。https://www.npmjs.com/package/multer
- 运行如下的终端命令,在项目中安装
multer
:
npm i multer@1.4.2
- 在
/router_handler/article.js
模块中导入并配置multer
:
// 导入解析 formdata 格式表单数据的包
const multer = require('multer')
// 导入处理路径的核心模块
const path = require('path')
// 创建 multer 的实例对象,通过 dest 属性指定文件的存放路径
const upload = multer({ dest: path.join(__dirname, '../uploads') })
- 修改
发布新文章
的路由如下:
// 发布新文章的路由
// upload.single() 是一个局部生效的中间件,用来解析 FormData 格式的表单数据
// 将文件类型的数据,解析并挂载到 req.file 属性中
// 将文本类型的数据,解析并挂载到 req.body 属性中
router.post('/add', upload.single('cover_img'), article_handler.addArticle)
- 在
/router_handler/article.js
模块中的addArticle
处理函数中,将multer
解析出来的数据进行打印:
// 发布新文章的处理函数
exports.addArticle = (req, res) => {
console.log(req.body) // 文本类型的数据
console.log('--------分割线----------')
console.log(req.file) // 文件类型的数据
res.send('ok')
}
测试
在认证条件下输入cover_img,查看返回值
5.2.4 验证表单数据
实现思路:通过 express-joi 自动验证 req.body 中的文本数据;通过 if 判断手动验证 req.file 中的文件数据;
- 创建
/schema/article.js
验证规则模块,并初始化如下的代码结构:
// 导入定义验证规则的模块
const joi = require('joi')
// 定义 标题、分类Id、内容、发布状态 的验证规则
const title = joi.string().required()
const cate_id = joi.number().integer().min(1).required()
const content = joi.string().required().allow('')
const state = joi.string().valid('已发布', '草稿').required()
// 验证规则对象 - 发布文章
exports.add_article_schema = {
body: {
title,
cate_id,
content,
state,
},
}
- 在
/router/article.js
模块中,导入需要的验证规则对象,并在路由中使用:
// 导入验证数据的中间件
const expressJoi = require('@escook/express-joi')
// 导入文章的验证模块
const { add_article_schema } = require('../schema/article')
// 发布新文章的路由
// 注意:在当前的路由中,先后使用了两个中间件:
// 先使用 multer 解析表单数据
// 再使用 expressJoi 对解析的表单数据进行验证
router.post('/add', upload.single('cover_img'), expressJoi(add_article_schema), article_handler.addArticle)
- 在
/router_handler/article.js
模块中的addArticle
处理函数中,通过if
判断客户端是否提交了封面图片
:
// 发布新文章的处理函数
exports.addArticle = (req, res) => {
// 手动判断是否上传了文章封面
if (!req.file || req.file.fieldname !== 'cover_img') return res.cc('文章封面是必选参数!')
// TODO:表单数据合法,继续后面的处理流程...
})
5.2.5 实现发布文章的功能
以下的内容放到/router_handler/article.js
的处理函数中
- 整理要插入数据库的文章信息对象:
// 导入处理路径的 path 核心模块
const path = require('path')
//注意:放入到处理函数内
const articleInfo = {
// 标题、内容、状态、所属的分类Id
...req.body,
// 文章封面在服务器端的存放路径
cover_img: path.join('/uploads', req.file.filename),
// 文章发布时间
pub_date: new Date(),
// 文章作者的Id
author_id: req.auth.id,
}
- 定义发布文章的 SQL 语句:
const sql = `insert into ev_articles set ?`
- 调用
db.query()
执行发布文章的 SQL 语句:
// 导入数据库操作模块
const db = require('../db/index')
// 执行 SQL 语句
db.query(sql, articleInfo, (err, results) => {
// 执行 SQL 语句失败
if (err) return res.cc(err)
// 执行 SQL 语句成功,但是影响行数不等于 1
if (results.affectedRows !== 1) return res.cc('发布文章失败!')
// 发布文章成功
res.cc('发布文章成功', 0)
})
- 在
app.js
中,使用express.static()
中间件,将uploads
目录中的图片托管为静态资源:
// 托管静态资源文件
app.use('/uploads', express.static('./uploads'))
测试
我的踩坑点:
- 原来之所以使用
multipart/form-data
的格式提交数据是因为cover_img
不承认提交网络图片链接的形式,而是要选择本地文件,不然是无法读取到文件类型的,点击File
即可,postman
的我不清楚。
articleInfo
对象中的req.user
一定要改成req.auth
,不然它会一直提示Cannot read properties of undefined (reading 'id')
的错误,现在就可以看到我提交成功了。
可以看到我在uploads文件夹中存放着以二进制流的形式存放图片数据。
5.3 查看文章列表
6. layui大事件项目
文件位置:1.Node.js零基础入门教程\node.js—资料\day8\素材\大事件项目
在assets/js/baseAPI.js
中修改统一请求根路径
6.1 调整接口名称
纯粹是因为之前本人手贱,故意修改名称与端口所致的。
在assets/js/login.js
中修改注册的post接口
6.2 express启动
先在VSCode的扩展中加上express插件先
接着启动之前的api_server
后端项目
nodemon app.js
然后再回到前端项目,按住ctrl+shift+p
调出Express: Host Current Workspace and Open in Browser
6.3 最终效果
输入我的数据库信息(因人而异):
- 账号:ks
- 密码:123456
标签:req,const,nodejs,layui,router,js,文章,后台,article 来源: https://www.cnblogs.com/PaturNax/p/16540422.html