82 lines
3.2 KiB
Markdown
82 lines
3.2 KiB
Markdown
# 历史记录按天去重功能实现计划
|
||
|
||
## 需求总结
|
||
当用户在**同一天内**重复点击同一个实用工具或API界面时,不创建新的历史记录,而是**更新已有记录的浏览时间**。
|
||
|
||
## 当前状态分析
|
||
|
||
### 前端(useRecordHistory.ts)
|
||
- 使用 `useRef` 实现2秒防抖
|
||
- **问题**:只在同一组件实例内有效,组件卸载后状态丢失,无法跨导航去重
|
||
|
||
### 后端(history/serializers.py)
|
||
- `BrowsingHistoryCreateSerializer.create()` 已有去重逻辑
|
||
- 查询一小时内是否有相同 `user + link` 的记录
|
||
- 如果有,调用 `existing.save()` 更新 `viewed_at`(因为 `auto_now=True`)
|
||
- **问题**:时间窗口是1小时,不是按天
|
||
|
||
## 实现方案
|
||
|
||
### 1. 前端修改:`src/hooks/useRecordHistory.ts`
|
||
|
||
**目标**:使用 localStorage 实现跨组件/跨导航的按天去重
|
||
|
||
**修改内容**:
|
||
- 添加 `getDailyKey(type, link)` 函数,生成格式为 `history:{type}:{link}:{YYYY-MM-DD}` 的 key
|
||
- 添加 `isRecordedToday(type, link)` 函数,检查 localStorage 中是否已存在当天记录
|
||
- 添加 `markAsRecorded(type, link)` 函数,在 localStorage 中标记已记录
|
||
- 在 `useEffect` 中,先检查 `isRecordedToday`,如果已记录则不发送请求
|
||
- 发送请求成功后,调用 `markAsRecorded` 标记
|
||
|
||
**localStorage 设计**:
|
||
- Key: `history:{type}:{link}:{YYYY-MM-DD}`
|
||
- Value: 时间戳或简单标记 `"1"`
|
||
- 示例: `history:tool:/utility/qrcode-generator:2026-07-28`
|
||
|
||
### 2. 后端修改:`history/serializers.py`
|
||
|
||
**目标**:将去重逻辑从"一小时内"改为"当天内"
|
||
|
||
**修改内容**:
|
||
- 修改 `BrowsingHistoryCreateSerializer.create()` 方法
|
||
- 将 `one_hour_ago = timezone.now() - timedelta(hours=1)` 改为当天开始时间
|
||
- 使用 `viewed_at__date=timezone.now().date()` 匹配当天记录
|
||
- 查询条件:`user=user, link=link, viewed_at__date=today`
|
||
- 如果找到当天记录,调用 `existing.save()` 更新 `viewed_at`
|
||
- 如果没有,创建新记录
|
||
|
||
### 3. 不需要修改的文件
|
||
- `history/models.py` - 模型定义无需修改
|
||
- `history/views.py` - 视图逻辑无需修改,serializer 已处理去重
|
||
- `history/urls.py` - URL 配置无需修改
|
||
|
||
## 涉及文件
|
||
|
||
| 文件 | 修改类型 | 说明 |
|
||
|------|----------|------|
|
||
| `src/hooks/useRecordHistory.ts` | 修改 | 添加 localStorage 按天去重逻辑 |
|
||
| `chunyu_project/history/serializers.py` | 修改 | 将去重时间窗口从1小时改为当天 |
|
||
|
||
## 验证步骤
|
||
|
||
1. **同一天内重复点击测试**
|
||
- 打开同一个工具/API 页面3次
|
||
- 检查历史记录页面,应只有1条记录
|
||
- 检查 localStorage,应有对应的 key
|
||
|
||
2. **跨天测试**
|
||
- 第一天点击工具A,记录历史
|
||
- 第二天再次点击工具A
|
||
- 检查历史记录页面,应有2条记录(分别在不同日期)
|
||
|
||
3. **不同工具测试**
|
||
- 同一天内点击工具A、工具B、工具C
|
||
- 检查历史记录页面,应有3条记录
|
||
|
||
4. **localStorage 清理测试**
|
||
- 确认不会无限增长(每天自动覆盖旧日期的 key)
|
||
|
||
## 风险评估
|
||
- localStorage 被用户清除时,去重会失效,但后端仍有兜底逻辑
|
||
- 后端修改不影响现有API接口,只是调整了去重时间窗口
|