学 MP 文件管理:鼠标悬停或键盘焦点所在行在行尾浮出 2–3 个图标按钮(未入库视频 / 目录:整理、识别、刮削;已入库:打开作品、刷新元数据、重命名;其余:重命名、移动到),带 tooltip 与 aria-label,被状态阻止的灰显写原因;浮出时让出修改时间列;焦点行可 Tab 进入、Esc 回列表;窄屏仍只用 ⋯ 菜单。 面包屑前加「下载目录 / 媒体库」说明段。顺带修正 Shift+F10 菜单定位按行键找行时被 CSS.escape 改坏的问题。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
26 KiB
文件管理 v2(对照 MP 逐功能 + 按我们的逻辑重整前端)
基础:
06-file-manager-spec(已删除,见 gitceb66f8)(下称"规格 06",后端 17 个/files端点已实现);行为账本docs/porting/moviepilot-filemanager.md(痛点 P1–P12)。 上游:MoviePilot-Frontend17b9d51——views/reorganize/FileBrowserView.vue、components/filebrowser/{FileBrowser,FileToolbar,FileNavigator,FileList}.vue、components/dialog/{ReorganizeDialog,FileRenameDialog,ScrapeDialog,MediaInfoDialog,FileNewFolderDialog,ProgressDialog}.vue、cards/MediaInfoCard.vue、cards/DirectoryCard.vue(覆盖模式)、locales/zh-CN.ts。只参考行为,不抄源码/模板/文案(GPLv3)。 本文只改前端信息架构与交互,加少量后端缺口(§15)。IA-3 已取消"身份与元数据"页,这直接影响整理向导(§6.1)。
0. 结论
- MP 文件管理共 52 个功能点(§2)。我们已有 37 个(一致 7、更好 10、做法不同 20),缺 12 个(v2 补 8、不做 4),另 3 个不适用(网盘存储、多数据源、类型/类别分目录开关)。
- 缺口集中在整理对话框和周边:最小体积、覆盖策略、目标目录、TMDB 候选就地建作品、整理后刷新元数据、已有整理记录提示/重新整理、批量刮削、模板推荐名、hover 行内操作、上一级按钮、目录树折叠;预览缺统计和"只看问题"。
- 布局定稿:桌面左树右表(树可折叠)+ 右侧详情抽屉;移动端单栏 + 面包屑 + 底部操作栏。整理只保留一个向导,下载详情和整理记录都用它(去掉
downloads/organize-dialog.tsx)。 - 拆分:契约 0.5 d → 后端 2.5 d / 前端 5 d 并行 → 测试截图 1 d,合计约 9 人日(§16)。
1. 现状盘点(代码 + qa-v02 截图)
已实现:routes/console/files.tsx(911 行)、files.trash.tsx、components/files/*(DirTree、PathBreadcrumb、ContextMenu、FileList 分页+长按多选、FileDetail、dialogs、4 步 OrganizeWizard)。后端 modules/file-manager/* 覆盖 roots/list/stat/mkdir/rename/move/copy/organize/delete/trash/identify/scrape/probe/records/download。
截图暴露的问题:
- 名称列太窄(60/61):文件名截到 25 字符;"季集"列对未登记文件恒空,"状态"列留白过宽。
- 右键菜单 13 项(61):"刮削/打开作品/在整理记录中查看"对未登记文件只是灰显 + 副标题,菜单高过半屏。
- 向导第 1 步是卡片(66-1):每项约 130 px,6 个文件要滚两屏;"应用到同目录 3 项"每张卡都重复一次。
- 向导第 2 步只有"动作 + 目标库根"(66-2),MP 对话框里的最小体积、覆盖、目标目录、命名说明都没有。
- 预览(66-3)只有前后路径,没有总数/问题数,也不能只看问题。
- 远端候选(只在 TMDB 上的作品)提示"先在身份与元数据建立作品",但这个页已取消,这条路断了。
- 下载详情另有一个"手动整理"对话框(45):字段、预览样式和文件管理的向导都不一样。
- 移动端(ia1/files.mobile):页头说明文字 + 回收站按钮 + 三行工具栏,首屏只剩一半给列表。
- 前端没接
/files/records;推荐名是前端拼的标题 (年份),没走命名模板。
2. MP 功能 → 我们现状 → v2 决定
状态:✓ 有 / ✓+ 有且更好 / ≠ 有但不同 / ✗ 无。决定:照抄 / 改(按我们逻辑)/ 不做。
| # | MP 功能点 | 我们 | v2 决定 |
|---|---|---|---|
| 1 | 存储切换菜单(local/115/阿里/Alist/SMB/rclone) | ≠ 左栏按"媒体库/下载目录"列登记目录 | 改:登记目录 = 库根 + 下载器路径映射,不接网盘(REQ §7.1.1) |
| 2 | 初始位置 = 下载目录公共前缀,记住上次存储 | ≠ 默认第一个在线库根 | 改:上次位置(localStorage)> 第一个下载目录 > 第一个库根。整理从下载目录开始 |
| 3 | 面包屑(桌面全段,移动端只显示存储名) | ✓ 可拖放 | 照抄 + 移动端折叠成"…/父/当前" |
| 4 | "上一级"按钮 | ✗ 只有 Backspace | 照抄:工具栏加"上一级" |
| 5 | 目录树懒加载、跟随当前路径展开 | ✓ | 保留 |
| 6 | 目录树显示/隐藏开关 | ✗ | 照抄:左栏可折叠,状态存 localStorage |
| 7 | 可拖宽分隔条(存 localStorage) | ✓ | 保留 |
| 8 | 排序:名称/时间切换 | ✓+ 名称/时间/大小/状态 + 升降 | 保留 |
| 9 | 过滤框(子串 / *? glob) |
✓+ 服务端过滤 | 保留 |
| 10 | 过滤大小写开关 | ✗ | 不做:媒体文件名按不区分大小写匹配就够 |
| 11 | 刷新 | ✓ | 保留 + SSE 自动刷新 |
| 12 | 新建文件夹(工具栏 + PWA 悬浮按钮) | ✓ 只读目录禁用 | 保留;移动端放进"更多" |
| 13 | 虚拟滚动全量列表 | ✓+ 游标分页 + 截断提示 | 保留 |
| 14 | 图标按扩展名映射 | ≠ 按 fileKind | 保留 fileKind(视频/字幕/NFO/图片/音频/其他) |
| 15 | 行 = 名称 + 大小副行 | ≠ 多列 | 改:名称副行放作品·季集,删"季集"列(§4.2) |
| 16 | 桌面 hover 出 5 个行内按钮 | ✗ 只有 ⋯ | 改:hover 出 2 个主操作 + ⋯(§5.1) |
| 17 | 移动端 ⋮ 菜单 | ✓ | 保留 |
| 18 | 选择模式开关(默认无复选框) | ≠ 常驻复选框 | 保留常驻(桌面);移动端长按进入 |
| 19 | 批量:刮削 / 整理 / 删除 | ≠ 整理/移动/复制/探测/删除 | 改:加批量刮削(按作品去重) |
| 20 | 点文件进"文件视图"(缩略图/大小/时间/识别/下载) | ✓+ 详情抽屉(资产/下载任务/绑定/媒体信息) | 保留抽屉,加"整理记录"节 |
| 21 | 图片大图预览 | ✓ | 保留 |
| 22 | 下载任意文件 | ≠ 仅非媒体 ≤ 20 MB | 保留限制:视频不经浏览器 |
| 23 | 空态:过滤无结果 / 空目录 | ✓+ 另有离线 / 截断 / 无权限 | 保留 |
| 24 | 进度弹窗(识别/删除/刮削/递归改名,SSE) | ≠ toast + 后台任务 | 保留我们的:长操作不阻塞页面 |
| 25 | 识别 → 单结果只读媒体卡(海报/标题/季集/年份/简介/类型/类别/TMDB ID/来源/版本/分辨率/编码/制作组/原始串/识别词) | ≠ 识别直接进向导 | 改:单项 → 识别卡片(解析 + Top5 候选),多项 → 向导(§7.1) |
| 26 | 刮削对话框(类型/数据源/媒体 ID + 搜索) | ≠ 仅已登记作品,字段级刷新 | 改:未登记不显示刮削;NFO 投影实现前不显示 NFO 选项(§7.2) |
| 27 | 批量刮削(逐个串行,失败汇总) | ✗ | 改:按作品去重后逐个提交 |
| 28 | 重命名 + "自动识别名称" | ≠ 前端拼建议名 | 改:推荐名走命名模板(§8) |
| 29 | 递归重命名目录内媒体(一个失败即中止) | ✗ | 改:放进向导"原地按模板改名"模式,先预览(阶段 3) |
| 30 | 删除确认"是否确认删除{name}?" | ✓+ 回收站 + 引用检查 | 保留 |
| 31 | 新建目录对话框 | ✓+ 名称校验 | 保留 |
| 32 | 整理:目的存储 | — | 不做:只有本机路径 |
| 33 | 整理方式 copy/move/link/softlink | ≠ 复制/移动 | 保留两项;硬链接灰显"W5" |
| 34 | 目的路径(自动 / 目录配置下拉 / 手输) | ≠ 目标库根(契约有 targetDir,界面没有) | 改:自动 / 指定库根 / 指定目录(§6.2) |
| 35 | 按源路径推荐目标(/manual/target-path) |
≠ 按作品绑定或类型 | 保留我们的:已绑定作品沿用原目录 |
| 36 | 媒体类型(自动/电影/剧集/音乐) | ≠ 由作品决定 | 不单列:作品选择器按类型过滤 |
| 37 | 数据源(TMDB/豆瓣/Bangumi/…) | — | 不做:本地作品 + TMDB |
| 38 | 媒体 ID + 名称搜索选择器 | ≠ 只能选本地作品 | 改:搜本地 + TMDB,选 TMDB 就地建作品(G1) |
| 39 | 剧集组 | ✗ | 不做:季集以本地内容单元为准 |
| 40 | 季 | ✓+ 逐项 | 保留 |
| 41 | 集(如 1 或 1,2) | ✓+ 逐项,支持 3-5 | 保留 |
| 42 | 集数定位 {ep} 模板 + 智能生成 |
✗ | 不做:解析器 + 逐项改集号覆盖同一需求 |
| 43 | 集数偏移(-10 / EP*2) | ≠ 仅正整数 | 改:支持正负整数;不做乘法 |
| 44 | 指定 Part | ✗ | 不做(命名模板 part 变量来自解析) |
| 45 | 最小文件大小(MB) | ✗ | 照抄:识别步骤按体积排除(G2) |
| 46 | 按类型/按类别分目录 | — | 不做开关:目录结构由命名模板决定 |
| 47 | 整理后刮削 | ✗ | 改:"入库后刷新元数据",默认开(G5) |
| 48 | 覆盖模式(从不/总是/按大小/仅保留最新,在目录配置) | ≠ 恒不覆盖 → 冲突进待处理 | 改:向导内三选一(§6.2,G3) |
| 49 | 检测到已有整理记录 → 重新整理(清旧目标) | ✗ | 改:识别步标"已登记/有 n 条记录";整理记录页"重新整理"开同一向导 |
| 50 | 预览:总/成功/失败统计、媒体信息、识别词详情、前后对照、分页 20 | ≠ 按作品分组前后对照 | 改:加统计条 + "只看问题" + 目标路径分段着色(§6.3) |
| 51 | "加入整理队列"(后台)与"立即整理"两个按钮 | ≠ 一律后台任务 | 保留一个"执行";执行后可关向导,列表自动刷新 |
| 52 | 键盘/拖拽/右键/隐藏文件开关 | ✓+ MP 全无 | 保留 |
3. 信息架构
- 位置:侧栏"整理"组(下载面板 / 整理记录 / 文件管理 / 媒体概览),路由
/console/files、/console/files/trash不变。 - 可浏览范围只有登记目录:库根(可写或只读登记)+ 下载器路径映射。根
/永不出现。 - 每行状态来自本地账本(资产位置、下载任务、临时文件规则),不需要逐个点识别:已登记 / 下载中 n% / 做种中(H&R 未满足)/ 临时文件 / 待识别 / 链接越界。
- 与其他页的关系:
从 到文件管理 从文件管理出去 下载面板任务详情 "整理"打开同一向导;"在文件管理中打开"定位到内容路径 状态徽标"下载中"→ 任务详情 整理记录 失败/重名拦截行"重新整理"打开向导(源路径按登记目录 hostPath 换算成 FileRef) 详情抽屉"整理记录"节 → 记录详情 媒体概览作品详情 资产位置"在文件管理中打开" 已登记行 → 作品详情 待处理 冲突事项"查看文件" 整理冲突进待处理
4. 页面布局定稿
4.1 桌面(≥ md):左树右表 + 详情抽屉
理由:① 库目录层级深(作品/季/文件),树 + 面包屑两种跳法都要;② 拖放移动需要常驻目标(树节点);③ MP 用户已习惯这个布局。单栏在窄屏用。
┌ PageHeader:文件管理 [回收站 n] ┐ ← 说明文字删掉,回收站带条数
├ 左栏 260px(可折叠/拖宽) ┬ 工具栏行 1:[⇤树] [↑上一级] 面包屑…… [刷新][新建目录]
│ 下载目录 │ 工具栏行 2:搜索 | 全部 视频 待识别 已登记 下载中 临时 | 排序 ⇅ 隐藏文件
│ qB · 待识别 12 ├──────────────────────────────────────────────
│ 媒体库 │ ☐ 名称(副行) 状态 大小 修改时间 [hover 操作]
│ 电影库 剩余 1.1 TB │ …虚拟列表…
│ └ 目录树 ├ 状态栏:15/15 项 · 已选 1 · 400 MB 剩余 1.1 TB 只读
│ 回收站 │ [浮动批量栏]
└──────────────────────────┴──────────────────────────────────────────────
- 左栏顺序改为下载目录在前(整理从下载开始),每个登记目录显示健康点 + 剩余空间;下载目录额外显示"待识别 n"(G6,可选)。
- 左栏折叠后只剩 44 px 图标条(登记目录图标 + 回收站)。
- 详情抽屉(
DetailSheet,右侧)不改布局,新增"整理记录"节。
4.2 列表列
| 列 | 内容 |
|---|---|
| ☐ | 复选框;Shift 区间选 |
| 名称 | 主行文件名(truncate,hover 显示全名);副行:已登记 → 作品 (年) · S01E02 · 版本目标;待识别 → 解析结果灰字 The Last of Us · S01E01 · 1080p(来自列表时服务端的轻量解析,G7);目录 → 13 视频 · 0 已登记 |
| 状态 | StatusBadge + 文字,固定 120 px |
| 大小 | 文件大小;目录空 |
| 修改时间 | 相对时间,≥ lg 显示 |
| 操作 | hover/聚焦显示(§5.1) |
删除独立的"季集"列,把宽度让给名称(名称列最小 40%)。
5. 操作
5.1 行内 hover 操作(桌面)
鼠标悬停或键盘焦点所在行(Tab 进入按钮,Esc 回列表),在行尾浮出 2–3 个图标按钮(带 tooltip 与 aria-label,盖在修改时间列上),其余留在 ⋯:未入库视频/目录 → 整理 识别 刮削;已入库 → 打开作品 刷新元数据 重命名;未完成的视频 → 识别 重命名 移动到;其他 → 重命名 移动到。窄屏卡片不依赖悬停,只用 ⋯。
面包屑照 MP「本地 > MEDIA > 亚洲剧集」:下载目录 / 媒体库(说明,不可点)> 登记目录 > 各级子目录;窄屏去掉类型并折叠。
5.2 右键 / ⋯ 菜单(单项,最终顺序)
- 打开 / 详情
Enter - ── 整理…(主操作,未登记视频或目录) · 识别 · 重命名
F2· 移动到… · 复制到… - ── 刷新元数据(仅已登记) · 探测(仅视频)
- ── 复制路径… · 打开作品(仅已登记) · 查看整理记录(仅有记录)
- ── 删除
Del
规则:不适用的项隐藏(未登记文件不出现刮削/打开作品/整理记录);被状态阻止的项灰显并在 tooltip 写原因("做种中,H&R 满足前不能改名")。单项菜单最多 11 项、常见 8 项。
多选菜单:整理 n 项… · 识别 · 移动到… · 复制到… · 探测 · 刷新元数据(按作品去重,仅含已登记时)· 删除 n 项。
5.3 浮动批量栏
已选 n · 大小 | 整理 | 移动 | 复制 | 更多(探测 / 刷新元数据 / 复制路径)| 删除 | ✕。任何按钮被阻止时灰显,tooltip 写第一条原因和涉及项数。
5.4 工具栏
⇤ 折叠树 · ↑ 上一级 · 面包屑 · 刷新 · 新建目录;第二行搜索、筛选 chips、排序 + 升降、隐藏文件开关。截断时在列表顶出黄条"目录过大,只读了前 20 000 项。用搜索或进入子目录"。
6. 整理向导重做
唯一入口组件 OrganizeWizard;来源三种:文件管理选中项、下载任务(内容路径)、整理记录(源路径)。Sheet 全高,3 步:① 文件与作品 → ② 选项 → ③ 预览并执行(原第 4 步"执行"并入 ③:执行后在原地显示每组结果)。
6.1 ① 文件与作品(表格,不再用卡片)
- 顶部批量条:
应用作品到选中(作品选择器)·季·集号偏移 ±N·最小体积 [100] MB(低于的项自动排除并计数,默认取设置"整理默认")· 统计n 个视频 · m 项待定 · k 项已排除。 - 表格按源目录分组,组头一行:目录名 +
应用到本组(把组内第一项作品复制到全组)。 - 行列:☐ | 源文件(主行文件名,副行解析:标题·年·季集·分辨率·来源·组)| 作品(选择器)| 季 | 集 | 版本目标(默认自动)| 标记。
- 标记:
已登记(existing.assetId,再整理会改路径)、有 n 条整理记录(接/files/records,对应 MP"检测到成功整理记录")、做种中·H&R 未满足(本行只能复制)。 - 作品选择器:上半本地作品(识别候选 Top5,带等级高/中/低和理由),下半"TMDB 候选"。选 TMDB 候选 → 行标"将新建作品",执行时由后端建作品(G1),不再跳去已取消的身份页。
- 未决项(无作品 / 集号格式错 / 剧集缺季)整行黄底,必须处理或排除才能下一步。
6.2 ② 选项(MP 手动整理字段的映射)
| MP 字段 | 我们的字段 | 取值与默认 |
|---|---|---|
| 整理方式 | 整理方式 | 复制(默认,保留源文件,不影响做种)/ 移动(跨卷按复制→核验→删源;含 H&R 未满足项时禁用并写原因)/ 硬链接(灰显,W5) |
| 目的存储 + 目的路径 | 目标 | 自动(默认:已绑定作品沿用原目录,否则按作品类型选库根)/ 指定库根(列可写库根 + 剩余空间)/ 指定目录(目录树选择器,写入 targetDir,不建路径绑定) |
| 覆盖模式 | 目标已存在 | 跳过 / 交给待处理(默认)/ 按版本目标替换(新文件更好才替换,旧文件进回收站,G3) |
| 智能重命名 + 类型/类别分目录 | 命名 | 只读说明:按命名模板(来源:作品覆盖 / 库根 / 全局)+"去设置"链接;另一选项"保留原文件名"(G4)。不提供临时模板,避免同一作品两套目录 |
| 季 / 集 / 集数偏移 | 在 ① 逐项设置 | — |
| 最小文件大小 | 在 ① 批量条 | — |
| 刮削元数据 | 入库后刷新元数据 | 默认开;字段级刷新,锁定字段不变(G5)。NFO/图片投影实现后再加"写 NFO" |
| (MP 自动带字幕) | 附属文件 | 只读:同名字幕/NFO/图片随主文件一起处理(planImport 已支持),在 ③ 列出 |
| 类型 / 数据源 / 剧集组 / 集数定位 / Part / 复用历史识别 | — | 不做,理由见 §2 |
6.3 ③ 预览并执行
- 统计条
n 组 · m 个文件 · 可执行 x · 冲突 y · 失败 z+ 开关只看问题;按作品分组的卡片:组头 = 作品 + 状态(计划就绪 / 不能执行 + 原因)+ 文件数与总大小 + 整理方式;目标目录显示一次,段着色:作品根 / 季 / 文件名,已绑定段加标签沿用绑定。 - 文件行:源(灰,只显示相对登记目录的路径)→ 目标(只显示文件名差异);附属文件缩进列在主文件下。
- 组数 > 20 时分页(每页 20 组,对应 MP 预览分页)。
- 底栏:
返回修改·执行 n 组。执行后原地替换为每组结果(已提交 / 失败 + 原因),按钮变查看整理记录(跳/console/organize?ids=)和完成。plan_stale 的组自动重新预览并提示"源文件在预览后有变化,已重新预览"。
6.4 移动端向导
全屏 Sheet;① 改为每项一张紧凑卡(文件名 + 作品 + 季/集一行),批量条收进"批量设置"折叠;②③ 单列。
7. 识别与刮削
7.1 识别
- 单项:详情抽屉里的"识别"节(不另开弹窗):解析字段表(标题/年份/季集/分辨率/来源/发布组/类型)+ Top5 候选列表(海报缩略图 G8、标题年份、等级、理由),每个候选一个按钮
按此整理(打开向导并预填)。TMDB 不可用时显示 warnings 原文。 - 多项:直接进向导 ①。
- 识别只读,不写库(规格 06 §2.3.4 不变)。
7.2 刮削 → 界面叫"刷新元数据"
- 只对已登记项出现;多选时按作品去重,提交 n 个作品,toast 汇总"已提交 n 个作品,锁定字段不变"。
- 对话框:说明一句"按字段刷新,锁定的字段和路径不变" + 锁定字段列表(来自响应)+
刷新。NFO/图片两项在后端返回not_implemented期间不显示(文案规则 8)。 - 未登记文件:不出现该项;引导走"整理"。
8. 重命名
- 对话框字段:新名称(默认选中主名不含扩展名)、
按模板生成按钮、附属文件对照表(同名字幕/NFO/图片,默认一起改)、已登记/绑定目录的后果说明。 按模板生成:调 G9(命名引擎按当前绑定与模板渲染),返回文件名或目录段;识别不可信时按钮旁提示"识别不可信,没有推荐名"。不再用前端拼接的suggestName。- 目标名已存在:输入框下即时报"同名已存在,不会覆盖"(用当前列表判断,服务端仍 409)。
- 做种中:菜单灰显,不进对话框。
- 目录内批量按模板改名:阶段 3 做成向导模式"原地改名"(目标 = 当前目录,只预览改名对),替代 MP 的递归重命名。
9. 预览与下载
- 图片(jpg/png/webp/gif):抽屉内缩略图,点开新窗口原图。文本(NFO/字幕/txt):抽屉内等宽预览,最多读前 256 KB,超出显示"只显示前 256 KB"。
- 视频:不做播放器;显示探测摘要(分辨率/HDR/编码/音轨/字幕轨/时长/容器),未登记文件需点"探测"。
- 下载:仅非媒体 ≤ 20 MB,按钮
下载。
10. 回收站
- 左栏底部入口 + 页头按钮都显示条数(
回收站 3);页内列:名称 · 原位置(可点回到目录)· 删除时间 · 到期 · 关联资产(已退役作品链接)· 操作(还原/还原到…)。 - 批量还原;
清空回收站仅管理员会话,需输入"清空"确认。 - 原位置被占用:行内报错"原位置已被占用",按钮变
还原到…。
11. 键盘与拖拽
沿用现有:↑↓ Enter Backspace Space Shift 区间 Ctrl/⌘+A F2 Del / Esc。新增:Alt+↑ 上一级、Ctrl/⌘+Enter 对选中项打开整理向导、? 显示快捷键浮层。拖放不变:拖到树节点/面包屑段/列表中的目录 = 移动到(Alt 复制),松手先出预览,不直接执行;只接受可写库根。
12. 移动端(< md)
- 页头只留标题,回收站进"更多"。工具栏一行:
[目录](左侧 Sheet:登记目录 + 树)· 面包屑"…/父/当前" ·[搜索](点开展开为整行输入)·[更多](排序、升降、隐藏文件、新建目录、回收站)。筛选 chips 第二行横滑。 - 列表单列卡片:名称 + 状态徽标 + 副行;点击打开/详情,长按进入多选;多选底栏:整理 · 移动 · 删除 · 更多;详情用底部 Sheet。
13. 文案(按 glossary)
| 现在 | 改为 | 理由 |
|---|---|---|
| 根与目录 / 只读根不能新建目录 | 目录 / 只读目录,不能新建 | glossary:可浏览目录叫"登记目录",不叫"根" |
| 整理到… / 整理 n 项… | 整理… / 整理 n 项 | 与批量栏一致 |
| 在整理记录中查看 | 查看整理记录 | 按钮 ≤ 6 字 |
| 刮削 | 刷新元数据 | 与作品详情同名;MP 用户看到 tooltip"即 MP 的刮削" |
| 链接逃逸 | 链接越界 | 用户能懂 |
| 页头说明"已登记的库根与下载目录。删除先进回收站,改名同步更新资产。" | 删除 | 事实已在状态栏和删除对话框里说 |
| 空目录描述"隐藏文件未显示。" | "隐藏文件未显示"只在目录里确有点文件时出现 | 不写无依据的话 |
向导按钮:下一步 生成预览 返回修改 执行 n 组 查看整理记录 完成;对话框确认:移入回收站 永久删除 重命名 刷新 还原 还原到…。
14. 组件复用与新建
复用:PageHeader、DataTable(向导 ① 用 dense 分组模式,缺分组行就给 DataTable 加 groupBy,不另造表格)、FilterBar(工具栏第二行改用它承载搜索 + chips + 排序)、DetailSheet、ConfirmDialog、StatusBadge、EmptyState、KvList、Timeline(抽屉整理记录节)。
保留并收拢到 components/files/:DirTree、PathBreadcrumb、ContextMenu、FileList、FileDetail。
新建:
| 组件 | 用途 |
|---|---|
EntityPicker |
本地作品 + TMDB 候选两段搜索选择;向导、识别卡片、下载任务共用 |
IdentifyPanel |
抽屉"识别"节:解析表 + 候选 + 按此整理 |
PathSegments |
目标路径分段着色 + 沿用绑定 标签;向导预览与重命名共用 |
DirPicker |
基于 DirTree 的目录选择器(只列可写库根);移动/复制/向导"指定目录"共用 |
WizardBulkBar |
向导 ① 批量条(作品/季/偏移/最小体积) |
删除:components/downloads/organize-dialog.tsx(下载详情与整理记录页改开 OrganizeWizard,sources 传下载任务内容路径或记录源路径)。model.ts 的 suggestName 删除。
15. 后端缺口
| # | 缺口 | 说明 | 必需 |
|---|---|---|---|
| G1 | 整理项接受外部候选 | FilesOrganizeItem 加 external?: {provider:"tmdb", externalId, kind}(与 mediaEntityId 二选一);dryRun 标"将新建作品",执行时在同一事务建 media_entity + 外部身份(复用 identity-pool assign 的建实体逻辑) |
是(身份页已取消) |
| G2 | 识别按体积过滤 | FilesIdentifyRequest 加 minSizeBytes;FileIdentifyItem 加 size、excludedBySize 计数 |
是 |
| G3 | 目标已存在策略 | FilesOrganizeRequest 加 onConflict: "skip"|"decision"|"replace_if_better";替换走现有 replace_with_verify,旧文件进回收站 |
是 |
| G4 | 命名方式 + 来源 | 请求加 naming: "template"|"keep";响应每组加 templateSource: "entity"|"root"|"global" 与目标路径 segments:[{text, role, bound}] |
是 |
| G5 | 入库后刷新元数据 | 请求加 refreshMetadata: boolean,执行成功后对每个作品排一次 refresh run |
否(前端可在完成后调 /files/scrape) |
| G6 | 下载目录待识别计数 | FileRoot 加 pendingCount(缓存 5 分钟) |
否(C1-C 已做,另有 pendingPartial) |
| G7 | 列表轻量解析 | 待识别视频的 entry 加 parsedHint(标题·季集·分辨率,纯字符串解析,不查库) |
否(C1-C 已做) |
| G8 | 候选海报 | FileIdentifyCandidate 加 posterUrl |
否(C1-C 已做) |
| G9 | 推荐名 | POST /files/suggest-name {root,path} → 命名引擎渲染(依赖 naming-template.md §8 的引擎);不可信时返回 null + 原因 |
是(依赖命名引擎) |
16. 实施拆分与估算
| 路 | 范围 | 估计 |
|---|---|---|
| 0 契约 | G1–G4、G9 的 schema + api 注册 | 0.5 d |
| B1 后端 | G1(建实体 + 事务)、G2、G3、G4;测试:外部候选 dryRun/执行、onConflict 三态、keep 命名、segments | 2 d |
| B2 后端 | G9(命名引擎就绪后接入)、G5–G8 可选项 | 0.5 d |
| F1 页面 | 左栏重排与折叠、上一级、列表列重排与副行、hover 操作、菜单隐藏规则、批量栏"更多"、移动端工具栏与页头、文案表 | 1.5 d |
| F2 向导 | 3 步重构、表格化 ①(DataTable groupBy)、EntityPicker、WizardBulkBar、② 选项表、③ 统计/只看问题/PathSegments/原地结果;下载详情与整理记录"重新整理"改用向导;删旧对话框 | 2.5 d |
| F3 周边 | IdentifyPanel、重命名按模板、刷新元数据(批量去重、隐藏 NFO)、抽屉整理记录节、文本预览上限、回收站条数与批量还原、快捷键浮层 | 1 d |
| T 验收 | model/向导单测;e2e:下载目录散文件 → 选 TMDB 候选 → 预览 → 执行 → 整理记录出现 → 行变"已登记";桌面/移动截图各 8 张 | 1 d |
顺序:0 → (B1 ∥ F1) → F2(先用 mock 接 G1–G4)→ F3 → B2 → T。合计约 9 人日;F1 不依赖后端,可立刻开工。