Block 博客文章发布链路原理
<!-- block-content-capability: 1 -->
本文说明 Block 博客从管理员/Agent 登录后台到读者在前台看到文章的完整链路,便于理解实现、排查问题或自行复现。
1. 架构总览
Block 采用前后端分离:三个前端/后端应用共用一套 NestJS API 与 PostgreSQL 数据库。
生产环境经 Nginx 统一入口 http://8.210.111.112:/ 为前台,/admin/ 为后台,/api/v1/ 反代到 NestJS。
2. 第一步:登录后台
| 环节 | 说明 |
|---|---|
| 入口 | /admin/login(生产:http://8.210.111.112/admin/login) |
| API | POST /api/v1/auth/login,请求体 { email, password } |
| 成功响应 | data.accessToken(短期)+ Set-Cookie: refresh_token(HttpOnly,路径 /api/v1/auth) |
| 前端存储 | Access Token 写入 sessionStorage(键名 block_admin_access_token) |
| 后续请求 | Axios 拦截器自动附加 Authorization: Bearer <token>,并 withCredentials: true 携带 Cookie |
Access Token 过期时,Admin 会静默调用 POST /auth/refresh 换新 Token;Refresh 失效则跳转登录页。
要点:仅 Admin 账号可登录后台;前台没有读者登录路由。
3. 第二步:撰写与发布(Admin UI)
典型路径:文章管理 → 新建文章(路由 /admin/posts/new)。
| UI 区域 | 对应数据字段 |
|---|---|
| 标题 | title |
| Slug | slug(可留空,后端按标题生成) |
| 摘要 / 封面 / 分类 / 标签 | excerpt / cover / categoryId / tagIds |
| Vditor 正文 | content(Markdown 纯文本,存 PostgreSQL Text) |
| 「保存草稿」 | status: DRAFT |
| 「发布」 | status: PUBLISHED |
点击发布时,Admin 调用:
- 新建:
POST /api/v1/admin/posts - 编辑:
PATCH /api/v1/admin/posts/:id
均需 JwtAuthGuard(有效 Access Token)。正文插图可走 Vditor 上传或媒体库,最终仍写入 Markdown 的  形式。
4. 第三步:API 如何处理写入
PostService.create / update 核心逻辑(简化):
- 校验 slug 格式与唯一性;关联分类/标签存在性
- 若未传
excerpt,从 Markdown 正文自动生成摘要 - 当
status === PUBLISHED时写入publishedAt = now() prisma.post.create/update持久化到Post表- 若变为已发布,调用
seoCacheService.invalidate()刷新 sitemap/feed 缓存
Post 表主要字段
| 字段 | 含义 |
|---|---|
title / slug |
标题与 URL 标识(slug 全局唯一) |
content |
Markdown 正文 |
status |
DRAFT / PUBLISHED / ARCHIVED |
publishedAt |
发布时间(仅已发布有值) |
authorId |
作者(当前登录 Admin) |
草稿不会出现在公开 API 与前台列表中。
5. 第四步:读者如何看到文章
前台不直连数据库,只读公开 API:
| 场景 | API | 过滤条件 |
|---|---|---|
| 首页 / 列表 | GET /api/v1/posts?page=&pageSize= |
仅 status = PUBLISHED |
| 详情页 | GET /api/v1/posts/:slug |
同上;草稿或非存在 slug → 404 |
前台路由注意:详情是单数 /post/:slug,不是 /posts/:slug。
post-detail-view.vue 拉取详情后:
MarkdownRenderer将content转为 HTML(GFM 表格、Mermaid、代码高亮等)useHead设置 SEO metaCommentSection按 slug 挂载评论外挂(Waline/Giscus,可选)
6. 端到端时序(发布一篇新文)
7. Agent / curl 复现要点
与人工操作同一套 JWT,无单独 API Key。最小流程:
POST /auth/login→ 取accessTokenPOST /admin/posts或PATCH /admin/posts/:id,content为 Markdown 字符串GET /posts/{slug}验证前台可读(或使用浏览器打开/post/{slug})
详细 curl 与 Content Capability 语法见仓库 docs/dev/Agent写作指南.md。
8. 常见问题
| 现象 | 可能原因 |
|---|---|
| 后台已发布,前台 404 | slug 拼错;或访问了 /posts/slug 而非 /post/slug |
| 列表看不到新文 | status 仍为 DRAFT;或列表分页未翻到第一页 |
| API 401 | Access Token 过期且 Refresh 失败,需重新登录 |
| 改 slug 后评论丢失 | 评论外挂按 path/slug 绑定,已发布文章改 slug 需谨慎 |
本文由 Block 维护者通过 Admin 后台发布,内容与当前代码库 Phase 7 实现一致。