📖 文章摘要
完整后台管理系统详解:JWT 认证中间件、分栏实时 Markdown 编辑器、评论审核流程、站点 key-value 配置和图片上传。
后台管理系统
博客后台提供完整的文章/分类/标签/评论/站点配置管理功能,所有接口需 JWT 认证。
认证体系
使用 JWT 实现无状态认证。首次部署通过 /api/auth/init 创建管理员,后续通过 /api/auth/login 登录。
前端认证拦截
Nuxt 中间件 middleware/auth.ts 自动保护后台路由:
export default defineNuxtRouteMiddleware((to) => {
const token = useCookie('auth_token').value
if (!token) return navigateTo('/admin/login')
})
所有 /admin/* 页面自动检查 token 有效性,无效则跳转登录。
文章编辑器
分栏实时预览编辑器是后台的核心功能:
<template>
<div class="grid grid-cols-2 gap-4">
<!-- 左栏:Markdown 编辑器 -->
<textarea v-model="form.content_md" @input="updatePreview" />
<!-- 右栏:实时预览 -->
<div class="prose" v-html="preview" />
</div>
</template>
主要功能特点:
- 分栏布局 — 左栏编辑 Markdown 源码,右栏实时渲染预览
- 同步滚动 — 编辑时自动渲染,无需手动刷新
- 草稿机制 — 支持将文章存为草稿,发布时才写入
published_at - 标签选择 — 复选框选择已存在的标签,支持多选
- 分类选择 — 下拉列表选择所属分类
创建文章 API
@router.post("", response_model=ArticleResponse)
def create_article(data: ArticleCreate, ...):
article = Article(
title=data.title, slug=data.slug,
content_md=data.content_md,
content_html=_render_markdown(data.content_md), # 写入时渲染
published_at=datetime.utcnow() if data.is_published else None,
)
db.add(article)
if data.tag_ids:
tags = db.query(Tag).filter(Tag.id.in_(data.tag_ids)).all()
article.tags = tags
db.commit()
return article
评论审核
评论提交后默认 is_approved = False,不会对外显示。管理员在后台审核通过后才公开:
@router.post("/{comment_id}/approve")
def approve_comment(comment_id: int, ...):
comment = db.query(Comment).filter(Comment.id == comment_id).first()
comment.is_approved = True
db.commit()
文章管理列表
后台文章列表与前台不同——显示所有状态的文章(已发布 + 草稿 + 已下架),按更新时间倒序:
@router.get("")
def list_all_articles(page, size, q=None, ...):
query = db.query(Article).order_by(desc(Article.updated_at))
if q:
query = query.filter(Article.title.ilike(f"%{q}%"))
# ...
搜索和筛选
- 标题模糊搜索(防抖 300ms 输入)
- 按状态快捷筛选(全部/已发布/草稿/置顶)
- 批量发布/下架(
Promise.all并发)
站点设置
key-value 配置表通过管理界面编辑,无需修改代码:
@router.put("/admin/site")
def update_settings(data: dict, ...):
for key, value in data.items():
setting = db.query(SiteSetting).filter(SiteSetting.key == key).first()
if setting:
setting.value = value
else:
db.add(SiteSetting(key=key, value=value))
db.commit()
可配置项:站点名称、作者姓名、头像(base64 上传)、技能标签、社交链接、背景图片地址。
图片上传
上传接口支持 jpg/png/gif/webp 格式,自动压缩优化:
POST /api/admin/upload → 返回图片 URL
图片存储在 /data/uploads/ 目录,通过 Nginx 直出,缓存策略 3 天。
最后更新:2026年6月29日CC BY-NC-SA 4.0
评论
暂无评论,来写第一条吧
