Ver Fonte

docs: 新增文章内容发布系统设计文档

User há 4 meses atrás
pai
commit
5a260716f9

+ 292 - 0
docs/superpowers/specs/2026-06-08-article-publishing-system-design.md

@@ -0,0 +1,292 @@
+# 文章内容发布系统 — 设计文档
+
+**日期:** 2026-06-08
+**状态:** 待确认
+**版本:** v1.0
+
+---
+
+## 1. 概述
+
+在浠艾福小程序内建立文章内容发布能力,让平台运营(admin)通过 Web 管理端创建/编辑/发布文章,小程序用户在「发现」和「心智成长」等页面浏览和阅读文章。
+
+### 核心目标
+
+- 将现有硬编码文章替换为后端动态数据
+- 运营人员可自主发布和管理内容,无需开发介入
+- 文章可关联五维维度,为能量系统提供内容来源
+- 记录用户阅读行为,为「智」维度能量计算提供数据
+
+---
+
+## 2. 架构
+
+```
+Web管理端 (cfc-web)                   后端 (cfc-backend)                    小程序 (cfc-frontend)
+┌────────────────────┐   CRUD API    ┌────────────────────┐  查询 API     ┌────────────────────┐
+│ 文章管理 (admin)    │ ────────────→ │ ArticleService     │ ───────────→ │ 发现页 (精选推荐)   │
+│ ┌ 文章列表/搜索     │               │ ├─ entity          │              │ 心智成长 (文章列表)  │
+│ ├ 创建/编辑(富文本)  │               │ ├─ controller      │              │ 文章详情页          │
+│ ├ 分类管理          │               │ ├─ service         │              └────────────────────┘
+│ ├ 封面图上传        │               │ └─ mapper          │
+│ └ 发布/下架/精选    │               └────────────────────┘
+└────────────────────┘
+```
+
+### 涉及改动范围
+
+| 模块 | 改动类型 | 说明 |
+|:----|:--------:|------|
+| cfc-backend | 新增 | Article entity/controller/service/mapper + ArticleCategory CRUD |
+| cfc-backend | 修改 | `ArticleReadingRecordService` 新增记录写入 |
+| cfc-backend | 新增 | 文件上传接口(封面图) |
+| cfc-web | 新增 | 文章管理3个页面(列表/编辑/分类) |
+| cfc-frontend | 修改 | `mind/articles.vue` 改为API数据源 |
+| cfc-frontend | 修改 | `mind/index.vue` 推荐阅读改为API |
+| cfc-frontend | 修改 | `discover/index.vue` 精选文章改为API |
+| cfc-frontend | 新增 | `mind/article-detail.vue` 详情页 |
+
+---
+
+## 3. 数据模型
+
+### 3.1 article_categories — 文章分类
+
+| 列名 | 类型 | 说明 |
+|------|------|------|
+| id | BIGINT AUTO_INCREMENT PK | |
+| name | VARCHAR(50) | 分类名:育儿、心理、健康、活动等 |
+| icon | VARCHAR(20) | 图标emoji |
+| color | VARCHAR(20) | 标识色(十六进制) |
+| sort_order | INT DEFAULT 0 | 排序 |
+| status | TINYINT DEFAULT 1 | 1启用/0禁用 |
+
+### 3.2 articles — 文章
+
+| 列名 | 类型 | 说明 |
+|------|------|------|
+| id | BIGINT AUTO_INCREMENT PK | |
+| category_id | BIGINT | 所属分类(FK→article_categories.id) |
+| title | VARCHAR(200) | 标题 |
+| summary | VARCHAR(500) | 摘要/简介 |
+| cover_image | VARCHAR(500) | 封面图URL |
+| content | LONGTEXT | 富文本HTML内容 |
+| tags | VARCHAR(200) | 标签,JSON数组格式 `["育儿","亲子"]` |
+| author | VARCHAR(100) | 作者名 |
+| read_time | INT DEFAULT 0 | 预计阅读分钟数 |
+| related_dimensions | VARCHAR(100) | 关联五维,JSON数组格式 `["mind","wisdom"]` |
+| status | VARCHAR(20) DEFAULT 'draft' | draft / published / archived |
+| is_featured | TINYINT DEFAULT 0 | 1=精选(在发现页展示)/ 0=普通 |
+| published_at | DATETIME | 发布时间 |
+| view_count | INT DEFAULT 0 | 浏览次数 |
+| created_by | BIGINT | 发布人(admin用户ID) |
+| created_at | DATETIME | |
+| updated_at | DATETIME | |
+
+### 3.3 article_reading_records(已有表,仅增加关联)
+
+现有 `article_reading_records` 表结构不变,在写入时增加 `content` 字段填入文章ID,用于后续统计每个文章的阅读时长。
+
+---
+
+## 4. API 设计
+
+### 4.1 公开接口(小程序端)
+
+| 端点 | 方法 | 说明 | 参数 |
+|------|------|------|------|
+| `/api/articles/list` | POST | 文章分页列表 | `{ categoryId, keyword, page, size }` — 只返回published |
+| `/api/articles/detail` | POST | 文章详情(含内容) | `{ id }` — 返回文章全部字段 |
+| `/api/articles/featured` | POST | 精选文章列表 | `{ size }` — 发现页用 |
+| `/api/articles/categories` | POST | 分类列表 | 无 — 返回启用的分类 |
+
+**响应结构示例:**
+
+```json
+POST /api/articles/list
+{ "categoryId": 1, "page": 1, "size": 10 }
+
+→ {
+  "code": 200,
+  "data": {
+    "records": [
+      {
+        "id": 1,
+        "categoryId": 1,
+        "categoryName": "育儿",
+        "title": "把握孩子的敏感期",
+        "summary": "了解0-6岁儿童发展的关键敏感期",
+        "coverImage": "https://...",
+        "author": "浠艾福",
+        "readTime": 3,
+        "relatedDimensions": ["mind", "wisdom"],
+        "publishedAt": "2026-06-01 10:00:00",
+        "viewCount": 1280
+      }
+    ],
+    "total": 45,
+    "page": 1,
+    "size": 10
+  }
+}
+```
+
+### 4.2 管理端接口(Web管理端)
+
+| 端点 | 方法 | 说明 | 参数 |
+|------|------|------|------|
+| `/api/admin/articles/list` | POST | 后台文章列表 | `{ status, categoryId, keyword, page, size }` — 包含draft |
+| `/api/admin/articles/create` | POST | 创建文章 | 文章所有字段 |
+| `/api/admin/articles/update` | POST | 更新文章 | `{ id, ...fields }` |
+| `/api/admin/articles/delete` | POST | 删除文章 | `{ id }` |
+| `/api/admin/articles/publish` | POST | 发布/下架 | `{ id, status }` |
+| `/api/admin/articles/toggle-featured` | POST | 切换精选 | `{ id, isFeatured }` |
+| `/api/admin/categories/list` | POST | 分类列表 | 无 |
+| `/api/admin/categories/create` | POST | 创建分类 | `{ name, icon, color, sortOrder }` |
+| `/api/admin/categories/update` | POST | 更新分类 | `{ id, ... }` |
+| `/api/admin/categories/delete` | POST | 删除分类 | `{ id }` |
+| `/api/admin/upload/image` | POST | 上传封面图 | multipart file → 返回URL |
+
+### 4.3 阅读记录接口
+
+| 端点 | 方法 | 说明 | 参数 |
+|------|------|------|------|
+| `/api/articles/record-read` | POST | 记录阅读行为 | `{ articleId, durationSeconds, childId? }` |
+
+---
+
+## 5. 前端改动详情
+
+### 5.1 小程序端
+
+#### 发现页 `discover/index.vue`
+
+- 将 `article-section` 的硬编码3篇文章改为请求 `/api/articles/featured`
+- 点击文章卡片跳转至 `mind/article-detail?id=xxx`
+- 未登录时点击仍跳转登录页
+
+#### 心智成长首页 `mind/index.vue`
+
+- 「推荐阅读」区块改为请求 `/api/articles/featured?size=5`
+- 保持现有UI布局
+
+#### 文章列表页 `mind/articles.vue`
+
+- `data()` 中的 `articles` 初始化为空数组
+- `onShow`/`onLoad` 时请求 `/api/articles/list`
+- 分类筛选改为请求 `/api/articles/list?categoryId=xxx`
+- 保留现有UI(封面+标题+摘要+分类标签+颜色)
+
+#### 新增:文章详情页 `mind/article-detail.vue`
+
+```
+┌────────────────┐
+│   ← 返回       │
+├────────────────┤
+│  ┌──────────┐  │
+│  │  封面图   │  │
+│  └──────────┘  │
+│  标题         │
+│  作者 · 日期  │
+│  分类标签      │
+│  关联五维标签  │
+├────────────────┤
+│                │
+│  富文本内容    │
+│  (图文混排)    │
+│                │
+├────────────────┤
+│  底部:点赞/收藏 │
+└────────────────┘
+```
+
+- 页面路径:`/pages/mind/article-detail?id=xxx`
+- `onLoad` 时调 `/api/articles/detail` 获取内容
+- 富文本使用小程序 `rich-text` 组件渲染
+- 页面底部展示阅读时间,离开时调 `record-read` 写入阅读记录
+
+### 5.2 Web管理端
+
+#### 文章管理列表 `admin/ArticleManage.vue`
+
+- 表格列:标题、分类、作者、状态、精选、发布时间、操作
+- 顶部筛选:状态(draft/published/archived)、分类下拉、关键词搜索
+- 操作列:编辑、发布/下架、设为精选、删除
+- 分页
+
+#### 文章编辑器 `admin/ArticleEdit.vue`
+
+- 标题(input)
+- 分类(下拉选择)
+- 摘要(textarea)
+- 封面图(图片上传组件)
+- 富文本编辑器(使用 `vue-quill-editor` 或 `tinymce`)
+- 标签(tag输入组件)
+- 作者(input)
+- 预计阅读时间(number input)
+- 关联五维(checkbox组:智/富/行/心/身)
+- 状态(draft/published 切换)
+- 精选开关
+- 保存/发布按钮
+
+#### 分类管理 `admin/ArticleCategory.vue`
+
+- 简易列表 + 新增/编辑/删除
+- 每次操作后刷新列表
+
+---
+
+## 6. 文件清单
+
+### 后端新增
+
+| 文件 | 路径 |
+|:----|:-----|
+| ArticleCategory.java | entity/ |
+| Article.java | entity/ |
+| ArticleCategoryMapper.java | mapper/ |
+| ArticleMapper.java | mapper/ |
+| ArticleCategoryService.java | service/ |
+| ArticleService.java | service/ |
+| ArticleController.java | controller/content/ |
+| ArticleCategoryController.java | controller/content/ |
+| AdminArticleController.java | controller/admin/ |
+| ArticleDTO.java | dto/(可选,非必须) |
+
+### 前端新增/修改
+
+| 文件 | 操作 | 路径 |
+|:----|:----:|:-----|
+| ArticleManage.vue | 新增 | cfc-web/src/views/admin/ |
+| ArticleEdit.vue | 新增 | cfc-web/src/views/admin/ |
+| ArticleCategory.vue | 新增 | cfc-web/src/views/admin/ |
+| router/index.js | 修改 | cfc-web/src/ |
+| api.js | 修改 | cfc-web/src/ |
+| mind/article-detail.vue | 新增 | cfc-frontend/pages/ |
+| mind/articles.vue | 修改 | cfc-frontend/pages/ |
+| mind/index.vue | 修改 | cfc-frontend/pages/ |
+| discover/index.vue | 修改 | cfc-frontend/pages/ |
+| api.js | 修改 | cfc-frontend/utils/ |
+
+---
+
+## 7. 与现有系统的关系
+
+| 现有模块 | 关系 |
+|:---------|:-----|
+| **ContentSection** 区块系统 | 无依赖,独立运行 |
+| **ArticleReadingRecord** 阅读记录 | 详情页调用记录接口写入数据;阅读数据可被 EnergyService 引用用于智维度计算 |
+| **五维能量系统** | articles 表的 `related_dimensions` 字段为能量系统预留关联入口 |
+| **用户角色** | 仅 admin 可管理文章;小程序端所有用户(含未登录)可阅读 |
+
+---
+
+## 8. 待定事项
+
+| 事项 | 说明 | 优先级 |
+|:-----|:------|:------|
+| 文章评论/点赞功能 | 本次不做,仅记录阅读量 | 低 |
+| 封面图存储方式 | 上传至服务器本地还是OSS?暂定服务器本地 `/uploads/articles/` | 中 |
+| 富文本编辑器选型 | vue-quill-editor 与 tinymce 二选一 | 中 |
+| 阅读记录与能量系统的联动 | 记录阅读时长后是否自动发放智维度能量?本次只记录不做联动 | 低 |
+| 文章SEO / 分享卡片 | 分享到微信时的标题/描述/封面定制 | 低 |