You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
3.7 KiB

import { ArticleModel } from "../../db/models/ArticleModel.js"
import Router from "utils/router.js"
import { marked } from "marked"
class ArticleController {
async index(ctx) {
const { page = 1, view = 'grid' } = ctx.query
const limit = 12 // 每页显示的文章数量
const offset = (page - 1) * limit
// 获取文章总数
const total = await ArticleModel.getPublishedArticleCount()
const totalPages = Math.ceil(total / limit)
// 获取分页文章
const articles = await ArticleModel.findPublished(offset, limit)
// 获取所有分类和标签
const categories = await ArticleModel.getArticleCountByCategory()
const allArticles = await ArticleModel.findPublished()
const tags = new Set()
allArticles.forEach(article => {
if (article.tags) {
article.tags.split(',').forEach(tag => {
tags.add(tag.trim())
})
}
})
return ctx.render("page/articles/index", {
articles,
categories: categories.map(c => c.category),
tags: Array.from(tags),
currentPage: parseInt(page),
totalPages,
view,
title: "文章列表",
}, {
includeUser: true,
includeSite: true,
})
}
async show(ctx) {
const { slug } = ctx.params
console.log(slug);
const article = await ArticleModel.findBySlug(slug)
if (!article) {
ctx.throw(404, "文章不存在")
}
// 增加阅读次数
await ArticleModel.incrementViewCount(article.id)
// 将文章内容解析为HTML
article.content = marked(article.content || '')
// 获取相关文章
const relatedArticles = await ArticleModel.getRelatedArticles(article.id)
return ctx.render("page/articles/article", {
article,
relatedArticles,
title: article.title,
}, {
includeUser: true,
})
}
async byCategory(ctx) {
const { category } = ctx.params
const articles = await ArticleModel.findByCategory(category)
return ctx.render("page/articles/category", {
articles,
category,
title: `${category} - 分类文章`,
}, {
includeUser: true,
})
}
async byTag(ctx) {
const { tag } = ctx.params
const articles = await ArticleModel.findByTags(tag)
return ctx.render("page/articles/tag", {
articles,
tag,
title: `${tag} - 标签文章`,
}, {
includeUser: true,
})
}
async search(ctx) {
const { q } = ctx.query
if(!q) {
return ctx.set('hx-redirect', '/articles')
}
const articles = await ArticleModel.searchByKeyword(q)
return ctx.render("page/articles/search", {
articles,
keyword: q,
title: `搜索:${q}`,
}, {
includeUser: true,
})
}
static createRoutes() {
const controller = new ArticleController()
const router = new Router({ auth: true, prefix: "/articles" })
router.get("", controller.index, { auth: false }) // 允许未登录访问
router.get("/", controller.index, { auth: false }) // 允许未登录访问
router.get("/search", controller.search, { auth: false })
router.get("/category/:category", controller.byCategory)
router.get("/tag/:tag", controller.byTag)
router.get("/:slug", controller.show)
return router
}
}
export default ArticleController
export { ArticleController }