Files
chunyu_prject_react/.trae/documents/history-dedup-by-day.md
T
2026-08-05 23:59:22 +08:00

3.2 KiB
Raw Blame History

历史记录按天去重功能实现计划

需求总结

当用户在同一天内重复点击同一个实用工具或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接口,只是调整了去重时间窗口