feat(web): 记录抽屉与两层导航标准

控制台导航最多两层(侧栏一项 = 一页,页内最多一层页签 / 分段);从列表打开的
记录改成列表页上的右侧抽屉,打开的记录写在 ?open=,刷新、分享、前进后退都能还原,
后退就是关抽屉。标准写在 docs/design/console-ia.md §9,ui-controls.md 引用。

- DetailSheet 加 xl 宽度、标题下操作行;抽屉里再开的 DetailSheet 在同一抽屉里换成子视图(返回 / Esc)
- record-sheet.tsx:useRecordSheet / RecordLink / useOpenRecord / recordPath / taskPath
- 整理记录、订阅、站点(含页签)、下载、日志任务改成抽屉;旧业务任务 / 下载任务 id 在任务抽屉里换算
- 回收站并进文件管理右侧视图(?view=trash);设置左栏只列分区
- 规则组、策略版本、媒体库未识别 / 外部身份、设置实例编辑走 ?open=
- 旧地址 /console/{organize,subscriptions,sites,downloads}/:id、/tasks/:id、/files/trash 跳到列表页抽屉
- 站内链接、铃铛、命令面板、任务时间线改拼新地址;冒烟按 ?open= 检查抽屉

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-08 14:03:47 +08:00
1 parent dd0f6e2c09
commit 21c55dfb3a
60 files changed
+2768 -2461

No files matched your search

+32 -15
View File
@@ -34,7 +34,7 @@ const STATIC_ROUTES = [
"/console/files?f=video&sort=size&order=desc&hidden=1",
"/console/files?mock=1",
"/console/files?mock=0",
"/console/files/trash",
"/console/files?view=trash",
"/console/subscriptions",
"/console/subscriptions?group=pending&sort=missing",
"/console/rules",
@@ -83,20 +83,20 @@ const STATIC_ROUTES = [
"/console/settings#account",
];
// 记录抽屉(docs/design/console-ia.md §9):列表里打开的记录是列表页上的抽屉(?open=);带 ?open= / ?run= 的地址要看到抽屉
const DETAIL_ROUTES = [
{ route: "/console/library/:id", list: "/api/v1/library" },
{ route: "/console/organize/:id", list: "/api/v1/organization-records" },
{ route: "/console/sites/:id", list: "/api/v1/sites" },
{ route: "/console/sites/:id", list: "/api/v1/sites", after: "?tab=resources" },
{ route: "/console/organize?open=:id", list: "/api/v1/organization-records" },
{ route: "/console/sites?open=:id", list: "/api/v1/sites" },
{ route: "/console/sites?open=:id", list: "/api/v1/sites", after: "&tab=resources" },
// 旧页签"整理视图"落到"资源"
{ route: "/console/sites/:id", list: "/api/v1/sites", after: "?tab=organized" },
{ route: "/console/sites/:id", list: "/api/v1/sites", after: "?tab=snapshots" },
{ route: "/console/sites/:id", list: "/api/v1/sites", after: "?tab=accounts" },
{ route: "/console/subscriptions/:id", list: "/api/v1/subscriptions" },
{ route: "/console/downloads/:id", list: "/api/v1/download-tasks" },
{ route: "/console/tasks/:id", list: "/api/v1/engine/runs" },
{ route: "/console/sites?open=:id", list: "/api/v1/sites", after: "&tab=organized" },
{ route: "/console/sites?open=:id", list: "/api/v1/sites", after: "&tab=snapshots" },
{ route: "/console/sites?open=:id", list: "/api/v1/sites", after: "&tab=accounts" },
{ route: "/console/subscriptions?open=:id", list: "/api/v1/subscriptions" },
{ route: "/console/downloads?open=:id", list: "/api/v1/download-tasks" },
{ route: "/console/tasks?run=:id", list: "/api/v1/engine/runs" },
{ route: "/console/logs?run=:id", list: "/api/v1/engine/runs" },
{ route: "/console/logs?type=task&run=:id", list: "/api/v1/engine/runs" },
{ route: "/console/agent/:id", list: "/api/v1/agent/runs", after: "?mock=0" },
];
@@ -114,9 +114,20 @@ const REDIRECT_ROUTES = [
{ from: "/console/preferences", to: "/console/rules" },
{ from: "/console/preferences?origin=agent_inferred", to: "/console/rules?origin=agent_inferred" },
{ from: "/console/sources?tab=snapshots", to: "/console/sites" },
{ from: "/console/sources?tab=snapshots&siteId=:id", to: "/console/sites/:id?tab=snapshots", list: "/api/v1/sites" },
// 旧的下载详情地址:先查业务任务(404 属预期),再跳到下载详情
{ from: "/console/tasks/:id", to: "/console/downloads/:id", list: "/api/v1/download-tasks", expect404: true },
{
from: "/console/sources?tab=snapshots&siteId=:id",
to: "/console/sites?open=:id&tab=snapshots",
list: "/api/v1/sites",
},
// 记录详情的旧地址 → 列表页抽屉(§9)
{ from: "/console/organize/:id", to: "/console/organize?open=:id", list: "/api/v1/organization-records" },
{ from: "/console/subscriptions/:id", to: "/console/subscriptions?open=:id", list: "/api/v1/subscriptions" },
{ from: "/console/sites/:id?tab=rss", to: "/console/sites?open=:id&tab=rss", list: "/api/v1/sites" },
{ from: "/console/downloads/:id", to: "/console/downloads?open=:id", list: "/api/v1/download-tasks" },
{ from: "/console/tasks/:id", to: "/console/logs?type=task&run=:id", list: "/api/v1/engine/runs" },
{ from: "/console/files/trash", to: "/console/files?view=trash" },
// 旧的下载详情地址 /console/tasks/<下载任务 id>:日志页抽屉先查引擎运行和业务任务(404 属预期),再换到下载面板抽屉
{ from: "/console/tasks/:id", to: "/console/downloads?open=:id", list: "/api/v1/download-tasks", expect404: true },
// 界面第二轮:任务 / 引擎面板 / 审计 / 计划并入日志页;身份与元数据并入媒体概览(IA-3)
{ from: "/console/tasks?tab=business", to: "/console/logs?type=task" },
{ from: "/console/tasks?tab=failed", to: "/console/logs?type=task&level=error" },
@@ -225,6 +236,12 @@ async function main() {
if (new URL(page.url()).pathname === "/login") problems.push("被重定向到登录页");
const notFound = await page.locator("text=页面不存在").count();
if (notFound) problems.push("渲染成 404 页");
if (/[?&](open|run)=/.test(path))
await page
.locator('[data-slot="sheet-content"]')
.first()
.waitFor({ timeout: 10_000 })
.catch(() => problems.push("没有打开记录抽屉"));
} catch (err) {
problems.push(`加载失败:${String(err?.message ?? err).split("\n")[0]}`);
}
@@ -422,7 +439,7 @@ async function main() {
});
try {
await page.goto("about:blank");
await page.goto(`${BASE}/console/sites/${encodeURIComponent(site.id)}?tab=origin`, {
await page.goto(`${BASE}/console/sites?open=${encodeURIComponent(site.id)}&tab=origin`, {
waitUntil: "domcontentloaded",
timeout: 30_000,
});