评论审核系统是内容平台保障内容合规性的重要组件,使用Golang搭建基础版本可以充分发挥其高并发、性能稳定的优势,快速处理大量用户提交的评论内容。本文将从零开始介绍搭建流程,覆盖核心功能实现。

系统核心需求与模块划分
基础的评论审核系统需要完成三个核心任务:接收用户提交的评论内容、检测内容是否包含违规信息、存储审核结果并反馈状态。对应的模块可以分为三个部分:
- 评论接收模块:提供HTTP接口接收前端提交的评论数据
- 审核处理模块:实现敏感词过滤逻辑,判断评论是否合规
- 存储模块:将评论内容和审核结果存入数据库,方便后续查询
环境准备与依赖安装
首先需要准备Golang开发环境,本文使用Go 1.21版本,需要安装的第三方依赖如下:
- gin:用于快速搭建HTTP服务
- gorm:用于操作数据库
- go-sqlite3:作为示例数据库驱动,也可以替换为MySQL等
安装依赖的命令如下:
go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite go get -u github.com/mattn/go-sqlite3
数据模型定义
首先定义评论的数据结构,包含评论ID、内容、提交用户、审核状态、提交时间等字段:
package main
import (
"time"
"gorm.io/gorm"
)
// Comment 评论数据模型
type Comment struct {
ID uint `gorm:"primaryKey" json:"id"` // 评论ID
Content string `json:"content"` // 评论内容
UserID uint `json:"user_id"` // 提交用户ID
Status string `json:"status"` // 审核状态:pending待审核 pass通过 reject拒绝
CreatedAt time.Time `json:"created_at"` // 提交时间
UpdatedAt time.Time `json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"` // 软删除字段
}
敏感词过滤实现
审核的核心是敏感词检测,这里实现一个简单的敏感词树(Trie树)来提升过滤效率:
package main
// TrieNode 敏感词树节点
type TrieNode struct {
Children map[rune]*TrieNode // 子节点
IsEnd bool // 是否为敏感词结尾
}
// SensitiveFilter 敏感词过滤器
type SensitiveFilter struct {
Root *TrieNode
}
// NewSensitiveFilter 初始化过滤器
func NewSensitiveFilter() *SensitiveFilter {
return &SensitiveFilter{
Root: &TrieNode{
Children: make(map[rune]*TrieNode),
IsEnd: false,
},
}
}
// AddWord 添加敏感词到树中
func (f *SensitiveFilter) AddWord(word string) {
node := f.Root
for _, ch := range word {
if _, ok := node.Children[ch]; !ok {
node.Children[ch] = &TrieNode{
Children: make(map[rune]*TrieNode),
IsEnd: false,
}
}
node = node.Children[ch]
}
node.IsEnd = true
}
// Check 检测内容是否包含敏感词,返回是否合规和命中的敏感词
func (f *SensitiveFilter) Check(content string) (bool, string) {
runes := []rune(content)
for i := 0; i < len(runes); i++ {
node := f.Root
for j := i; j < len(runes); j++ {
ch := runes[j]
if child, ok := node.Children[ch]; ok {
if child.IsEnd {
return false, string(runes[i : j+1])
}
node = child
} else {
break
}
}
}
return true, ""
}
HTTP服务与接口实现
使用gin框架搭建HTTP服务,实现评论提交接口和审核结果查询接口:
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var (
db *gorm.DB
sensitiveFilter *SensitiveFilter
)
func main() {
// 初始化数据库
initDB()
// 初始化敏感词过滤器,添加示例敏感词
initFilter()
// 初始化gin服务
r := gin.Default()
// 注册接口
r.POST("/comment/submit", submitComment) // 提交评论接口
r.GET("/comment/list", listComments) // 查询评论列表接口
// 启动服务
r.Run(":8080")
}
// initDB 初始化数据库连接并自动迁移表结构
func initDB() {
var err error
db, err = gorm.Open(sqlite.Open("comment.db"), &gorm.Config{})
if err != nil {
panic("连接数据库失败: " + err.Error())
}
// 自动创建comment表
err = db.AutoMigrate(&Comment{})
if err != nil {
panic("迁移表结构失败: " + err.Error())
}
}
// initFilter 初始化敏感词过滤器
func initFilter() {
sensitiveFilter = NewSensitiveFilter()
// 添加示例敏感词,实际项目中可以从数据库或配置文件加载
sensitiveFilter.AddWord("违规词1")
sensitiveFilter.AddWord("违规词2")
}
// submitComment 处理评论提交请求
func submitComment(c *gin.Context) {
var req struct {
Content string `json:"content" binding:"required"` // 请求中的评论内容
UserID uint `json:"user_id" binding:"required"` // 请求中的用户ID
}
// 绑定请求参数
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"msg": "参数错误"})
return
}
// 创建评论记录,初始状态为待审核
comment := Comment{
Content: req.Content,
UserID: req.UserID,
Status: "pending",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// 先保存待审核记录
if err := db.Create(&comment).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"msg": "保存评论失败"})
return
}
// 执行敏感词检测
pass, hitWord := sensitiveFilter.Check(req.Content)
if pass {
// 审核通过
comment.Status = "pass"
} else {
// 审核拒绝
comment.Status = "reject"
}
// 更新审核状态
db.Model(&comment).Update("status", comment.Status)
// 返回结果
c.JSON(http.StatusOK, gin.H{
"msg": "提交成功",
"status": comment.Status,
"comment_id": comment.ID,
})
}
// listComments 查询评论列表
func listComments(c *gin.Context) {
var comments []Comment
// 查询所有未删除的评论,按提交时间倒序排列
if err := db.Order("created_at desc").Find(&comments).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"msg": "查询失败"})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": "查询成功",
"data": comments,
})
}
系统测试与扩展方向
启动服务后,可以使用Postman等工具测试接口:
- 提交评论:POST请求到
http://127.0.0.1:8080/comment/submit,携带{"content":"测试评论内容","user_id":1}参数,会返回审核状态 - 查询列表:GET请求到
http://127.0.0.1:8080/comment/list,可以获取所有评论及审核结果
这个基础版本还可以进一步扩展,比如添加人工审核模块、支持正则匹配违规内容、对接第三方审核接口、增加评论回复功能等,满足更复杂的业务需求。