3.2 KiB
3.2 KiB
历史记录按天去重功能实现计划
需求总结
当用户在同一天内重复点击同一个实用工具或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小时改为当天 |
验证步骤
-
同一天内重复点击测试
- 打开同一个工具/API 页面3次
- 检查历史记录页面,应只有1条记录
- 检查 localStorage,应有对应的 key
-
跨天测试
- 第一天点击工具A,记录历史
- 第二天再次点击工具A
- 检查历史记录页面,应有2条记录(分别在不同日期)
-
不同工具测试
- 同一天内点击工具A、工具B、工具C
- 检查历史记录页面,应有3条记录
-
localStorage 清理测试
- 确认不会无限增长(每天自动覆盖旧日期的 key)
风险评估
- localStorage 被用户清除时,去重会失效,但后端仍有兜底逻辑
- 后端修改不影响现有API接口,只是调整了去重时间窗口