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>
164 lines
4.8 KiB
Markdown
164 lines
4.8 KiB
Markdown
# 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在中英文环境下都能正常工作
|