Skip to content

历史归档

核心目标

让用户离开页面再回来时,所有素材、对话、提示词都能秒级恢复。

三层存储架构

text
┌────────────────────────────────────────────────────┐
│  浏览器层(前端)                                   │
│                                                    │
│  ┌─────────────────┐       ┌──────────────────┐    │
│  │  localStorage   │       │   IndexedDB      │    │
│  │  - 元数据索引    │       │   - 图片 Blob    │    │
│  │  - SKU 列表      │       │   - 视频 URL     │    │
│  │  - 当前会话 ID   │       │   - 完整对话     │    │
│  │  - 配置偏好      │       │   - 提示词历史    │    │
│  │                 │       │                  │    │
│  │  ≤ 5 MB         │       │   GB 级容量      │    │
│  └─────────────────┘       └──────────────────┘    │
└────────────────────┬───────────────────────────────┘

                     │ 持久化(异步)

┌────────────────────────────────────────────────────┐
│  后端层(Go + SQLite)                              │
│                                                    │
│  - usage_logs:配额扣减审计                         │
│  - request_logs:完整请求链路                       │
│  - kg_entities + kg_relations:GraphRAG 图谱        │
└────────────────────────────────────────────────────┘

存储分级策略

数据类型存储位置容量级别TTL
用户会话 tokenHttpOnly Cookie< 1KB7 天
当前页面状态localStorage≤ 5MB永久
SKU 索引 / 元数据localStorage≤ 5MB永久
图片缩略图IndexedDB100MB永久
图片原图 BlobIndexedDBGB 级永久
视频文件供应商 CDN URLURL only60 天
选品对话IndexedDB≤ 100MB永久
配额日志后端 SQLite不限永久

为什么不用 localStorage 存图片?

localStorage 限制

  • 容量上限 5MB(部分浏览器 10MB)
  • 同步 API → 阻塞主线程
  • 仅支持字符串 → 大图片 base64 化体积膨胀 33%

IndexedDB 优势

  • 容量 GB 级(受磁盘限制)
  • 异步 API → 不阻塞 UI
  • 原生支持 Blob → 直接存二进制
  • 索引查询性能高

IndexedDB Schema 设计

javascript
// 数据库结构
const dbSchema = {
  name: 'haiyu_history',
  version: 1,
  stores: {
    // 1. 多对话历史
    sessions: {
      keyPath: 'id',
      indexes: ['type', 'created_at', 'title']
    },
    // 2. 图片大文件
    images: {
      keyPath: 'id',
      indexes: ['session_id', 'model', 'created_at']
    },
    // 3. 一键全案记录
    all_in_one: {
      keyPath: 'id',
      indexes: ['product_title', 'created_at']
    },
    // 4. 选品分析
    product_analysis: {
      keyPath: 'session_id',
      indexes: ['topic', 'created_at']
    },
    // 5. 提示词模板
    prompt_templates: {
      keyPath: 'id',
      indexes: ['category', 'usage_count']
    }
  }
}

数据示例

javascript
{
  id: 'img_2026-05-01_xyz',
  session_id: 'session_abc',
  blob: <Blob 1024×1024 PNG>,
  thumbnail: <Blob 256×256 JPG>,
  prompt: 'Stainless steel kitchen rack ...',
  negative_prompt: '',
  model: 'NanoBananaPro',
  ratio: '1:1',
  resolution: '1K',
  created_at: '2026-05-01T08:32:11Z',
  metadata: {
    seed: 12345,
    cfg_scale: 7.5,
    graphrag_session: 'kg_xxx'
  }
}
javascript
{
  id: 'aio_2026-05-01_001',
  product_title: 'Stainless Steel Kitchen Rack',
  parameters: { material: '304 SUS', size: '60×30×80cm', ... },
  references: ['ref_image_1.jpg', 'ref_image_2.jpg'],
  graphrag: {
    entities: [...],
    relations: [...],
    visualization_url: 'idb://...'
  },
  outputs: {
    main_image: 'idb://img_xxx',
    bullets: ['...', '...', '...', '...', '...'],
    aplus: ['idb://...', 'idb://...', ...],
    grid_4: 'idb://...',
    video_url: 'https://cdn.veo.../xxx.mp4'
  },
  created_at: '2026-05-01T08:30:00Z',
  duration_ms: 38420
}
javascript
{
  session_id: 'pa_2026-05-01_001',
  topic: '美国站厨房收纳类目分析',
  category: 'Kitchen Storage',
  rounds: [
    {
      user: '我想做美国站厨房收纳...',
      ai: '该类目(B0085QQTUC 父节点)当前格局...',
      timestamp: '2026-05-01T09:00:00Z',
      tokens: { prompt: 234, completion: 1023 }
    }
  ],
  extracted_entities: {
    categories: ['Kitchen Storage'],
    asins: ['B0085QQTUC'],
    keywords: ['small apartment', 'foldable']
  },
  total_tokens: 4567
}

多对话切换

历史归档支持多对话标签页式切换

text
左侧侧栏:
┌──────────────────────────┐
│  + 新对话                  │
├──────────────────────────┤
│  📌 当前会话               │
│  🍴 厨房收纳全案           │
│  🏕️ 户外帐篷主图           │
│  💧 智能水杯 A+ 图         │
│  📊 美国厨房选品分析       │
│  ...                      │
│                          │
│  [按时间] [按 SKU]        │
└──────────────────────────┘

切换会话时,主区自动恢复:

  • 所有图片画廊
  • 文案历史
  • GraphRAG 图谱节点
  • 输入框最后状态

跨设备同步(路线图)

未来规划

当前版本数据仅保存在浏览器 IndexedDB。下个版本计划:

  • 用户主动「云同步」 → 上传到后端 SQLite
  • 接入对象存储(OSS / S3) → 替代 IndexedDB
  • 多设备登录自动拉取

性能数据

操作耗时说明
写入 1MB 图片 Blob≈ 50msIndexedDB 异步写入
读取 1000 张缩略图列表< 500ms索引查询 + 批量读
搜索 SKU 历史< 100mslocalStorage 元数据索引
切换会话 + 恢复< 800ms含图片懒加载
千张图历史回滚< 1s视口可见时再加载

清理策略

javascript
// 用户在「设置」页可清理
- 单条会话删除
- 按时间范围批量删除(如 30 天前)
- 全部清空
javascript
// 用户开启后自动清理
- 超过 90 天的会话自动归档
- 单会话超过 100 张图自动压缩
- 视频 URL 60 天后自动失效(CDN 限制)

容灾与备份

数据持久性提醒

  • IndexedDB 数据仅在当前浏览器,清浏览器缓存会清空
  • 重要素材请及时下载到本地
  • 后端 SQLite 仅保存配额、日志、知识图谱,不存图片原文件

下一步

基于 MIT 协议开源 · 中国大学生计算机设计大赛软件应用与开发类作品