这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
在之前我们写好了登录和注册两个接口,并颁发了令牌,接下来我们今天做发表文章(增删改查)
详细请看这篇文章:第二篇文章
大致的流程是这样的
1. 创建文章表
CREATE TABLE IF NOT EXISTS `moment`(
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(1000) NOT NULL,
user_id INT NOT NULL,
createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY(user_id) REFERENCES user(id)
);
2. 创建moment路由
moment.router.js
const Router = require('koa-router')
const momentRouter = new Router({prefix: '/moment'})
const {
create
} = require('../controller/moment.controller')
// 发表动态
momentRouter.post("/",)
module.exports = momentRouter
moment.controller.js
class MomentController {
async create(ctx, next) {
ctx.body = "发表评论成功"
}
}
module.exports = new MomentController()
实现验证是否登录的中间件verifyAuth,属于auth.middleware.js
const jwt = require("jsonwebtoken"); //之前登录用的私钥加密的,我们现在要来用公钥来解密
const { PUBLIC_KEY } = require("../app/config"); //公钥
// 验证是否登录
const verifyAuth = async (ctx, next) => {
const authorization = ctx.headers.authorization;
// 获取token
if (!authorization) {
const error = new Error(errorTypes.UNAUTHORIZATION);
return ctx.app.emit("error", error, ctx);
}
const token = authorization.replace("Bearer ", "");
// 验证token
try {
const result = jwt.verify(token, PUBLIC_KEY, {
algorithms: ["RS256"],
});
ctx.user = result;
await next();
} catch (err) {
const error = new Error(errorTypes.UNAUTHORIZATION);
ctx.app.emit("error", error, ctx);
}
};
module.exports = {
verifyAuth
};
当验证成功后,进入我们发表文章中间件create
const momentService = require("../service/moment.service");
async create(ctx, next) {
// 获取数据(user_id, content)
const userId = ctx.user.id;
const content = ctx.request.body.content;
// 数据插入到数据库
const result = await momentService.create(userId, content);
ctx.body = result;
}
const connection = require("../app/database");
class MomentService {
//将获取到的评论内容插入到数据中
async create(userId, content) {
const statement = `INSERT INTO moment (content, user_id) VALUES (?, ?);`;
const [result] = await connection.execute(statement, [content, userId]);
return result;
}
}
module.exports= new MomentService()
测试
查询动态(单)
//moment.router.js
const {
detail
} = require('../controller/moment.controller')
// 查询动态(单)
momentRouter.get("/:momentId", detail)
//moment.controller.js
class MomentController {
async detail(ctx, next) {
const momentId = ctx.params.momentId
ctx.body = momentId //2
}
}
module.exports = new MomentController();
获取到要查询的文章id后,我们进入数据开始查询(返回的数据有,文章,用户id, 发表时间, 更新时间)
//moment.service.js
const connection = require("../app/database");
class MomentService {
async getMomentById(id) {
//这里也可以用tyrcatch来捕获一下,以后出错了方便查找
const statement = `
SELECT
m.id id, m.content content, m.createAt createTime, m.updateAt updateTime,
JSON_OBJECT('id', u.id, 'name', u.name) author
from moment m
LEFT JOIN user u ON m.user_id = u.id
WHERE m.id = ?
`
const [result] = await connection.execute(statement, [id])
return result
}
}
module.exports= new MomentService()
将结果返回给用户
//moment.controller.js
const momentService = require("../service/moment.service");
class MomentController {
async detail(ctx, next) {
// 获取id
const momentId = ctx.params.momentId;
// 根据id去查询
const result = await momentService.getMomentById(momentId);
ctx.body = result;
}
}
module.exports = new MomentController();
查询动态(多)流程和查询单个的差不多,唯一不同的就是数据库查询
// moment.router.js
const {
list
} = require('../controller/moment.controller')
// 查询动态(多)
momentRouter.get("/", list)
获取传入的query,然后传入数据库进行查询
const momentService = require("../service/moment.service");
class MomentController {
async list(ctx, next) {
// 获取数据(offset, size)
const { offset, size } = ctx.query;
const result = await momentService.getMomentList(offset, size);
ctx.body = result;
}
}
module.exports = new MomentController();
const connection = require("../app/database");
class MomentService {
async getMomentList(offset, size) {
const statement = `
SELECT
m.id id, m.content content, m.createAt createTime, m.updateAt updateTime,
JSON_OBJECT('id', u.id, 'name', u.name) author
FROM moment m
LEFT JOIN user u ON m.user_id = u.id
LIMIT ?, ?;
`
const [result] = await connection.execute(statement, [offset, size])
return result
}
}
module.exports= new MomentService()
修改动态
graph TD
必须登录 --> 要修改的动态是属于登录的那个人 --> 修改成功/修改失败
封装验证权限中间件verifyPermission
//auth.middleware.js
// 通过闭包来实现
const verifyPermission = (tableName) => { //要查询的表
return async (ctx, next) => {
// 取数据
const {commentId} = ctx.params //获取文章的id
const { id } = ctx.user; //用户的id
// 查询
const isPermission = await authService.checkResoure(
tableName,
commentId,
id
);
// 判断是否具备,如果不具备就抛出异常
if (!isPermission) {
const error = new Error(errorTypes.UNPERMISSION);
return ctx.app.emit("error", error, ctx);
}
await next();
};
}
module.exports = {
verifyPermission
};
// auth.service.js
const connection = require("../app/database");
//根据要查询的表,id,用户id来查询他是否存在
class AuthService {
async checkResoure(tableName, resourceId, userId) {
const statement = `SELECT * from ${tableName} WHERE id = ? AND user_id = ?`;
const [result] = await connection.execute(statement, [resourceId, userId]);
return result.length === 0 ? false : true;
}
}
module.exports = new AuthService();
当具备后,拿到修改的内容,去数据库里进行修改并提示成功
// moment.router.js
const {
update
} = require('../controller/moment.controller')
const {
verifyAuth,
verifyPermission
} = require('../middleware/auth.middleware.js')
// 修改动态
momentRouter.patch("/:momentId", verifyAuth, verifyPermission(moment), update)
// moment.controller
const momentService = require("../service/moment.service");
class MomentController {
async update(ctx, next) {
const { momentId } = ctx.params;
const { content } = ctx.request.body;
const result = await momentService.update(content, momentId);
ctx.body = result;
}
}
module.exports = new MomentController();
// moment.service.js
const connection = require("../app/database");
class MomentService {
async update(content, momentId) {
try {
const statement = `UPDATE moment SET content = ? WHERE id = ?`;
const [result] = await connection.execute(statement, [content, momentId]);
return result;
} catch (error) {
console.log(error);
}
}
}
module.exports= new MomentService()
删除动态
graph TD
必须登录 --> 要删除的动态是属于登录的那个人 --> 删除成功/删除失败
// moment.router.js
const {
remove
} = require('../controller/moment.controller')
const {
verifyAuth,
verifyPermission
} = require('../middleware/auth.middleware.js')
// 删除动态
momentRouter.delete("/:momentId", verifyAuth, verifyPermission(moment), remove)
//moment.controller.js
const momentService = require("../service/moment.service");
class MomentController {
async remove(ctx, next) {
const { momentId } = ctx.params;
const result = await momentService.remove(momentId);
ctx.body = result;
}
}
module.exports = new MomentController();
// moment.service.js
const connection = require("../app/database");
class MomentService {
async remove(momentId) {
try {
const statement = `DELETE FROM moment WHERE id = ?`;
const [result] = await connection.execute(statement, [momentId]);
return result;
} catch (error) {
console.log(error);
}
}
}
module.exports= new MomentService()