评论模块
欢迎来到评论模块文档!本模块实现了一个功能完整的多层级评论系统。
📚 模块概览
评论模块是博客系统的核心交互功能,支持:
- ✅ 多层级嵌套评论(最大5层)
- ✅ 树形结构查询和展示
- ✅ 状态流转和审核机制
- ✅ 权限控制
- ✅ 审核原因记录
- ✅ 内容安全处理(XSS过滤、敏感词过滤、Markdown渲染)
- ✅ 点赞和举报功能
- ✅ @mention 用户提及
- ✅ 评论编辑历史
- ✅ 通知系统集成
🏗️ 技术架构
核心技术
- 数据结构: Materialized Path(物化路径)
- 设计模式: 状态模式(State Pattern)、责任链模式(Chain of Responsibility)
- 权限控制: Spring Security + @PreAuthorize
- 数据库: MySQL 9.4.0 + MyBatis-Plus
- 内容安全: XSS 过滤、敏感词过滤、Markdown 渲染
- 事件驱动: Spring Events + @Async 异步处理
- 跨模块通信: 通过 *-api 接口实现松耦合
模块结构
blog-module-comment/
├── blog-comment-api/ # API层(DTO、VO、枚举)
└── blog-comment-service/ # 服务层
├── controller/ # REST API
├── service/ # 业务逻辑
├── domain/
│ ├── entity/ # 实体类
│ ├── state/ # 状态模式类
│ ├── processor/ # 责任链处理器
│ ├── parser/ # @mention 解析器
│ └── event/ # 领域事件
└── infrastructure/ # 基础设施
├── converter/ # MapStruct转换器
└── mapper/ # MyBatis Mapper
🎯 功能特性
1. 树形评论结构
使用 Materialized Path 算法实现高效的多层级评论:
- 单次查询获取整棵树
- 深度限制(最大5层)
- 自动计算 path、depth、rootId
2. 状态管理
通过状态模式实现评论审核流转:
- PENDING (待审核): 新评论的初始状态
- APPROVED (已通过): 审核通过,前端可见
- REJECTED (已拒绝): 审核不通过
- USER_DELETED (用户删除): 用户主动删除
- ADMIN_DELETED (管理员删除): 违规内容删除
3. 权限控制
- 用户可以删除自己的评论
- 管理员可以审核和删除任何评论
- 使用
@PreAuthorize进行方法级权限控制
📖 学习路径
本模块分为七个阶段实施,每个阶段都是可运行的完整功能:
Phase 1: 基础框架搭建
学习目标: 掌握模块结构、Flyway迁移、基础CRUD
- 数据库表设计
- Entity、Mapper、Service、Controller 全套
- 基础 CRUD 接口
- 单元测试和集成测试
Phase 2: 树形结构实现
学习目标: 掌握 Materialized Path、递归查询、树形数据组装
- Materialized Path 算法
- 树形查询和组装
- 深度限制和错误处理
- 通用 TreeBuilder 工具类
Phase 3: 状态模式与审核
学习目标: 掌握状态模式、消除if-else、状态机设计
- 状态模式架构
- 审核流转逻辑
- 权限控制
- 审核原因记录
Phase 7: 通知系统集成
学习目标: 事件驱动架构、跨模块通信、异步处理
- 跨模块服务接口设计
- 异步事件处理(@Async)
- @mention 和回复通知
- 类型安全处理
🚀 快速开始
API 端点
普通用户接口:
POST /api/v1/comments # 创建评论
POST /api/v1/comments/reply # 回复评论
GET /api/v1/comments/{id} # 查询评论详情
GET /api/v1/comments/tree # 获取评论树
DELETE /api/v1/comments/{id} # 删除自己的评论
管理员接口 (需要 ADMIN 角色):
POST /api/v1/comments/audit/{id}/approve # 审核通过
POST /api/v1/comments/audit/{id}/reject # 审核拒绝
DELETE /api/v1/comments/audit/{id} # 管理员删除
🚀 快速开始
API 端点
普通用户接口:
POST /api/v1/comments # 创建评论
POST /api/v1/comments/reply # 回复评论
GET /api/v1/comments/{id} # 查询评论详情
GET /api/v1/comments/tree # 获取评论树
DELETE /api/v1/comments/{id} # 删除自己的评论
POST /api/v1/comments/{id}/like # 点赞评论
DELETE /api/v1/comments/{id}/like # 取消点赞
POST /api/v1/comments/report # 举报评论
管理员接口 (需要 ADMIN 角色):
POST /api/v1/comments/audit/{id}/approve # 审核通过
POST /api/v1/comments/audit/{id}/reject # 审核拒绝
DELETE /api/v1/comments/audit/{id} # 管理员删除
POST /api/v1/comments/audit/reports/{reportId}/approve # 通过举报
POST /api/v1/comments/audit/reports/{reportId}/reject # 拒绝举报
数据库表结构
主表: cmt_comment
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键(雪花ID) |
| target_type | VARCHAR(20) | 目标类型(ARTICLE/PAGE等) |
| target_id | BIGINT | 目标ID |
| parent_id | BIGINT | 父评论ID(根评论为NULL) |
| content | TEXT | 评论内容(原始文本) |
| content_html | TEXT | 渲染后的HTML内容 |
| status | TINYINT | 状态(0:待审核 1:已通过 2:已拒绝 3:用户删除 4:管理员删除) |
| like_count | INT | 点赞数 |
| reply_count | INT | 回复数 |
| path | VARCHAR(500) | 物化路径(如 /1/2/3/) |
| depth | INT | 深度(根评论为0) |
| root_id | BIGINT | 根评论ID |
| audit_reason | VARCHAR(500) | 审核/删除原因 |
| is_edited | TINYINT | 是否编辑过(0:否 1:是) |
| edit_time | DATETIME | 最后编辑时间 |
| mentioned_user_ids | VARCHAR(500) | 被@提及的用户ID(JSON数组) |
| version | INT | 乐观锁版本号 |
| create_by | BIGINT | 创建人ID |
| create_time | DATETIME | 创建时间 |
| update_by | BIGINT | 更新人ID |
| update_time | DATETIME | 更新时间 |
| is_deleted | TINYINT | 逻辑删除(0:否 1:是) |
辅助表:
cmt_comment_like: 评论点赞记录cmt_comment_report: 评论举报记录cmt_comment_history: 评论编辑历史
📊 状态流转图
stateDiagram-v2
[*] --> PENDING: 创建评论
PENDING --> APPROVED: 审核通过
PENDING --> REJECTED: 审核拒绝
PENDING --> ADMIN_DELETED: 管理员删除
APPROVED --> USER_DELETED: 用户删除
APPROVED --> ADMIN_DELETED: 管理员删除
REJECTED --> [*]
USER_DELETED --> [*]
ADMIN_DELETED --> [*]
🔧 配置说明
最大嵌套深度
在 CommentServiceImpl 中定义:
private static final int MAX_DEPTH = 5;
默认状态
新评论默认状态为 PENDING(待审核),需要管理员审核后才能显示。
💡 最佳实践
- 深度控制: 限制最大嵌套深度避免性能问题
- 状态模式: 使用状态模式而非 if-else 管理复杂状态转换
- 权限分离: 普通用户接口和管理员接口分开
- 乐观锁: 使用版本号防止并发更新冲突
- 审核原因: 记录拒绝和删除的原因便于追溯
📝 相关文档
版本: 1.7.0
最后更新: 2025-12-18
Phase 7 完成: 通知系统集成 ✅