第七章:评论系统与敏感词过滤

博客v1.0系列教程(Csharp)博客 v1.0 系列教程 (C#)

7.1 评论数据模型

评论支持嵌套回复,通过 ParentId 和 RootParentId 实现:

public class CommentDto
{
    public long Id { get; set; }
    public string? Content { get; set; }
    public long? ArticleId { get; set; }
    public long? UserId { get; set; }
    public string? Username { get; set; }
    public long? ParentId { get; set; }
    public long? RootParentId { get; set; }
    public int? DiggCount { get; set; }
    public DateTime? CreateTime { get; set; }
    public List<CommentDto>? Children { get; set; }
}

7.2 敏感词过滤

使用 ToolGood.Words 基于 DFA 算法实现:

public class SensitiveWordFilter
{
    private readonly WordsSearch _search = new();

    public SensitiveWordFilter()
    {
        // 加载敏感词库
        var words = LoadSensitiveWords();
        _search.SetKeywords(words);
    }

    public bool ContainsSensitive(string text)
    {
        return _search.ContainsAny(text);
    }

    public string Filter(string text)
    {
        return _search.Replace(text, '*');
    }

    public List<string> FindAll(string text)
    {
        return _search.FindAll(text)
            .Select(r => r.Keyword)
            .ToList();
    }
}

7.3 评论服务

public class CommentService : ICommentService
{
    private readonly IRepository<CommentModel> _commentRepo;
    private readonly SensitiveWordFilter _filter;

    public async Task<long> CreateCommentAsync(CreateCommentDto dto)
    {
        // 敏感词检测
        if (_filter.ContainsSensitive(dto.Content))
            throw new AppException(ErrorCode.COMMENT_CONTAINS_SENSITIVE);

        // 垃圾评分
        var spamScore = CalculateSpamScore(dto.Content);
        if (spamScore > 0.8)
            throw new AppException(ErrorCode.COMMENT_SPAM);

        var comment = new CommentModel
        {
            Content = dto.Content,
            ArticleId = dto.ArticleId,
            UserId = dto.UserId,
            ParentId = dto.ParentId,
            RootParentId = dto.RootParentId ?? dto.ParentId,
            CreateTime = DateTime.UtcNow
        };

        await _commentRepo.InsertAsync(comment);
        return comment.Id;
    }

    private double CalculateSpamScore(string content)
    {
        // 基于规则的垃圾评分
        var score = 0.0;
        if (content.Contains("http://") || content.Contains("https://"))
            score += 0.3;
        if (content.Length < 5)
            score += 0.2;
        // ... 更多规则
        return Math.Min(score, 1.0);
    }
}

7.4 评论树 API

app.MapGet("/api/comment/tree/{articleId}",
    async (ICommentService service, long articleId) =>
{
    // 获取某个文章的所有评论,构建嵌套树
    var comments = await service.GetCommentTreeAsync(articleId);
    return Results.Ok(comments);
});

下一章将实现分类管理与收藏功能。

csharpcommentfilterdfa