chore(web): 合并 U / V / W 后的收尾——剩余「入库」文案、设置新分区深链、冒烟锚点

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-06 18:25:20 +08:00
1 parent ee3ebcb25c
commit f397687a5f
11 files changed
+31 -36

No files matched your search

+1 -1
View File
@@ -110,7 +110,7 @@ const TASK_STATUS_TEXT: Record<string, string> = {
const TASK_KIND_LABEL: Partial<Record<TaskKind, string>> = {
submitDownload: "提交下载",
verifyAndImport: "核验入库",
verifyAndImport: "核验整理",
evaluateAcquisition: "评估候选",
cleanupDownloadCache: "清理缓存",
resolveDecision: "处理待处理事项",
+1 -1
View File
@@ -88,7 +88,7 @@ describe("控制台导航", () => {
});
it("settingsPath 只认新分区名", () => {
expect(settingsPath("automation", "cache")).toBe("/console/settings#automation/cache");
expect(settingsPath("downloaders", "cache")).toBe("/console/settings#downloaders/cache");
expect(settingsPath("agent")).toBe("/console/settings#agent");
});
});
+9 -6
View File
@@ -51,7 +51,7 @@ export const NAV_GROUPS: NavGroup[] = [
to: "/console",
label: "首页",
icon: House,
description: "在忙什么、要我处理什么、最近入库了什么",
description: "在忙什么、要我处理什么、最近整理了什么",
},
{
to: "/console/agent",
@@ -139,15 +139,18 @@ export const NAV_ITEMS = NAV_GROUPS.flatMap((g) => g.items);
/** 设置页深链(IA-2):`/console/settings#分区[/节]`。调用方只认新分区名 */
export type SettingsSection =
| "automation"
| "sites"
| "downloaders"
| "library"
| "media-servers"
| "sites"
| "metadata"
| "acquire"
| "library"
| "organize"
| "agent"
| "api-keys"
| "account";
| "system"
| "cache"
| "account"
| "interface";
export function settingsPath(section: SettingsSection, anchor?: string): string {
return `${CONSOLE_BASE}/settings#${section}${anchor ? `/${anchor}` : ""}`;
}
@@ -28,7 +28,7 @@ export const TASK_KIND_LABEL: Record<TaskKind, string> = {
resolveObservation: "识别资源",
evaluateAcquisition: "评估候选",
submitDownload: "提交下载",
verifyAndImport: "核验入库",
verifyAndImport: "核验整理",
refreshMetadata: "刷新元数据",
reconcileLibrary: "文件核对",
cleanupDownloadCache: "清理缓存",
@@ -246,7 +246,7 @@ export function BusinessTasks() {
empty={{
icon: ListTodo,
title: f.active ? "没有符合筛选的任务" : "还没有业务任务",
description: f.active ? undefined : "提交下载、核验入库、清理缓存、对账等后台任务会出现在这里。",
description: f.active ? undefined : "提交下载、核验整理、清理缓存、对账等后台任务会出现在这里。",
}}
/>
<DetailSheet
@@ -106,7 +106,7 @@ export function CacheVolumes() {
<h2 className="text-label font-semibold tracking-[0.18em] text-muted-foreground uppercase">下载盘</h2>
<div className="flex flex-wrap gap-2">
<Button asChild variant="ghost" size="sm">
<Link to={settingsPath("automation", "cache")}>
<Link to={settingsPath("downloaders", "cache")}>
<SlidersHorizontal />
调整阈值
</Link>
@@ -20,7 +20,7 @@ import { cn, formatBytes, formatDateTime } from "~/lib/utils.ts";
// 运行状态页「存储」节(FIX-5):GET /system/health 的存储告警 + GET /system/storage 明细(库体积与预算、表 top 10、
// 缓存用量、图片 / 备份 / 会话与证据、DATA_DIR 分目录、各清理任务),手动清理调 POST /system/storage/cleanup/{target}。
// 预算与保留期在「设置 → 自动化 → 存储与保留」改,见 docs/runbook/storage.md。
// 预算与保留期在「设置 → 系统 → 存储预算 / 数据保留」改,见 docs/runbook/storage.md。
const LEVEL: Record<HealthLevel, { label: string; tone: StatusTone }> = {
ok: { label: "正常", tone: "success" },
+1 -1
View File
@@ -36,7 +36,7 @@ export const WORKFLOW_LABEL: Record<string, string> = {
resolveObservation: "识别资源",
evaluateAcquisition: "评估候选",
submitDownload: "提交下载",
verifyAndImport: "核验入库",
verifyAndImport: "核验整理",
scrapeMedia: "刮削",
refreshMetadata: "刷新元数据",
reconcileLibrary: "文件核对",
+9 -9
View File
@@ -36,7 +36,7 @@ import { qk } from "~/lib/query-keys.ts";
import { useSse } from "~/lib/sse.ts";
import { cn } from "~/lib/utils.ts";
// 首页概览:自动化、存储与下载器状态,以及当前工作、要我处理的汇总计数(整理需要处理 / 等你批准 / 系统健康)和最近入库。
// 首页概览:自动化、存储与下载器状态,以及当前工作、要我处理的汇总计数(整理需要处理 / 等你批准 / 系统健康)和最近整理。
/** 首页关心的事件:任意一个到达就(节流)刷新聚合 */
const DASHBOARD_EVENTS = [
@@ -102,7 +102,7 @@ function Row({ children }: { children: ReactNode }) {
return <li className="flex min-w-0 items-center justify-between gap-3 py-1.5 text-sm">{children}</li>;
}
/** 非零项拼一句:[[3, "个下载"], [0, "个入库中"]] → "3 个下载" */
/** 非零项拼一句:[[3, "个下载"], [0, "个整理中"]] → "3 个下载" */
function nonZero(parts: [number, string][]): string {
return parts
.filter(([n]) => n > 0)
@@ -157,7 +157,7 @@ function StatusLine({ d }: { d: Dashboard }) {
) : a.readOnlyReconcile ? (
<>
只读模式:不会自动下载和整理。
<Link to={settingsPath("automation", "advanced")} className="underline underline-offset-4">
<Link to={settingsPath("system", "readonly")} className="underline underline-offset-4">
去设置关闭
</Link>
</>
@@ -211,7 +211,7 @@ function Busy({ w }: { w: Dashboard["currentWork"] }) {
const agents = w.agentRuns.slice(0, 2);
const summary = nonZero([
[w.downloading, "个下载中"],
[w.importing, "个入库中"],
[w.importing, "个整理中"],
[w.stalled, "个没有进展"],
[w.paused, "个已暂停"],
]);
@@ -275,14 +275,14 @@ function NeedsMe() {
);
}
// ─── 最近入库了什么:成功 / 部分成功的整理 ───
// ─── 最近整理了什么:成功 / 部分成功的整理 ───
function RecentImports({ d }: { d: Dashboard }) {
const rows = d.recentOutput.filter((r) => r.status === "succeeded" || r.status === "partial").slice(0, 6);
const today = d.automation.today.filesImported;
return (
<Section title="最近入库" icon={LibraryIcon} to={consolePath("organize")}>
<Section title="最近整理" icon={LibraryIcon} to={consolePath("organize")}>
{rows.length === 0 ? (
<EmptyState plain icon={LibraryIcon} title="最近没有新入库的作品" className="py-6" />
<EmptyState plain icon={LibraryIcon} title="最近没有新整理的作品" className="py-6" />
) : (
<ul className="divide-y divide-border/60">
{rows.map((r) => (
@@ -294,7 +294,7 @@ function RecentImports({ d }: { d: Dashboard }) {
<span className="block truncate">{r.title ?? r.targetPath?.split("/").pop() ?? "未关联作品"}</span>
{r.status === "partial" ? (
<span className="block text-meta text-warning">
{r.counts.succeeded}/{r.counts.total} 个文件入库
{r.counts.succeeded}/{r.counts.total} 个文件已整理
</span>
) : null}
</Link>
@@ -303,7 +303,7 @@ function RecentImports({ d }: { d: Dashboard }) {
))}
</ul>
)}
{today ? <p className="mt-auto pt-3 text-meta text-muted-foreground">今天入库 {today} 个文件</p> : null}
{today ? <p className="mt-auto pt-3 text-meta text-muted-foreground">今天整理 {today} 个文件</p> : null}
</Section>
);
}
+1 -1
View File
@@ -59,7 +59,7 @@ const OP_KIND: Record<AssetOperation["kind"], string> = {
delete_source: "删除源文件",
delete_target: "删除目标文件",
verify: "校验",
register: "登记入库",
register: "登记",
qb_pause: "暂停下载",
qb_resume: "恢复下载",
qb_remove: "移除下载",
+5 -3
View File
@@ -75,9 +75,11 @@ const STATIC_ROUTES = [
"/console/settings#media-servers",
"/console/settings#metadata",
"/console/settings#agent",
"/console/settings#api-keys",
"/console/settings#acquire",
"/console/settings#organize",
"/console/settings#system",
"/console/settings#cache",
"/console/settings#interface",
"/console/settings#automation/advanced",
"/console/settings#account",
];
@@ -128,7 +130,7 @@ const REDIRECT_ROUTES = [
{ from: "/console/identity?tab=external", to: "/console/library?view=identities" },
// 设置旧页签 ?tab= → 分区 hash(IA-2)
{ from: "/console/settings?tab=pi", to: "/console/settings#agent" },
{ from: "/console/settings?tab=storage", to: "/console/settings#automation/cache" },
{ from: "/console/settings?tab=storage", to: "/console/settings#downloaders/cache" },
{ from: "/console/settings?tab=path-mappings", to: "/console/settings#downloaders" },
{ from: "/console/settings?tab=site-credentials", to: "/console/settings#sites" },
];
-10
View File
@@ -59,16 +59,6 @@ const TERM_PENDING = new Set([
"apps/web/app/components/agent/mock.ts",
"apps/web/app/components/agent/quick-goals.ts",
"apps/web/app/api/agent.ts",
"apps/web/app/api/tasks.ts",
"apps/web/app/components/console/nav.ts",
"apps/web/app/components/downloads/business-tasks.tsx",
"apps/web/app/components/settings/automation.tsx",
"apps/web/app/components/settings/instances.tsx",
"apps/web/app/components/settings/library.tsx",
"apps/web/app/components/settings/organize-sources.tsx",
"apps/web/app/components/tasks/labels.ts",
"apps/web/app/routes/console/home.tsx",
"apps/web/app/routes/console/tasks.$id.tsx",
"apps/server/src/modules/agent/report.ts",
]);
let termScope = true;