# 文章内容发布系统 — 设计文档 **日期:** 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"]` | | **visibility** | VARCHAR(20) DEFAULT 'public' | 浏览权限:`public` / `login` / `private` | | **visible_to** | TEXT | 私密指定人群,JSON数组格式(见下方说明) | | 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 | | **`visible_to` 格式说明:** `visibility=private` 时,`visible_to` 为 JSON 数组,每个元素是一个条件组(同一组内为 AND 关系,数组内不同组为 OR 关系): ```json [ { "type": "family", "familyId": 42 }, { "type": "vendor_type", "vendorType": "planner" }, { "type": "vendor_type", "vendorType": "activity_provider" }, { "type": "user", "userId": 10086 } ] ``` 支持的 `type`: | type | 说明 | 参数 | |:-----|:------|:------| | `family` | 指定家庭 | `familyId` | | `vendor_type` | 指定供应商类型 | `vendorType`:planner / activity_provider / product_supplier | | `user` | 指定单个用户 | `userId` | ### 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 }` — 无权限时返回403 | | `/api/articles/featured` | POST | 精选文章列表 | `{ size }` — 只返回当前用户可见的精选 | | `/api/articles/categories` | POST | 分类列表 | 无 — 返回启用的分类 | **权限过滤逻辑(后端统一处理):** ``` 当前请求用户: - 未登录 → 只能看到 visibility='public' 的文章 - 已登录(无家庭/非供应商) → 看到 visibility='public' + visibility='login' 的文章 - 已登录且有家庭 → 看到 public + login + private中visible_to含其familyId的 - 已登录且是某类供应商 → 看到 public + login + private中visible_to含其vendorType的 ``` `/api/articles/list` 和 `/api/articles/featured` 自动返回当前用户可见范围的文章。 `/api/articles/detail` 检测权限,无权时返回 `{ code: 403, message: "无权访问该文章" }`。 > **注意:** 未登录用户请求列表或详情时,`@RequestAttribute("userId")` 会为 null,需要在 Controller 中特殊处理(允许 userId=null 时只查 public)。 **响应结构示例:** ```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组:智/富/行/心/身) - 浏览权限(radio 三选一) - 公开(public)— 未登录可见 - 登录可见(login) - 私密(private)— 选此项时展开指定人群配置 - 家庭搜索+选择(按家庭ID/名称搜索) - 供应商类型勾选(规划师/活动方/供应商) - 单个用户搜索+选择 - 状态(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/(可选,非必须) | | ArticlePermissionService.java | service/(权限过滤逻辑抽离到独立Service) | ### 前端新增/修改 | 文件 | 操作 | 路径 | |:----|:----:|:-----| | 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 可管理文章;小程序端按`visibility` + `visible_to` 控制不同用户的可见范围(public / login / private) | | **家庭系统** | 私密文章可按 `familyId` 精确指定可见家庭 | | **供应商系统** | 私密文章可按 `vendor_type` 指定某类供应商可见 | --- ## 8. 待定事项 | 事项 | 说明 | 优先级 | |:-----|:------|:------| | 文章评论/点赞功能 | 本次不做,仅记录阅读量 | 低 | | 封面图存储方式 | 上传至服务器本地还是OSS?暂定服务器本地 `/uploads/articles/` | 中 | | 富文本编辑器选型 | vue-quill-editor 与 tinymce 二选一 | 中 | | 阅读记录与能量系统的联动 | 记录阅读时长后是否自动发放智维度能量?本次只记录不做联动 | 低 | | 文章SEO / 分享卡片 | 分享到微信时的标题/描述/封面定制 | 低 |