This repository has been archived on 2026-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MetaLab/docs/content-system.md
Victor_Jay 2528ebd28a docs: 计划开发内容系统,新增设计文档
- 内容模型 Post(Markdown + 渲染缓存)
- 分层架构对齐现有四层(model/repository/service/controller)
- 发帖审核流程(对接 AuditSubmission)
- SSR 页面 / API / 管理后台路由设计
- Markdown 安全策略(Goldmark + DOMPurify)
- MVP 范围 vs 后续迭代
2026-05-27 17:54:21 +08:00

7.1 KiB
Raw Blame History

内容系统设计文档

状态: 计划中 | 优先级: MVP


1. 内容模型

Post帖子/文章)

字段 类型 说明
id uint (PK) 自增主键
title varchar(200) 标题,非空
slug varchar(200), unique URL 友好标识,标题自动生成,去重追加数字
body text Markdown 原文
body_html text 渲染后 HTML写时缓存避免重复解析
user_id uint (FK → users) 作者
status varchar(20) draft / published / pending(审核中)/ hidden
allow_comment bool 是否允许评论MVP 预留字段)
deleted_at gorm.DeletedAt 软删除
created_at / updated_at timestamp

状态流转:

draft ──→ pending ──(审核通过)──→ published
                                    |
                              (管理隐藏)──→ hidden
                                    |
                              (作者删除)──→ deleted_at

2. 分层结构

对齐现有四层架构:

internal/
├── model/post.go              # Post + 状态常量
├── repository/post_repo.go    # DB CRUD
├── service/post_service.go    # 业务逻辑 (依赖 postRepository 接口)
├── controller/
│   ├── post_controller.go     # SSR 页面 + API
│   └── interfaces.go          # 新增 postUseCase 接口
├── router/                    # 注册路由

依赖方向: router → controller → service → repository → model
接口定义: service 层定义 repository 接口controller 层定义 service 接口ISP
控制器位置: 放在 controller 根包,与 auth/settings 并列


3. 接口定义

Repository 接口service/repository.go 定义)

type postRepository interface {
    Create(post *model.Post) error
    FindBySlug(slug string) (*model.Post, error)
    FindByID(id uint) (*model.Post, error)
    FindPageable(keyword string, status string, page, pageSize int) ([]model.Post, int64, error)
    Update(post *model.Post) error
    SoftDelete(id uint) error
}

Service 接口controller/interfaces.go 定义)

type postUseCase interface {
    Create(userID uint, title, body string) (*model.Post, error)
    GetBySlug(slug string) (*model.Post, error)
    List(keyword string, page, pageSize int) ([]model.Post, int64, error)
    Update(userID, role uint, title, body string) error
    Delete(userID uint, id uint) error
    AdminHide(id uint) error
    AdminPublish(id uint) error
}

4. Service 业务逻辑

发帖流程

用户提交 → 
  1. 鉴权(中间件 authMdw.Required
  2. 校验标题/正文非空
  3. 生成 unique slug标题 → URL 安全 → 查重追加数字后缀)
  4. body → body_htmlGoldmark 渲染)
  5. 检查审核开关:
     - IsRegistrationEnabled = false → status = published
     - IsAuditEnabled = true → status = pending创建 AuditSubmission
  6. Save → 返回

列表

  • 仅返回 status = published
  • keyword 标题模糊搜索
  • 分页默认 page_size=20
  • 排序: created_at DESC
  • 每条附带作者用户名

详情

  • 通过 slug 查找
  • 公开: 仅 published
  • 作者本人 + admin+: 可预览 draft / pending
  • 已渲染的 body_html 直接输出(带 XSS 防护)

编辑 / 删除

  • 权限: 作者本人 或 admin+
  • 编辑: 更新 title / body / body_html重新生成 slug若标题变更
  • 删除: 软删除

5. 路由设计

SSR 页面frontend

GET  /posts              列表页
GET  /posts/:slug        详情页
GET  /posts/new          编辑器(需登录)
GET  /posts/:slug/edit   编辑页(作者/admin

APIapi

POST   /api/posts              发帖
PUT    /api/posts/:slug        编辑
DELETE /api/posts/:slug        删除
GET    /api/posts              列表 JSON
GET    /api/posts/:slug        详情 JSON
GET    /api/posts/:slug/preview Markdown 预览

管理后台admin

GET   /admin/posts            所有帖子(含草稿/审核中/隐藏)
POST  /admin/posts/:slug/hide     隐藏
POST  /admin/posts/:slug/publish  强制发布
POST  /admin/posts/:slug/restore  恢复软删除

6. 模板设计

templates/MetaLab-2026/html/posts/
├── index.html            列表(卡片式: 标题+作者+时间+摘要)
├── show.html             详情Markdown 渲染 → 主题 CSS
├── new.html              编辑器EasyMDE + 实时预览)
└── edit.html             复用 new.html注入现有内容

templates/admin/html/posts/
└── index.html            管理列表(全量状态 + 操作按钮)
  • 列表摘要: body 前 200 字符纯文本剥离
  • 详情样式: 代码高亮、响应式图片、表格自适应
  • 编辑器: EasyMDE + marked.js + DOMPurify

7. Markdown 安全策略

层级 措施
服务端渲染 Goldmark (Go) + html.EscapeString
客户端预览 marked.js + DOMPurify
外部链接 rel="nofollow noopener noreferrer"
图片 限制域名白名单 + CSS max-width: 100%

8. 审核集成

复用现有 AuditSubmission 表,新增 type = "post":

用户角色 发帖后状态 如何可见
user审核开启 pending → AuditSubmission 审核通过 → published
moderator+ published 直接可见
user审核关闭 published 直接可见

9. 管理后台扩展

侧边栏新增 "内容管理" 入口admin+

  • 全状态列表: 标题 / 作者 / 状态 / 时间
  • 操作: 隐藏 / 强制发布 / 恢复
  • 状态标签: draft/ pending/ published绿/ hidden

10. MVP vs 后续

维度 MVP 后续
内容 帖子 CRUD 评论系统
编辑器 EasyMDE + 实时预览 图片拖拽上传
列表 卡片 + 分页 分类 / 标签 / 置顶
审核 复用 Audit 表 编辑也走审核
管理 列表 + 基本操作 批量操作 / 搜索
通知 审核通过 / 新评论通知

11. 预计新增/修改文件

新增(~12:

internal/model/post.go
internal/repository/post_repo.go
internal/service/post_service.go
internal/controller/post_controller.go
templates/MetaLab-2026/html/posts/index.html
templates/MetaLab-2026/html/posts/show.html
templates/MetaLab-2026/html/posts/new.html
templates/admin/html/posts/index.html
templates/MetaLab-2026/static/css/posts.css
templates/admin/static/css/posts.css
templates/MetaLab-2026/static/js/editor.js
templates/admin/static/js/posts.js

修改(~6:

internal/controller/interfaces.go    + postUseCase
internal/service/repository.go       + postRepository (接口)
internal/router/frontend.go          + post SSR 路由
internal/router/api.go               + post API 路由
internal/router/admin.go             + admin post 路由
templates/admin/html/layout/base.html + 侧边栏
cmd/server/main.go                   + AutoMigrate Post