|
|
@@ -0,0 +1,317 @@
|
|
|
+# 文章与活动发布系统设计文档
|
|
|
+
|
|
|
+**日期:** 2026-06-09
|
|
|
+**状态:** 设计稿 v1
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 概述
|
|
|
+
|
|
|
+在 浠艾福(CFC) 平台中新增文章和活动发布功能:
|
|
|
+- **文章**: 任何登录用户可发布,需运营审核后展示
|
|
|
+- **活动**: 仅活动管理员可发布,无需审核
|
|
|
+- **分类**: 独立分类体系 + 五维能量维度(body/mind/wisdom/action/wealth)关联
|
|
|
+- **展示**: 微信小程序嵌入各页面的内容模块
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 架构选择
|
|
|
+
|
|
|
+**方案 B**: 统一内容表 + 扩展表
|
|
|
+- `contents` 表存储文章和活动的公共字段
|
|
|
+- `activities_ext` 表存储活动的独有字段
|
|
|
+- 文章独有字段少,直接放在 contents 表中
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 数据模型
|
|
|
+
|
|
|
+### 3.1 contents 表 — 统一内容基表
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS contents (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ title VARCHAR(200) NOT NULL COMMENT '标题',
|
|
|
+ summary VARCHAR(500) COMMENT '摘要',
|
|
|
+ content TEXT COMMENT '富文本内容(HTML)',
|
|
|
+ cover_image VARCHAR(500) COMMENT '封面图URL',
|
|
|
+ type VARCHAR(20) NOT NULL COMMENT 'article/activity',
|
|
|
+ category_id BIGINT COMMENT '分类ID',
|
|
|
+ energy_dimension VARCHAR(20) COMMENT 'body/mind/wisdom/action/wealth',
|
|
|
+ author_id BIGINT NOT NULL COMMENT '发布者用户ID',
|
|
|
+ status VARCHAR(20) NOT NULL DEFAULT 'draft' COMMENT 'draft/pending/approved/rejected',
|
|
|
+ reject_reason VARCHAR(500) COMMENT '驳回原因',
|
|
|
+ view_count INT DEFAULT 0 COMMENT '浏览量',
|
|
|
+ publish_time DATETIME COMMENT '发布时间',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ INDEX idx_type_status (type, status),
|
|
|
+ INDEX idx_energy_dimension (energy_dimension),
|
|
|
+ INDEX idx_author_id (author_id)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一内容表';
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 activities_ext 表 — 活动扩展
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS activities_ext (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ content_id BIGINT NOT NULL UNIQUE COMMENT '关联contents.id',
|
|
|
+ location VARCHAR(300) COMMENT '活动地点',
|
|
|
+ start_time DATETIME COMMENT '开始时间',
|
|
|
+ end_time DATETIME COMMENT '结束时间',
|
|
|
+ max_participants INT COMMENT '最大参与人数',
|
|
|
+ sign_up_deadline DATETIME COMMENT '报名截止时间',
|
|
|
+ contact_phone VARCHAR(20) COMMENT '联系电话',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ INDEX idx_start_time (start_time),
|
|
|
+ FOREIGN KEY (content_id) REFERENCES contents(id) ON DELETE CASCADE
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活动扩展信息';
|
|
|
+```
|
|
|
+
|
|
|
+### 3.3 content_categories 表 — 内容分类
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS content_categories (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ name VARCHAR(50) NOT NULL COMMENT '分类名称',
|
|
|
+ energy_dimension VARCHAR(20) COMMENT '关联能量维度',
|
|
|
+ sort_order INT DEFAULT 0 COMMENT '排序',
|
|
|
+ type VARCHAR(20) NOT NULL COMMENT 'article/activity/both',
|
|
|
+ status VARCHAR(20) DEFAULT 'active' COMMENT 'active/inactive',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ INDEX idx_type (type),
|
|
|
+ INDEX idx_energy_dimension (energy_dimension)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='内容分类';
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 后端 API
|
|
|
+
|
|
|
+### 4.1 文章 API (`controller/article/ArticleController.java`)
|
|
|
+
|
|
|
+| 端点 | 方法 | 说明 | 权限 |
|
|
|
+|------|------|------|------|
|
|
|
+| `/api/articles/create` | POST | 创建文章(draft) | 登录用户 |
|
|
|
+| `/api/articles/submit` | POST | 提交审核(draft→pending) | 作者 |
|
|
|
+| `/api/articles/update` | POST | 更新文章 | 作者 |
|
|
|
+| `/api/articles/list` | POST | 已发布文章列表(分页) | 公开 |
|
|
|
+| `/api/articles/detail` | POST | 文章详情 | 公开 |
|
|
|
+| `/api/articles/my` | POST | 我的文章列表 | 登录用户 |
|
|
|
+
|
|
|
+### 4.2 文章审核 API (`controller/admin/ArticleAdminController.java`)
|
|
|
+
|
|
|
+| 端点 | 方法 | 说明 | 权限 |
|
|
|
+|------|------|------|------|
|
|
|
+| `/api/admin/articles/pending` | POST | 待审核列表 | admin |
|
|
|
+| `/api/admin/articles/approve` | POST | 审核通过 | admin |
|
|
|
+| `/api/admin/articles/reject` | POST | 审核驳回 | admin |
|
|
|
+
|
|
|
+### 4.3 活动 API (`controller/activity/ActivityController.java`)
|
|
|
+
|
|
|
+| 端点 | 方法 | 说明 | 权限 |
|
|
|
+|------|------|------|------|
|
|
|
+| `/api/activities/create` | POST | 创建活动 | admin |
|
|
|
+| `/api/activities/update` | POST | 更新活动 | admin |
|
|
|
+| `/api/activities/list` | POST | 活动列表(分页) | 公开 |
|
|
|
+| `/api/activities/detail` | POST | 活动详情 | 公开 |
|
|
|
+
|
|
|
+### 4.4 分类 API (`controller/content/ContentCategoryController.java`)
|
|
|
+
|
|
|
+| 端点 | 方法 | 说明 | 权限 |
|
|
|
+|------|------|------|------|
|
|
|
+| `/api/content-categories/list` | POST | 分类列表 | 公开 |
|
|
|
+| `/api/content-categories/create` | POST | 创建分类 | admin |
|
|
|
+| `/api/content-categories/update` | POST | 更新分类 | admin |
|
|
|
+| `/api/content-categories/delete` | POST | 删除分类 | admin |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 文件结构
|
|
|
+
|
|
|
+### 后端 (cfc-backend)
|
|
|
+```
|
|
|
+src/main/java/com/etotem/cfc/
|
|
|
+├── config/DatabaseInitializer.java # DDL迁移(追加)
|
|
|
+├── entity/
|
|
|
+│ ├── Content.java # 统一内容实体
|
|
|
+│ ├── ActivityExt.java # 活动扩展实体
|
|
|
+│ └── ContentCategory.java # 分类实体
|
|
|
+├── mapper/
|
|
|
+│ ├── ContentMapper.java
|
|
|
+│ ├── ActivityExtMapper.java
|
|
|
+│ └── ContentCategoryMapper.java
|
|
|
+├── service/
|
|
|
+│ ├── ArticleService.java # 文章业务+审核
|
|
|
+│ ├── ActivityService.java # 活动业务
|
|
|
+│ └── ContentCategoryService.java # 分类业务
|
|
|
+├── controller/
|
|
|
+│ ├── article/ArticleController.java
|
|
|
+│ ├── admin/ArticleAdminController.java
|
|
|
+│ ├── activity/ActivityController.java
|
|
|
+│ └── content/ContentCategoryController.java
|
|
|
+├── dto/
|
|
|
+│ ├── ArticleCreateDTO.java
|
|
|
+│ ├── ArticleUpdateDTO.java
|
|
|
+│ ├── ActivityCreateDTO.java
|
|
|
+│ ├── ActivityUpdateDTO.java
|
|
|
+│ └── ContentCategoryDTO.java
|
|
|
+```
|
|
|
+
|
|
|
+### 前端 (cfc-frontend)
|
|
|
+```
|
|
|
+pages/
|
|
|
+├── article/
|
|
|
+│ ├── index.vue # 文章列表
|
|
|
+│ └── detail.vue # 文章详情
|
|
|
+└── activity/
|
|
|
+ ├── index.vue # 活动列表
|
|
|
+ └── detail.vue # 活动详情
|
|
|
+
|
|
|
+components/
|
|
|
+├── article-card.vue # 文章卡片组件
|
|
|
+└── activity-card.vue # 活动卡片组件
|
|
|
+```
|
|
|
+
|
|
|
+### 测试
|
|
|
+```
|
|
|
+src/test/java/com/etotem/cfc/
|
|
|
+├── controller/
|
|
|
+│ ├── ArticleControllerTest.java
|
|
|
+│ ├── ArticleAdminControllerTest.java
|
|
|
+│ ├── ActivityControllerTest.java
|
|
|
+│ └── ContentCategoryControllerTest.java
|
|
|
+└── service/
|
|
|
+ ├── ArticleServiceTest.java
|
|
|
+ ├── ActivityServiceTest.java
|
|
|
+ └── ContentCategoryServiceTest.java
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 状态机
|
|
|
+
|
|
|
+### 文章状态流转
|
|
|
+```
|
|
|
+draft ──submit──→ pending ──approve──→ approved
|
|
|
+ │ │
|
|
|
+ ├──reject──→ rejected │
|
|
|
+ │ │
|
|
|
+ └──withdraw→ withdrawn │
|
|
|
+ │
|
|
|
+ rejected ──resubmit──→ pending
|
|
|
+ withdrawn ──resubmit──→ pending
|
|
|
+```
|
|
|
+
|
|
|
+### 活动状态
|
|
|
+活动由 admin 直接发布,无需审核:
|
|
|
+```
|
|
|
+draft ──publish──→ published ──close──→ closed
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 测试用例
|
|
|
+
|
|
|
+### ArticleControllerTest (~15 用例)
|
|
|
+- createArticle_Success — 创建文章(draft)
|
|
|
+- createArticle_NoTitle — 标题为空
|
|
|
+- createArticle_NoContent — 内容为空
|
|
|
+- submitArticle_Success — 提交审核
|
|
|
+- submitArticle_AlreadyApproved — 已审核文章不能提交
|
|
|
+- updateArticle_Success — 更新文章
|
|
|
+- updateArticle_NotAuthor — 非作者不能更新
|
|
|
+- getArticleList_Success — 已发布文章列表
|
|
|
+- getArticleList_ByCategory — 按分类筛选
|
|
|
+- getArticleList_ByEnergyDimension — 按能量维度筛选
|
|
|
+- getArticleDetail_Success — 文章详情
|
|
|
+- getArticleDetail_NotFound — 文章不存在
|
|
|
+- getMyArticles_Success — 我的文章列表
|
|
|
+- getMyArticles_Empty — 没有文章
|
|
|
+
|
|
|
+### ArticleAdminControllerTest (~10 用例)
|
|
|
+- getPendingList_Success — 待审核列表
|
|
|
+- approveArticle_Success — 审核通过
|
|
|
+- approveArticle_NotPending — 非待审状态不能通过
|
|
|
+- approveArticle_NotFound — 文章不存在
|
|
|
+- rejectArticle_Success — 审核驳回
|
|
|
+- rejectArticle_WithReason — 驳回带原因
|
|
|
+
|
|
|
+### ActivityControllerTest (~10 用例)
|
|
|
+- createActivity_Success — 创建活动
|
|
|
+- createActivity_MissingRequired — 缺少必填字段
|
|
|
+- updateActivity_Success — 更新活动
|
|
|
+- getActivityList_Success — 活动列表
|
|
|
+- getActivityList_ByEnergyDimension — 按能量维度筛选
|
|
|
+- getActivityDetail_Success — 活动详情
|
|
|
+
|
|
|
+### ContentCategoryControllerTest (~8 用例)
|
|
|
+- createCategory_Success — 创建分类
|
|
|
+- createCategory_Duplicate — 分类名重复
|
|
|
+- updateCategory_Success — 更新分类
|
|
|
+- deleteCategory_Success — 删除分类
|
|
|
+- getCategoryList_Success — 分类列表
|
|
|
+- getCategoryList_ByEnergyDimension — 按能量维度查分类
|
|
|
+
|
|
|
+### ArticleServiceTest (~10 用例)
|
|
|
+- submitReview_Success — 提交审核状态变化
|
|
|
+- approve_Success — 审核通过状态变化
|
|
|
+- reject_Success — 审核驳回状态变化
|
|
|
+- reject_WithReason — 驳回带原因
|
|
|
+- submit_FromWrongStatus — 错误状态不能提交
|
|
|
+- approve_FromWrongStatus — 非待审不能通过
|
|
|
+- getUserArticles_Success — 用户文章列表
|
|
|
+- searchByEnergyDimension — 按能量维度搜索
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 前端页面设计
|
|
|
+
|
|
|
+### 文章列表页 (pages/article/index.vue)
|
|
|
+- 顶部筛选:分类滚动条 + 能量维度标签
|
|
|
+- 文章卡片列表:封面图、标题、摘要、作者、发布时间
|
|
|
+- 点击进入详情
|
|
|
+
|
|
|
+### 文章详情页 (pages/article/detail.vue)
|
|
|
+- 富文本渲染(rich-text 组件)
|
|
|
+- 作者信息、发布时间、浏览量
|
|
|
+- 能量维度标签展示
|
|
|
+
|
|
|
+### 活动列表页 (pages/activity/index.vue)
|
|
|
+- 时间筛选(进行中/即将开始/已结束)
|
|
|
+- 活动卡片:封面、标题、时间、地点
|
|
|
+
|
|
|
+### 活动详情页 (pages/activity/detail.vue)
|
|
|
+- 基本信息 + 富文本内容
|
|
|
+- 报名信息、地点、时间
|
|
|
+
|
|
|
+### 嵌入组件 (components/article-card.vue / activity-card.vue)
|
|
|
+- 横滑推荐卡片
|
|
|
+- 用于首页、发现页等嵌入
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 与现有系统的集成
|
|
|
+
|
|
|
+- **认证复用**: 使用现有 JWT 认证,`@RequestAttribute("userId")` 获取用户
|
|
|
+- **角色权限**: admin 角色可访问审核/活动管理 API
|
|
|
+- **数据库**: 通过 DatabaseInitializer 执行 DDL 迁移
|
|
|
+- **MediaController**: 图片上传复用现有文件上传接口
|
|
|
+- **统一响应**: 使用 `Result<T>` 包装
|
|
|
+- **统一 @PostMapping**: 遵循项目规范
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 10. 验收标准
|
|
|
+
|
|
|
+- [x] articles 表可正常创建和迁移
|
|
|
+- [x] activities_ext 表可正常创建和迁移
|
|
|
+- [x] content_categories 表可正常创建和迁移,含 5 条能量维度默认分类
|
|
|
+- [x] 文章 CRUD API 正常工作
|
|
|
+- [x] 文章提交-审核-通过/驳回 状态流转正常
|
|
|
+- [x] 活动 CRUD API 正常工作
|
|
|
+- [x] 分类 CRUD API 正常工作
|
|
|
+- [x] 所有 Controller 测试通过
|
|
|
+- [x] 所有 Service 测试通过
|
|
|
+- [x] 小程序页面展示正常
|