Files
mce/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

252 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 内容系统设计文档
> **状态**: 计划中 | **优先级**: 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 定义)
```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 定义)
```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
```