96 lines
5.9 KiB
Markdown
96 lines
5.9 KiB
Markdown
# 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 验收,回执需贴门禁原始输出
|