2026-06-08-article-publishing-system-design.md 13 KB

文章内容发布系统 — 设计文档

日期: 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 关系):

[
  { "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)。

响应结构示例:

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-editortinymce
  • 标签(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 / 分享卡片 分享到微信时的标题/描述/封面定制