feat: implement comprehensive reading analytics system with bot detection

Features:
- Add article view tracking with automatic deduplication (per user/IP)
- Implement intelligent bot detection (35+ patterns: Google, Bing, Baidu, GPTBot, etc)
- Create admin analytics dashboard with statistics and filtering
- Display view count and comment count on article cards
- Add search-based article filter (replaced dropdown for scalability)

Analytics Dashboard:
- Global stats: total views, human/bot views, unique IPs/users
- Top 20 articles ranking with detailed metrics
- Detailed view records with time, article, user, IP, user-agent
- Filters: article title search, IP search, show/hide bots
- Pagination support (50 records per page)

Technical Implementation:
- Async view recording (non-blocking)
- Dual deduplication (application + database layer)
- Database indexes for performance optimization
- Batch query for comment counts
- Full i18n support (Chinese/English)

Files Added:
- models/article_view.go: View tracking model
- models/bot_detector.go: Bot detection logic
- handlers/admin_analytics.go: Analytics page handler
- templates/admin/analytics_views.html: Analytics UI
- test_analytics.sh: Testing script
- Documentation: implementation guide, usage guide, changelog

Files Modified:
- handlers/home.go: Add view recording and comment count queries
- models/db.go: Add ArticleView to auto-migration
- main.go: Add analytics routes
- i18n/i18n.go: Add 35+ translation keys
- templates/admin/dashboard.html: Add analytics entry link
- templates/pages/home.html: Display view/comment counts on cards

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 19:57:12 +08:00
co-authored by Claude Fable 5
parent 5ec783e471
commit da7a39c1c8
16 changed files with 1701 additions and 5 deletions
+163
View File
@@ -0,0 +1,163 @@
# RSS订阅功能实现计划
## 概述
为Go博客系统添加RSS 2.0订阅功能,允许用户通过RSS阅读器订阅博客的最新文章。
## 当前项目分析
### 技术栈
- **框架**: Gin (HTTP框架)
- **ORM**: GORM
- **数据库**: SQLite/MySQL (可配置)
- **模板**: Go HTML templates
### 现有结构
1. **路由**: 在 `main.go` 中集中注册
2. **处理器**: 在 `handlers/` 目录下,按功能分文件
3. **模型**: 在 `models/` 目录下
4. **文章模型** (`models/article.go`):
- 包含标题、摘要、内容、作者、发布时间等字段
- 有状态管理(草稿/已发布/已归档)
- 支持slug用于URL
5. **主页** (`handlers/home.go`):
- 已有获取已发布文章的逻辑
- 按置顶和发布时间排序
- 限制返回10篇文章
### 发现
- 项目没有现有的RSS或feed相关代码
- 没有RSS相关的Go依赖包
- 项目支持中英文双语(i18n
- 有网站设置模型 (`SiteSetting`),包含网站标题、描述等信息
## 实现方案
### 方案选择
**推荐方案**: 使用标准库 `encoding/xml` 手动构建RSS 2.0格式
- **优点**:
- 无需引入新依赖
- RSS 2.0格式简单明确
- 完全控制输出格式
- 符合项目轻量化原则
- **缺点**:
- 需要手动定义XML结构
**备选方案**: 使用第三方库如 `github.com/gorilla/feeds`
- **优点**: 简化RSS生成,支持RSS/Atom/JSON Feed
- **缺点**: 引入新依赖
**决策**: 采用推荐方案,使用标准库实现RSS 2.0
### 实现步骤
#### 1. 创建RSS模型和生成器 (`handlers/rss.go`)
- 定义RSS 2.0的XML结构体:
- `RSS` (根元素)
- `Channel` (频道信息)
- `Item` (文章项)
- 实现 `RSSFeed` 处理器函数:
- 从数据库获取最近20篇已发布文章(包含作者信息)
-`SiteSetting` 获取网站标题和描述
- 根据当前语言决定使用中文或英文的网站信息
- 构建RSS XML结构
- 设置正确的Content-Type: `application/rss+xml; charset=utf-8`
- 返回XML响应
#### 2. RSS内容规范
- **Channel级别**:
- `title`: 网站标题(从 `SiteSetting.LogoText` 获取)
- `link`: 网站首页URL
- `description`: 网站描述(从 `SiteSetting.HomeSubtitle` 获取)
- `language`: zh-CN 或 en-US(根据当前语言)
- `lastBuildDate`: 最新文章的发布时间
- **Item级别**:
- `title`: 文章标题
- `link`: 文章详情页URL(使用slug
- `description`: 文章摘要(如果有)或内容前200字符
- `author`: 作者用户名或显示名称
- `pubDate`: 文章发布时间(RFC822格式)
- `guid`: 文章的唯一标识(使用文章详情URL)
#### 3. 注册路由 (`main.go`)
在public路由区域添加:
```go
router.GET("/rss", handlers.RSSFeed(db))
router.GET("/feed", handlers.RSSFeed(db)) // 别名,增加兼容性
```
#### 4. 可选:在模板中添加RSS链接
在HTML head中添加RSS自动发现标签:
```html
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/rss">
```
### 技术细节
#### URL生成
- 需要构建完整的文章URL(包含域名)
- 从请求的 `Host` 头获取域名
- 构建格式: `http(s)://domain/article/{slug}`
#### 时间格式
- RSS 2.0要求使用RFC822格式
- Go time包: `time.RFC1123Z` 或手动格式化
#### 文章内容处理
- 优先使用 `Summary` 字段
- 如果没有摘要,截取 `Content` 前200字符
- 需要处理HTML标签(strip或escape
#### 字符编码
- 确保XML声明中包含 `encoding="UTF-8"`
- Gin自动处理UTF-8编码
### 安全考虑
- RSS是只读接口,不需要认证
- 只返回状态为"已发布"的文章
- XSS防护:XML自动转义特殊字符
### 性能考虑
- 限制返回文章数量(20篇)
- 使用数据库索引(status和published_at字段已有索引)
- 可以考虑添加缓存(后续优化)
## 文件清单
### 新建文件
1. `handlers/rss.go` - RSS处理器和XML结构定义
### 修改文件
1. `main.go` - 添加RSS路由
2. 可选:`templates/layouts/base.html` - 添加RSS自动发现标签
## 测试验证
### 手动测试
1. 启动服务器
2. 访问 `http://localhost:PORT/rss`
3. 验证返回的XML格式正确
4. 检查Content-Type头
5. 使用RSS阅读器(如Feedly)订阅测试
### 测试点
- [ ] RSS XML格式符合RSS 2.0规范
- [ ] 包含最新的已发布文章
- [ ] 文章链接可点击且正确
- [ ] 中英文切换正常工作
- [ ] 时间格式正确
- [ ] 特殊字符正确转义
- [ ] 在RSS阅读器中可正常显示
## 实现优先级
1. **核心功能**: RSS feed端点,返回最新文章
2. **可选优化**:
- 在页面头部添加RSS自动发现标签
- 添加RSS订阅链接到导航栏
- 实现缓存机制
## 注意事项
- 保持代码风格与现有项目一致
- 遵循项目的命名约定
- 添加适当的注释(中英文)
- 确保RSS feed在中英文环境下都能正常工作