gongxiangp2/docs/upload-status-issue-analysis.md
chenpei ea9076df45 feat: 实现统一的下载错误处理系统并修复产品全案数据库Schema
- 创建统一的下载错误处理模块 (lib/download-errors.ts)
- 实现13种错误类型分类和中文错误消息
- 后端统一使用 createDownloadError 创建标准化错误响应
- 前端统一使用 parseDownloadError 解析错误并显示
- 修复正式系统数据库Schema,添加产品全案相关字段和表
- 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段
- 创建 material_assets, api_keys, api_call_logs 表
2026-01-05 17:52:42 +08:00

3.9 KiB
Raw Blame History

上传状态问题分析报告

📋 问题描述

用户报告正式系统中有4个素材"一直在上传",但实际上传已完成。

🔍 问题分析

系统架构

  1. 分片上传机制

    • 大文件(≥5MB)使用分片上传
    • 使用 IndexedDB 存储上传状态
    • 上传流程:chunkUpload → completeUpload → deleteUploadState
  2. 状态存储

    • IndexedDB 数据库名:chunk-upload-db
    • ObjectStore 名:upload-states
    • 存储内容:文件ID、文件名、分片信息、上传进度等
  3. 状态清理

    • 正常情况下,completeUpload 成功后应该调用 deleteUploadState 清理状态
    • 如果出现异常,状态可能残留

可能的原因

  1. 状态未正确清理

    • completeUpload 成功但 deleteUploadState 未执行
    • 上传过程中异常,状态没有正确清理
    • 网络问题导致清理请求失败
  2. 前端显示问题

    • IndexedDB 中有残留状态
    • 如果使用 ResumeUploadModal,会显示这些残留状态
    • 前端可能认为还有未完成的上传
  3. 实际状态

    • ✅ 文件已成功上传到服务器
    • ✅ 数据库记录已创建
    • ⚠️ 但 IndexedDB 中可能还有残留状态

✅ 验证结果

  1. 服务器端验证

    • ✅ 所有4个素材的文件都已成功上传
    • ✅ 数据库记录正常
    • ✅ 文件大小正常(1.6GB左右)
  2. 前端状态

    • ⚠️ 需要检查浏览器 IndexedDB 中是否有残留状态

🛠️ 解决方案

方案1:使用检查工具(推荐)

已创建检查工具:scripts/check-indexeddb-uploads.html

使用方法:

  1. 在浏览器中打开此HTML文件
  2. 工具会自动检查 IndexedDB 中的上传状态
  3. 如果发现残留状态:
    • 可以单独删除某个状态
    • 或者清除所有状态

方案2:手动清理(开发者工具)

  1. 打开浏览器开发者工具(F12)
  2. 切换到 Application 标签
  3. 左侧找到 IndexedDB → chunk-upload-db → upload-states
  4. 查看是否有残留的状态记录
  5. 如果有,可以手动删除

方案3:代码修复(长期)

如果问题经常出现,可以考虑:

  1. 增强错误处理

    // 在 completeUpload 成功后,确保删除状态
    try {
      result = await completeUpload(state.uploadId!, metadata)
      await deleteUploadState(fileId) // 确保执行
      return result
    } catch (error) {
      // 即使失败也要清理状态(避免残留)
      await deleteUploadState(fileId).catch(() => {})
      throw error
    }
    
  2. 添加状态验证

    • 上传完成后,验证服务器端是否已创建记录
    • 如果已创建,清理本地状态
    • 如果未创建,保留状态以便重试
  3. 定期清理

    • 检查超过一定时间(如24小时)的残留状态
    • 验证服务器端是否已创建记录
    • 如果已创建,自动清理

📝 检查清单

  • 在浏览器中打开检查工具查看 IndexedDB 状态
  • 确认是否有残留状态
  • 如果有,验证服务器端是否已创建记录
  • 如果已创建,清理 IndexedDB 中的残留状态
  • 刷新页面,确认问题是否解决

🔗 相关文件

  • lib/chunk-upload.ts - 分片上传核心逻辑
  • components/ResumeUploadModal.tsx - 恢复上传模态框
  • scripts/check-indexeddb-uploads.html - 检查工具
  • app/api/materials/upload/complete/route.ts - 完成上传API

📌 注意事项

  1. 不要轻易删除状态

    • 如果服务器端未创建记录,删除状态会导致无法恢复上传
    • 建议先验证服务器端状态再删除
  2. IndexedDB 是浏览器本地存储

    • 每个浏览器、每个域名独立
    • 需要在使用该浏览器的用户端操作
    • 不能从服务器端清理
  3. 如果问题持续出现

    • 可能需要检查代码逻辑
    • 添加更多的错误处理和日志
    • 考虑添加状态同步机制