2.首页、分类、课程接口
章节接口
const express = require("express")
const router = express.Router()
const { Course, Category, Chapter, User } = require("../models")
const { success, failure } = require("../utils/responses")
router.get("/:id", async (req, res) => {
try {
const { id } = req.params
const condition = {
attributes: {
exclude: ["CourseId"],
},
include: [
{
model: Course,
as: "course",
attributes: {
exclude: ["id", "name"],
},
include: [
{
model: User,
as: "user",
attributes: {
exclude: ["id", "username", "nickname", "avatar", "company"],
},
},
],
},
],
}
const chapter = await Chapter.findByPk(id, condition)
if (!chapter) {
throw new Error("chapter not found,章节未找到")
}
const chapters = await Chapter.findAll({
attributes: {
exclude: ["CourseId", "content"],
},
where: {
courseId: chapter.courseId,
},
order: [
["rank", "DESC"],
["id", "DESC"],
],
})
success(
res,
{
chapter,
chapters,
},
"查询章节成功"
)
} catch (error) {
failure(res, error)
}
})
module.exports = router
文章列表接口
const express = require("express")
const router = express.Router()
const { Article } = require("../models")
const { success, failure } = require("../utils/responses")
router.get("/", async (req, res) => {
try {
const query = req.query
const currentPage = Math.abs(query.currentPage) || 1
const pageSize = Math.abs(query.pageSize) || 10
const offset = (currentPage - 1) * pageSize
const condition = {
attributes: {
exclude: ["content"],
},
order: [["id", "DESC"]],
limit: pageSize,
offset,
}
const { count, rows } = await Article.findAndCountAll(condition)
success(
res,
{
articles: rows,
pagination: {
total: count,
currentPage,
pageSize,
},
},
"查询文章列表成功"
)
} catch (error) {
failure(res, error)
}
})
router.get("/:id", async (req, res) => {
try {
const id = req.params.id
const article = await Article.findByPk(id)
if (!article) {
return failure(res, "文章不存在")
}
success(res, { article }, "查询文章详情成功")
} catch (error) {
failure(res, error)
}
})
module.exports = router
系统设置接口
const express = require("express")
const router = express.Router()
const { Setting } = require("../models")
const { success, failure } = require("../utils/responses")
router.get("/", async (req, res) => {
try {
const setting = await Setting.findOne()
if (!setting) {
return failure(res, "设置不存在")
}
success(res, { setting }, "查询设置成功")
} catch (error) {
failure(res, error)
}
})
module.exports = router
搜索接口
const express = require("express")
const router = express.Router()
const { Course } = require("../models")
const { success, failure } = require("../utils/responses")
const { Op } = require("sequelize")
router.get("/", async (req, res) => {
try {
const query = req.query
const currentPage = Math.abs(query.page) || 1
const pageSize = Math.abs(query.pageSize) || 10
const offset = (currentPage - 1) * pageSize
const keyword = query.keyword || ""
const condition = {
attributes: {
exclude: ["categoryId", "UserId", "content"],
},
order: [["id", "DESC"]],
limit: pageSize,
offset,
}
if (query.name) {
condition.where = {
name: {
[Op.like]: `%${query.name}%`,
},
}
}
const { count, rows } = await Course.findAndCountAll(condition)
success(
res,
{
courses: rows,
pagination: {
total: count,
currentPage,
pageSize,
},
},
"搜索课程成功。"
)
} catch (error) {
failure(res, error)
}
})
module.exports = router
app.js中引入
const chaptersRouter = require("./routes/chapters")
const articlesRouter = require("./routes/articles")
const settingsRouter = require("./routes/settings")
const searchRouter = require("./routes/search")
app.use("/chapters", chaptersRouter)
app.use("/articles", articlesRouter)
app.use("/settings", settingsRouter)
app.use("/search", searchRouter)
3.用户注册、登录、认证接口
用户注册,隐藏密码
const express = require("express")
const router = express.Router()
const { User } = require("../models")
const { success, failure } = require("../utils/responses")
const { BadRequestError, UnauthorizedError, NotFoundError } = require("../utils/error")
const bcrypt = require("bcryptjs")
const jwt = require("jsonwebtoken")
const { Op } = require("sequelize")
router.post("/sign_up", async (req, res) => {
try {
const { username, password, nickname, email } = req.body
const body = { username, password, nickname, email, sex: 2, role: 0 }
const user = await User.create(body)
delete user.dataValues.password
success(res, { user }, "注册成功")
} catch (error) {
failure(res, error)
}
})
module.exports = router
用户登录
router.post("/sign_in", async (req, res) => {
try {
const { login, password } = req.body
if (!login) {
throw new BadRequestError("邮箱或用户名不能为空")
}
if (!password) {
throw new BadRequestError("密码不能为空")
}
const condition = {
where: {
[Op.or]: [{ username: login }, { email: login }],
},
}
const user = await User.findOne(condition)
if (!user) {
throw new NotFoundError("用户不存在")
}
const isPasswordValid = await bcrypt.compare(password, user.password)
if (!isPasswordValid) {
throw new UnauthorizedError("密码错误")
}
const token = jwt.sign({ userId: user.id }, process.env.SECRET, {
expiresIn: "30d",
})
success(res, { token }, "登录成功")
} catch (error) {
failure(res, error)
}
})
用户认证中间件
const jwt = require("jsonwebtoken")
const { User } = require("../models")
const { UnauthorizedError } = require("../utils/error")
const { success, failure } = require("../utils/responses")
module.exports = async (req, res, next) => {
try {
const { token } = req.headers
if (!token) {
throw new UnauthorizedError("当前接口需要认证才能访问。")
}
const decoded = jwt.verify(token, process.env.SECRET)
const { userId } = decoded
req.userId = userId
next()
} catch (error) {
failure(res, error)
}
}
4.用户相关的接口
用户首页,使用中间件
const express = require("express")
const router = express.Router()
const { User } = require("../models")
const { success, failure } = require("../utils/responses")
const { NotFoundError, BadRequestError } = require("../utils/error")
const bcrypt = require("bcryptjs")
router.get("/me", async (req, res) => {
try {
const user = await getUser(req)
success(res, { user }, "用户信息查询成功!")
} catch (error) {
failure(res, error)
}
})
async function getUser(req, showPassword = false) {
const id = req.userId
let condition = {}
if (!showPassword) {
condition = {
attributes: {
exclude: ["password"],
},
}
}
const user = await User.findByPk(id, condition)
if (!user) {
throw new NotFoundError("用户不存在")
}
return user
}
module.exports = router
const userAuth = require("./middlewares/user-auth")
const usersRouter = require("./routes/users")
app.use("/users", userAuth, usersRouter)
更新用户信息:性别\公司\昵称等
router.put("/info", async (req, res) => {
try {
const { nickname, sex, company, introduce, avatar } = req.body
const body = {
nickname,
sex,
company,
introduce,
avatar,
}
const user = await getUser(req)
await user.update(body)
success(res, { user }, "更新用户成功!")
} catch (error) {
failure(res, error)
}
})
更新账户信息:邮箱\用户名\邮箱
router.put("/account", async (req, res) => {
try {
const { email, username, password, currentPassword, passwordConfirmation } = req.body
const body = {
email,
username,
password,
currentPassword,
passwordConfirmation,
}
if (!currentPassword) {
throw new BadRequestError("请输入当前密码")
}
if (password !== passwordConfirmation) {
throw new BadRequestError("两次输入密码不一致")
}
const user = await getUser(req, true)
const isPasswordValid = bcrypt.compareSync(currentPassword, user.password)
if (!isPasswordValid) {
throw new BadRequestError("当前密码输入错误")
}
await user.update(body)
delete user.dataValues.password
success(res, { user }, "更新账户成功!")
} catch (error) {
failure(res, error)
}
})
5.点赞
点赞/取消点赞
const express = require("express")
const router = express.Router()
const { User, Course, Like } = require("../models")
const { success, failure } = require("../utils/responses")
const { NotFoundError, BadRequestError } = require("../utils/error")
const bcrypt = require("bcryptjs")
const { or } = require("sequelize")
router.post("/", async (req, res) => {
try {
const userId = req.userId
const { courseId } = req.body
const course = await Course.findByPk(courseId)
if (!course) {
throw new NotFoundError("课程不存在")
}
const like = await Like.findOne({
where: { userId, courseId },
})
if (!like) {
await Like.create({
userId,
courseId,
})
await course.increment("likesCount")
success(res, {}, "点赞成功")
} else {
await like.destroy()
await course.decrement("likesCount")
success(res, {}, "取消点赞成功")
}
} catch (error) {
failure(res, error)
}
})
module.exports = router
查询当前用户点赞的课程
class Course extends Model {
static associate(models) {
models.Course.belongsToMany(models.User, { through: models.Like, foreignKey: "courseId", as: "likeUsers" })
}
}
class User extends Model {
static associate(models) {
models.User.belongsToMany(models.Course, { through: models.Like, foreignKey: "userId", as: "likeCourses" })
}
}
router.get("/", async (req, res) => {
try {
const query = req.query
const currentPage = query.currentPage || 1
const pageSize = query.pageSize || 10
const offset = (currentPage - 1) * pageSize
const user = await User.findByPk(req.userId)
const courses = await user.getLikeCourses({
joinTableAttributes: [],
attributes: { exclude: ["CategoryId", "userId", "content"] },
offset,
limit: pageSize,
order: [["id", "DESC"]],
})
const count = await user.countLikeCourses()
success(res, { courses, pagination: { currentPage, pageSize, total: count } }, "查询成功")
} catch (error) {
failure(res, error)
}
})
get的妙用
const express = require("express")
const router = express.Router()
const { Course, Category, Chapter, User } = require("../models")
const { success, failure } = require("../utils/responses")
router.get("/:id", async (req, res) => {
try {
const { id } = req.params
const chapter = await Chapter.findByPk(id, {
attributes: { exclude: ["CourseId"] },
})
if (!chapter) {
throw new Error("chapter not found,章节未找到")
}
const course = await Chapter.getCource({
attributes: {
exclude: ["id", "name", "userId"],
},
})
const user = await Course.getUser({
attributes: {
exclude: ["id", "username", "nickname", "avatar", "company"],
},
})
const chapters = await Chapter.findAll({
attributes: {
exclude: ["CourseId", "content"],
},
where: {
courseId: chapter.courseId,
},
order: [
["rank", "DESC"],
["id", "DESC"],
],
})
success(
res,
{
chapter,
chapters,
course,
user,
},
"查询章节成功"
)
} catch (error) {
failure(res, error)
}
})
module.exports = router