Files
FruitServer/docs/plans/INBOX.md

5.9 KiB
Raw Permalink Blame History

INBOX

本轮任务:K100 后台剧集多选上传(分片 + 断点续传 + 进度展示)。[已处理] 开工前置:先读 AGENTS.md、CODING_STANDARDS.md、GIT_WORKFLOW.md 本文件,再读 ReelShortWeb/src/utils/uploader.ts、src/api/admin/media.ts、src/views/contentManagement/EpisodeManagementView.vue。

Codex 回执(K100)

  • ReelShortWeb 分支:feature/episode-batch-upload → --no-ff 合入 develop 并 push
  • 提交:feat(admin): 剧集多选分片上传与断点续传
  • 门禁:pnpm lint:eslint 零错误;pnpm build:dev 成功
  • 未验证:PM 手工多选/暂停/刷新续传/批量建集(8080+3005)
  • 风险:续传需重选相同本地文件;暂停不 abort 进行中分片

现状(已勘察,不要重复排查)

  • 后端分片上传已具备且不改:POST /admin/media/upload/init → POST /admin/media/upload/chunk → POST /admin/media/upload/complete;断点查询 GET /admin/media/upload/{uploadId} 返回 receivedChunks/totalChunks/chunkSize/percent/status/assetId/url。
  • 前端已有 src/utils/uploader.ts:uploadFile() 分片并发 3、resumeUpload() 按服务端已收片数续传、 probeVideoDuration() 探测时长。这两个函数已可用,本次在其上做批量队列 UI。
  • 当前剧集管理 EpisodeManagementView.vue 只有一个 el-upload 单文件入口(http-request="uploadVideo"), 不支持多选、没有进度条、没有断点续传入口,onSession 也没有落盘。

目标

在剧集管理页提供「批量上传」:一次选多个视频 → 队列分片上传 → 每个文件独立进度 → 失败可重试 → 刷新/重进页面能续传 → 上传完成后批量创建分集。

A. 上传队列(新建 src/views/contentManagement/upload/useUploadQueue.ts)

  1. 输入:File[] + dramaId + 可选 bizType
  2. 每项状态机:waiting → uploading → merging → done / failed / paused;对外暴露 items、overallPercent、 start()、pause()、retry(id)、retryAll()、remove(id)、clear()
  3. 队列并发:同时最多 2 个文件上传(文件内分片并发沿用 uploadFile 的 3)
  4. 进度:文件内 onProgress 回调更新单项百分比;总进度 = 各文件字节加权,不是简单平均
  5. 失败隔离:单文件失败不影响其它文件,错误原因记在该项 error
  6. 暂停语义(本轮简化,不做 abort):暂停后不再派发新任务,已在传的分片让其完成
  7. 上传完成后 completeUploadApi 拿到 assetId/url/durationSec 写回该项

B. 断点续传(关键)

  1. 上传开始(拿到 uploadId)即写入 localStorage:键 reel_upload_sessions, 值数组项含 { uploadId, fileName, fileSize, lastModified, dramaId, bizType, createdAt }
  2. 页面进入时读取该键,过滤 dramaId 匹配且 24 小时内的会话,弹出提示「发现 N 个未完成上传,是否续传」
  3. 续传前用 file.name + size + lastModified 匹配本地重新选择的文件; 文件匹配不上(换机器/改名)则不自动续传,提示后由用户手动重选
  4. 续传走现有 resumeUpload(file, uploadId);GET /admin/media/upload/{uploadId} 返回 404 或已 completed 的会话要从 localStorage 清理
  5. 上传成功、用户移除、用户放弃续传三种情况都要清理对应记录

C. 批量创建分集

  1. 上传完成列表提供「批量创建分集」按钮
  2. 默认值:按文件名自然排序(去扩展名后再比较,第2集 排在 第10集 之前); 集号 = 该剧当前最大集号 + 1 起顺延;标题取文件名去扩展名;是否免费沿用现有新建默认值
  3. 弹窗内每行可改:集号、标题、是否免费;冲突集号在提交前本地校验并标红
  4. 提交:逐条调用现有 createEpisodeApi(src/api/admin/episode.ts), 逐条显示成功/失败,失败的保留在弹窗内可重试;全部结束后刷新剧集列表
  5. 不新增后端接口,契约不动

D. 组件拆分(红线:单文件 ≤ 500 行)

  • src/views/contentManagement/upload/BatchUploadDialog.vue:多选、队列列表、总进度、暂停/重试/移除
  • src/views/contentManagement/upload/UploadTaskRow.vue:单行(文件名、大小、进度条、状态、操作)
  • src/views/contentManagement/upload/CreateEpisodesDialog.vue:批量建分集表单
  • src/views/contentManagement/upload/useUploadQueue.ts:队列逻辑(纯逻辑单元,不写 UI)
  • EpisodeManagementView.vue 只加一个「批量上传」入口按钮,并保持原单文件上传入口可用

E. 细节要求

  • 文件类型白名单:mp4/mov/mkv/webm(accept="video/*" + before-upload 二次校验)
  • 单文件大小上限从现有常量取值,超限直接标红不入队
  • 所有文案走 src/locales/zh-CN.ts / en.ts,禁止硬编码中文
  • 进度与错误展示用项目现有样式变量,不新引入 UI 依赖
  • 上传期间:关闭页面前用 beforeunload 提示存在未完成上传

F. 门禁

  • pnpm lint:eslint 零错误
  • pnpm build:dev 构建成功
  • 手工验证(PM 会复核):本地起 8080 + 3005,多选 3 个视频 → 三条并行进度 → 中途暂停 → 刷新页面 → 出现续传提示 → 续传完成 → 批量建分集成功

Git

  • ReelShortWeb:从 develop 拉 feature/episode-batch-upload → 提交 feat(admin): 剧集多选分片上传与断点续传 → --no-ff 合回 develop 并 push
  • 作者 Zhou Weidong <502333560@qq.com>;禁止 git add -A;源码首行 // Author: fruit.com.cn

约束

  • 先写计划 docs/plans/2026-10-21-K100-episode-batch-upload.md,再改代码
  • 每跑一个命令,把「命令 + 原始输出 + 解读」追加到 docs/plans/PROGRESS.md
  • 不改 FruitServer、不改 ReelShort 客户端、不改接口契约
  • 禁止 git add -A;不要操作真机
  • 完成后停住等 PM 验收,回执需贴门禁原始输出