后端: - 文章审核状态机:draft → pending_review → published(含 reject/unpublish) - 文章分类 CRUD(article_category entity + service + handler) - 文章标签 CRUD(article_tag + article_article_tag 关联) - 文章修订版快照(article_revision) - 阅读计数、排序、slug、审核备注 - 新增 health.articles.review 权限 前端: - ArticleManageList:状态标签页 + 分类筛选 + 关键字搜索 + 审核操作 - ArticleEditor:Wangeditor 富文本编辑器 + 元数据侧栏 - ArticleCategoryManage:分类 CRUD + 父子层级 - ArticleTagManage:标签 CRUD 修复: - diagnosis_service/health_data_service/dialysis_service: 补充 key_version 字段 - ArticleCategoryManage: 补充 Select 组件导入
11 KiB
11 KiB
HMS 内容管理模块设计规格
日期: 2026-04-26 | 状态: Draft | 依赖: erp-health (现有 article 基础)
1. 概述
1.1 目标
将现有 article 基础 CRUD 扩展为综合内容管理平台,支持:
- 健康科普、医院公告、活动通知、科室介绍等多种内容类型
- 富文本可视化编辑(Wangeditor)
- 作者 → 审核员 → 发布的审核工作流
- 受控分类 + 多对多标签
- 图片上传
- 阅读统计
1.2 方案选择
在 erp-health 内扩展 + 预留拆分接口。
理由:内容管理与健康管理强关联(科普、体检解读),现有后端 CRUD 完整只需增强。所有 article 相关代码放在 crates/erp-health/src/content/ 子目录,通过事件总线与 health 核心通信,未来可拆分为独立 crate。
1.3 角色定义
| 角色 | 职责 | 权限 |
|---|---|---|
| 内容作者 | 创建/编辑/提交文章 | health.articles.manage |
| 审核员 | 审核/批准/拒绝文章 | health.articles.review |
| 患者读者 | 小程序阅读已发布内容 | 无需权限(公开端点) |
2. 数据模型
2.1 articles 表改造
新增字段(在现有表基础上 ALTER):
| 字段 | 类型 | 说明 |
|---|---|---|
status |
String(20) | draft / pending_review / approved / rejected / published,默认 draft |
slug |
String(可选) | URL 友好标识 |
content_type |
String(20) | rich_text(默认) / markdown,预留扩展 |
reviewed_by |
UUID(可选) | 审核人 ID |
reviewed_at |
DateTime(可选) | 审核时间 |
review_note |
Text(可选) | 审核备注/拒绝原因 |
view_count |
i32 | 阅读次数,默认 0 |
sort_order |
i32 | 置顶/排序权重,默认 0 |
发布语义变更: 原来通过 published_at IS NOT NULL 判断发布状态,改为通过 status = 'published' 控制。published_at 保留作为实际发布时间。
现有字段保留: id, tenant_id, title, summary, content, cover_image, category(过渡期保留,迁移完成后废弃), author, published_at, 标准字段。
2.2 新增 article_category 表
CREATE TABLE article_category (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100),
parent_id UUID REFERENCES article_category(id),
description TEXT,
sort_order INT DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID,
updated_by UUID,
deleted_at TIMESTAMPTZ,
version INT NOT NULL DEFAULT 1
);
2.3 新增 article_tag 表
CREATE TABLE article_tag (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
name VARCHAR(50) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID,
updated_by UUID,
deleted_at TIMESTAMPTZ,
version INT NOT NULL DEFAULT 1
);
2.4 新增 article_article_tag 关联表
CREATE TABLE article_article_tag (
article_id UUID NOT NULL REFERENCES articles(id),
tag_id UUID NOT NULL REFERENCES article_tag(id),
PRIMARY KEY (article_id, tag_id)
);
2.5 新增 article_revision 表(预留版本历史)
CREATE TABLE article_revision (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
article_id UUID NOT NULL REFERENCES articles(id),
revision_number INT NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
summary TEXT,
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
3. 审核工作流
3.1 状态机
draft ──submit()──→ pending_review ──approve()──→ published
↑ │
│ reject()
│ ↓
└─────rejected ←──────┘
(修改后重新 submit → pending_review)
published ──unpublish()──→ draft
| 状态 | 可见性 | 允许操作 |
|---|---|---|
draft |
仅作者 | 编辑、提交审核、删除 |
pending_review |
作者 + 审核员 | 审核员:通过/拒绝;作者:撤回 |
approved |
过渡态,自动发布 | — |
rejected |
作者 | 编辑后重新提交 |
published |
所有人(含小程序) | 撤回、删除 |
3.2 事件
| 事件 | 触发时机 | 消费者 |
|---|---|---|
article.submitted |
draft → pending_review | 通知审核员 |
article.approved |
审核通过 | 记录日志 |
article.rejected |
审核拒绝 | 通知作者 |
article.published |
正式发布 | 记录日志 |
4. API 设计
4.1 文章 CRUD(增强已有)
| Method | Path | 说明 | 权限 |
|---|---|---|---|
| GET | /api/v1/health/articles |
文章列表(管理端,支持 status/category/tag 筛选) | health.articles.list |
| GET | /api/v1/health/articles/{id} |
文章详情 | health.articles.list |
| POST | /api/v1/health/articles |
创建文章(默认 draft) | health.articles.manage |
| PUT | /api/v1/health/articles/{id} |
更新文章 | health.articles.manage |
| DELETE | /api/v1/health/articles/{id} |
软删除 | health.articles.manage |
列表查询参数:page, page_size, status, category_id, tag_id, keyword(标题搜索)
4.2 审核流程
| Method | Path | 说明 | 权限 |
|---|---|---|---|
| POST | /api/v1/health/articles/{id}/submit |
提交审核 | health.articles.manage |
| POST | /api/v1/health/articles/{id}/approve |
审核通过并发布 | health.articles.review |
| POST | /api/v1/health/articles/{id}/reject |
审核拒绝(body: { "note": "..." }) |
health.articles.review |
| POST | /api/v1/health/articles/{id}/unpublish |
撤回发布 | health.articles.manage |
4.3 分类管理
| Method | Path | 说明 | 权限 |
|---|---|---|---|
| GET | /api/v1/health/article-categories |
分类列表(树形) | health.articles.list |
| POST | /api/v1/health/article-categories |
创建分类 | health.articles.manage |
| PUT | /api/v1/health/article-categories/{id} |
更新分类 | health.articles.manage |
| DELETE | /api/v1/health/article-categories/{id} |
删除分类 | health.articles.manage |
4.4 标签管理
| Method | Path | 说明 | 权限 |
|---|---|---|---|
| GET | /api/v1/health/article-tags |
标签列表 | health.articles.list |
| POST | /api/v1/health/article-tags |
创建标签 | health.articles.manage |
| DELETE | /api/v1/health/article-tags/{id} |
删除标签 | health.articles.manage |
4.5 图片上传
| Method | Path | 说明 | 权限 |
|---|---|---|---|
| POST | /api/v1/health/articles/upload-image |
上传图片,返回 { url } |
health.articles.manage |
图片存储:本地文件系统 uploads/articles/{tenant_id}/{yyyy-MM}/{uuid}.{ext},后续可迁移至 OSS。
4.6 权限变更
新增权限码:
| 权限码 | 名称 | 说明 |
|---|---|---|
health.articles.review |
审核资讯 | 新增 |
保留已有:
| 权限码 | 名称 |
|---|---|
health.articles.list |
查看资讯 |
health.articles.manage |
管理资讯 |
5. Web 前端
5.1 新增页面
| 页面 | 路由 | 组件 |
|---|---|---|
| 文章列表 | /health/articles |
ArticleManageList |
| 创建文章 | /health/articles/new |
ArticleEditor |
| 编辑文章 | /health/articles/:id/edit |
ArticleEditor |
| 文章详情/预览 | /health/articles/:id |
ArticlePreview |
| 分类管理 | /health/article-categories |
ArticleCategoryManage |
| 标签管理 | /health/article-tags |
ArticleTagManage |
5.2 文章列表页
- 状态 Tab 筛选:全部 | 草稿 | 待审核 | 已发布 | 已拒绝
- 分类下拉筛选
- 标题关键词搜索
- 表格列:标题、分类、标签、状态(色块)、作者、阅读数、发布时间、操作
- 操作按钮根据状态和权限动态显示:
- 草稿:编辑、删除、提交审核
- 待审核:查看(审核员可看到审核/拒绝)
- 已发布:查看、撤回
- 已拒绝:编辑、重新提交
5.3 富文本编辑器
选型:Wangeditor v5
- MIT 协议,轻量(~200KB)
- 中文优先,React 集成简单(
@wangeditor/editor-for-react) - 支持图片上传 hook(对接后端 upload-image API)
- 支持标题/列表/链接/表格等常用格式
编辑器页面布局:
- 左侧:富文本编辑区域
- 右侧:标题、分类选择、标签选择、摘要、封面图上传、slug
- 底部:保存草稿 / 提交审核 按钮
5.4 侧边栏菜单
在健康管理分组下新增「内容管理」菜单项,图标使用 FileTextOutlined。
6. 小程序端增强
6.1 文章列表页改造
- 增加顶部分类 Tab(从 article-category API 获取)
- 下拉刷新 + 无限滚动
- 搜索框(标题关键词)
6.2 文章详情页改造
- 增加
view_count展示 - 进入详情页时调用阅读计数 API(POST 或 PUT 递增)
6.3 新增 API 调用
GET /api/v1/health/articles— 增加category_id、keyword参数POST /api/v1/health/articles/{id}/view— 阅读计数
7. 实施步骤
Phase 1:后端增强(3-4 天)
- 数据库迁移:articles 表 ALTER + article_category/article_tag/article_article_tag/article_revision 四张新表
- Entity 定义:修改 Article entity + 新增 ArticleCategory、ArticleTag、ArticleArticleTag、ArticleRevision
- Service 层:ArticleService 增强(状态机、审核、搜索)+ CategoryService + TagService + RevisionService
- Handler 层:新增审核/分类/标签/上传端点
- 权限注册:新增
health.articles.review - 事件发布:article.submitted/approved/rejected/published
- 图片上传:文件存储端点
Phase 2:Web 前端(3-4 天)
- 安装 Wangeditor 依赖
- 文章列表页(筛选、状态 Tab、表格)
- 文章编辑页(富文本编辑器 + 元数据表单)
- 文章预览/审核页
- 分类管理页
- 标签管理页
- 路由注册 + 侧边栏菜单
Phase 3:小程序增强(1-2 天)
- 文章列表分类 Tab
- 搜索功能
- 阅读计数
- API 调用适配
总估算:7-10 天
8. 验收标准
- 作者可创建/编辑文章(富文本),保存为草稿
- 作者可提交审核
- 审核员可看到待审列表,通过或拒绝
- 已发布文章在小程序端可见
- 分类和标签可管理
- 图片可上传并在编辑器中插入
- 阅读计数正确递增
cargo check+cargo test通过- 前端
pnpm build通过