# 新闻资讯模块设计方案 ## 1. 概述 ### 1.1 模块定位 新闻资讯模块是飞点健康 CMS 系统的核心内容管理模块,用于发布和管理企业新闻、行业资讯、产品动态等内容。该模块与顶级菜单"新闻动态"关联,提供完整的栏目管理和资讯发布功能。 ### 1.2 设计目标 - 支持双格式发布:Markdown + HTML 富文本 - 复用现有成熟代码(personal-blog) - 支持图片资源管理(可作为独立顶级模块) - 提供良好的编辑体验和预览功能 ### 1.3 功能范围 ``` ┌─────────────────────────────────────────────────────────────┐ │ 新闻资讯模块 │ ├─────────────────┬─────────────────┬─────────────────────────┤ │ 栏目管理 │ 资讯管理 │ 图片管理 │ ├─────────────────┼─────────────────┼─────────────────────────┤ │ • 创建栏目 │ • 创建资讯 │ • 上传图片 │ │ • 编辑栏目 │ • 编辑资讯 │ • 图片列表 │ │ • 删除栏目 │ • 删除资讯 │ • 插入到文章 │ │ • 栏目排序 │ • 发布/草稿 │ • 删除图片 │ │ │ • Markdown编辑 │ │ │ │ • HTML富文本 │ │ │ │ • 预览功能 │ │ └─────────────────┴─────────────────┴─────────────────────────┘ ``` --- ## 2. 数据库设计 ### 2.1 数据表关系图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ news_categories│ │ news_posts │ │ images │ │ (栏目表) │◄────────│ (资讯表) │────────►│ (图片表) │ ├─────────────────┤ 1:N ├─────────────────┤ N:M ├─────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ name │ │ title │ │ filename │ │ slug (UQ) │ │ slug (UQ) │ │ file_path │ │ description │ │ content │ │ thumb_path │ │ sort_order │ │ content_type │◄───────│ description │ │ is_enabled │ │ summary │ │ file_size │ │ created_at │ │ cover_image │◄───────│ width │ │ updated_at │ │ category_id(FK) │ │ height │ └─────────────────┘ │ is_published │ │ created_at │ │ is_draft │ └─────────────────┘ │ view_count │ │ created_at │ │ updated_at │ └─────────────────┘ │ │ 1:N ▼ ┌─────────────────┐ │ news_post_images│ │ (文章图片关联) │ ├─────────────────┤ │ post_id (FK) │ │ image_id (FK) │ └─────────────────┘ ``` ### 2.2 表结构定义 #### 2.2.1 news_categories - 栏目表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | name | VARCHAR(50) | NOT NULL | 栏目名称 | | slug | VARCHAR(50) | UNIQUE, NOT NULL | URL标识(如:company-news) | | description | VARCHAR(200) | NULL | 栏目描述 | | sort_order | INTEGER | DEFAULT 0 | 排序权重 | | is_enabled | BOOLEAN | DEFAULT 1 | 是否启用 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE news_categories ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50) NOT NULL, slug VARCHAR(50) UNIQUE NOT NULL, description VARCHAR(200), sort_order INTEGER DEFAULT 0, is_enabled BOOLEAN DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` #### 2.2.2 news_posts - 资讯表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | title | VARCHAR(200) | NOT NULL | 资讯标题 | | slug | VARCHAR(200) | UNIQUE, NOT NULL | URL友好的标识 | | content | TEXT | NOT NULL | 内容 | | content_type | VARCHAR(10) | DEFAULT 'markdown' | 内容类型:markdown/html | | summary | VARCHAR(500) | NULL | 摘要(自动生成或手动填写)| | cover_image | VARCHAR(500) | NULL | 封面图路径 | | category_id | INTEGER | FK -> news_categories | 栏目ID(必填)| | is_published | BOOLEAN | DEFAULT 0 | 是否发布 | | is_draft | BOOLEAN | DEFAULT 1 | 是否草稿 | | view_count | INTEGER | DEFAULT 0 | 浏览次数 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE news_posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(200) NOT NULL, slug VARCHAR(200) UNIQUE NOT NULL, content TEXT NOT NULL, content_type VARCHAR(10) DEFAULT 'markdown', summary VARCHAR(500), cover_image VARCHAR(500), category_id INTEGER NOT NULL, is_published BOOLEAN DEFAULT 0, is_draft BOOLEAN DEFAULT 1, view_count INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES news_categories(id) ON DELETE RESTRICT ); ``` #### 2.2.3 images - 图片表(复用/扩展) 复用 personal-blog 的图片表结构,但提升为系统级资源表: | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | filename | VARCHAR(255) | NOT NULL | 存储文件名 | | original_name | VARCHAR(255) | NULL | 原始文件名 | | file_path | VARCHAR(500) | NOT NULL | 文件路径 | | thumb_path | VARCHAR(500) | NULL | 缩略图路径 | | description | VARCHAR(500) | NULL | 图片描述 | | file_size | INTEGER | NULL | 文件大小(字节)| | width | INTEGER | NULL | 图片宽度 | | height | INTEGER | NULL | 图片高度 | | module | VARCHAR(20) | DEFAULT 'news' | 所属模块:news/product/page等 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | ```sql CREATE TABLE images ( id INTEGER PRIMARY KEY AUTOINCREMENT, filename VARCHAR(255) NOT NULL, original_name VARCHAR(255), file_path VARCHAR(500) NOT NULL, thumb_path VARCHAR(500), description VARCHAR(500), file_size INTEGER, width INTEGER, height INTEGER, module VARCHAR(20) DEFAULT 'news', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` --- ## 3. 后端 API 设计 ### 3.1 路由结构 ``` /api/v1/ ├── /news/ │ ├── GET /categories # 获取栏目列表 │ ├── POST /categories # 创建栏目 │ ├── GET /categories/{id} # 获取栏目详情 │ ├── PUT /categories/{id} # 更新栏目 │ ├── DELETE /categories/{id} # 删除栏目 │ ├── GET /posts # 获取资讯列表(分页、筛选) │ ├── POST /posts # 创建资讯 │ ├── GET /posts/{id} # 获取资讯详情 │ ├── PUT /posts/{id} # 更新资讯 │ ├── DELETE /posts/{id} # 删除资讯 │ ├── POST /posts/{id}/publish # 发布资讯 │ ├── POST /posts/{id}/unpublish # 取消发布 │ └── GET /posts/slug/{slug} # 通过slug获取(访客端) └── /images/ ├── GET / # 获取图片列表(分页) ├── POST /upload # 上传图片 ├── DELETE /{id} # 删除图片 └── POST /{id}/insert # 获取图片插入URL ``` ### 3.2 核心 API 定义 #### 3.2.1 栏目管理 API **GET /api/v1/news/categories** ```json // Response { "items": [ { "id": 1, "name": "公司新闻", "slug": "company-news", "description": "飞点健康最新动态", "sort_order": 1, "is_enabled": true, "post_count": 15, "created_at": "2024-01-15T08:00:00" } ], "total": 5 } ``` **POST /api/v1/news/categories** ```json // Request { "name": "公司新闻", "slug": "company-news", "description": "飞点健康最新动态", "sort_order": 1 } ``` #### 3.2.2 资讯管理 API **GET /api/v1/news/posts?page=1&size=10&category_id=1&keyword=xxx** ```json // Response { "items": [ { "id": 1, "title": "飞点健康完成A轮融资", "slug": "feidian-series-a", "summary": "今日,飞点健康宣布完成数千万元A轮融资...", "cover_image": "/uploads/covers/xxx.jpg", "category": { "id": 1, "name": "公司新闻" }, "content_type": "markdown", "is_published": true, "is_draft": false, "view_count": 1250, "created_at": "2024-01-20T10:30:00", "updated_at": "2024-01-20T10:30:00" } ], "total": 50, "page": 1, "size": 10 } ``` **POST /api/v1/news/posts** ```json // Request { "title": "飞点健康完成A轮融资", "slug": "feidian-series-a", "content": "# 飞点健康完成A轮融资\n\n今日...", "content_type": "markdown", "summary": "今日,飞点健康宣布完成数千万元A轮融资...", "cover_image": "/uploads/covers/xxx.jpg", "category_id": 1, "is_draft": false } ``` --- ## 4. 前端设计 ### 4.1 页面结构 ``` /admin/news # 资讯管理首页(列表) /admin/news/posts # 资讯列表 /admin/news/posts/new # 新建资讯 /admin/news/posts/:id/edit # 编辑资讯 /admin/news/categories # 栏目管理 /admin/images # 图片管理(可作为顶级菜单) /news # 访客端新闻列表页 /news/:slug # 访客端新闻详情页 ``` ### 4.2 组件设计 #### 4.2.1 管理端组件 ``` src/pages/admin/news/ ├── NewsLayout.jsx # 新闻模块布局(侧边栏导航) ├── PostList.jsx # 资讯列表页 ├── PostEdit.jsx # 资讯编辑页(双编辑器支持) ├── CategoryList.jsx # 栏目列表页 └── components/ ├── MarkdownEditor.jsx # Markdown编辑器(复用blog) ├── HtmlEditor.jsx # HTML富文本编辑器 ├── PostForm.jsx # 资讯表单(标题、栏目、封面等) ├── CategoryForm.jsx # 栏目表单 ├── ImagePicker.jsx # 图片选择器 └── PostPreview.jsx # 文章预览组件 src/pages/admin/images/ ├── ImageManager.jsx # 图片管理页(可作为独立模块) └── components/ ├── ImageUploader.jsx # 图片上传组件 ├── ImageGrid.jsx # 图片网格展示 └── ImageDetail.jsx # 图片详情/编辑 ``` #### 4.2.2 编辑器选型 | 格式 | 编辑器 | 特点 | 图片支持 | |------|--------|------|----------| | Markdown | react-markdown-editor-lite | 轻量、性能好 | 支持粘贴/拖拽上传 | | HTML | TinyMCE 6 | 功能丰富、稳定 | 内置图片上传插件 | **TinyMCE 配置要点:** ```javascript { plugins: 'image link media table code fullscreen', toolbar: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright | bullist numlist | image media link | table | code fullscreen', images_upload_url: '/api/v1/images/upload', images_upload_handler: customUploadHandler } ``` ### 4.3 路由配置 ```javascript // 添加到 AdminLayout 侧边栏 { path: '/admin/news', label: '新闻资讯', icon: Newspaper, children: [ { path: '/admin/news/posts', label: '资讯管理' }, { path: '/admin/news/categories', label: '栏目管理' } ] } // 独立图片管理(可作为顶级菜单) { path: '/admin/images', label: '图片管理', icon: Image } ``` --- ## 5. 复用代码清单 ### 5.1 从 personal-blog 复用 | 组件/模块 | 源文件路径 | 目标路径 | 修改点 | |-----------|-----------|----------|--------| | 图片模型 | backend/models.py Image | backend/app/models/image.py | 添加 module 字段 | | 图片上传API | backend/routers/images.py | backend/app/routers/images.py | 适配新路由前缀 | | 图片管理页 | frontend/src/pages/admin/Images.jsx | frontend/src/pages/admin/images/ImageManager.jsx | 样式统一 | | Markdown编辑器 | 无(需新增) | frontend/src/pages/admin/news/components/MarkdownEditor.jsx | - | ### 5.2 复用策略 1. **图片管理**:完全复用 blog 的图片表结构,添加 `module` 字段区分来源 2. **文件上传**:复用上传逻辑,统一存储到 `/uploads/news/` 3. **缩略图生成**:复用 PIL 缩略图生成逻辑 --- ## 6. 访客端展示 ### 6.1 新闻列表页 (/news) - 顶部显示栏目筛选标签 - 列表展示:封面图、标题、摘要、发布时间、浏览量 - 支持分页加载 ### 6.2 新闻详情页 (/news/:slug) - 文章标题、发布时间、栏目 - 根据 content_type 渲染不同格式 - Markdown: 使用 react-markdown + remark-gfm - HTML: 使用 dangerouslySetInnerHTML(需 XSS 过滤) ### 6.3 首页新闻模块联动 home_modules 表中 type=news 的模块,从 news_posts 表读取最新 N 条数据展示。 --- ## 7. 实现步骤 ### Phase 1: 数据库与后端 API(预计 2-3 天) 1. [ ] 创建数据库表(categories, posts, images) 2. [ ] 实现栏目管理 API 3. [ ] 实现资讯管理 API 4. [ ] 复用/改造图片上传 API 5. [ ] 编写 API 测试 ### Phase 2: 管理端前端(预计 3-4 天) 1. [ ] 创建新闻模块路由和布局 2. [ ] 实现栏目管理页面 3. [ ] 实现 Markdown 编辑器组件 4. [ ] 实现 HTML 编辑器组件(TinyMCE 集成) 5. [ ] 实现资讯列表页 6. [ ] 实现资讯编辑页(双编辑器切换) 7. [ ] 实现图片管理页面 ### Phase 3: 访客端与联调(预计 2 天) 1. [ ] 实现新闻列表页 2. [ ] 实现新闻详情页(支持 Markdown/HTML 渲染) 3. [ ] 联调首页新闻模块数据 4. [ ] 顶部菜单"新闻动态"链接配置 ### Phase 4: 优化与测试(预计 1-2 天) 1. [ ] 图片懒加载优化 2. [ ] XSS 防护(HTML 内容过滤) 3. [ ] 移动端适配 4. [ ] 性能测试 --- ## 8. 技术要点 ### 8.1 XSS 防护 对于 HTML 格式的内容,必须做 XSS 过滤: ```python # 后端存储前过滤(可选) from bleach import clean allowed_tags = ['p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'a', 'img', 'table', 'thead', 'tbody', 'tr', 'td', 'th'] allowed_attrs = {'a': ['href', 'title'], 'img': ['src', 'alt', 'width', 'height']} cleaned_html = clean(raw_html, tags=allowed_tags, attributes=allowed_attrs) ``` ### 8.2 图片存储规范 ``` uploads/ ├── news/ # 新闻资讯图片 │ ├── 2024/01/ # 按年月组织 │ │ ├── xxx.jpg │ │ └── thumbnails/ # 缩略图 │ └── ... ├── products/ # 产品图片 ├── pages/ # 页面图片 └── common/ # 通用图片 ``` ### 8.3 slug 生成规则 ```python def generate_slug(title: str) -> str: """将标题转换为 URL 友好的 slug""" # 1. 移除特殊字符 # 2. 空格替换为连字符 # 3. 转小写 # 4. 处理重复(添加数字后缀) ``` --- ## 9. 扩展性考虑 ### 9.1 未来可扩展功能 - [ ] 文章标签系统 - [ ] 文章评论功能 - [ ] 文章定时发布 - [ ] 文章版本历史 - [ ] 文章 SEO 元数据管理 - [ ] 多语言支持 ### 9.2 图片管理升级 当前作为新闻模块子功能,后续可提升为系统级资源中心,支持: - 图片分类/标签 - 批量上传 - 图片搜索 - 在线编辑(裁剪、滤镜) --- ## 10. 参考资源 ### 10.1 编辑器文档 - TinyMCE React: https://www.tiny.cloud/docs/tinymce/6/react-cloud/ - react-markdown-editor-lite: https://github.com/HarryChen0506/react-markdown-editor-lite ### 10.2 代码参考 - personal-blog Markdown 编辑实现 - personal-blog 图片管理实现 --- *文档版本: 1.0* *创建时间: 2026-04-20* *作者: nanobot*