feat(控制台): 去掉待处理中心,问题回到发生处

- 侧栏与命令面板没有「待处理」;/console/inbox?kind= 按问题类型跳到整理记录「需要处理」、下载面板、运行状态或订阅
- 整理记录加「需要处理」筛选,行内写原因与推荐动作(指定作品 / 重新整理 / 让智能体识别 / 替换·保留两者·跳过 / 忽略),
  详情页同样可处理;处理按钮从原待处理页抽成 components/decisions/decision-actions.tsx 复用
- 铃铛只放等你批准的智能体操作与系统健康;首页「要我处理」与运行状态「需要关注」放汇总计数,运行状态加智能体用量
- 设置 → 智能体:预算卡改为「用量与限制」(只剩单次工具调用与时长,附花费统计),自动调查卡加「整理识别不到作品时叫智能体识别」
- 集数待确认的原因显示在作品页集数映射(可确认建议规则 / 智能体建议)与订阅详情;未识别资源在媒体库「未识别」里直接选候选或指定
- 下载、站点、任务里指向待处理的链接改到对应页面

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 16:47:25 +08:00
1 parent 1c1a954703
commit fa76d7563c
36 files changed
+1209 -921

No files matched your search

+14 -28
View File
@@ -16,8 +16,8 @@ import type { ReactNode } from "react";
import { useRef } from "react";
import { Link } from "react-router";
import { toast } from "sonner";
import { useAttention } from "~/api/attention.ts";
import { useDashboard, useSitesWithAccounts } from "~/api/dashboard.ts";
import { useDecisions } from "~/api/decisions.ts";
import { useEngineRunsPage } from "~/api/engine.ts";
import { useUpdateSettings } from "~/api/settings.ts";
import { useSystemHealth } from "~/api/system.ts";
@@ -25,17 +25,18 @@ import { ConfirmDialog } from "~/components/console/confirm-dialog.tsx";
import { EmptyState, ErrorState, LoadingState } from "~/components/console/empty-state.tsx";
import { consolePath, settingsPath } from "~/components/console/nav.ts";
import { PageHeader } from "~/components/console/page-header.tsx";
import { AttentionList, attentionRows } from "~/components/dashboard/attention-summary.tsx";
import { HomeRuntime } from "~/components/dashboard/home-runtime.tsx";
import { runTitle } from "~/components/tasks/labels.ts";
import { useLiveTasks } from "~/components/tasks/task-stream.tsx";
import { Button } from "~/components/ui/button.tsx";
import { errorMessage } from "~/lib/api.ts";
import { decisionKindLabel, formatRelative } from "~/lib/labels.ts";
import { formatRelative } from "~/lib/labels.ts";
import { qk } from "~/lib/query-keys.ts";
import { useSse } from "~/lib/sse.ts";
import { cn } from "~/lib/utils.ts";
// 首页概览:自动化、存储与下载器状态,以及当前工作、待处理事项和最近入库。
// 首页概览:自动化、存储与下载器状态,以及当前工作、要我处理的汇总计数(整理需要处理 / 等你批准 / 系统健康)和最近入库。
/** 首页关心的事件:任意一个到达就(节流)刷新聚合 */
const DASHBOARD_EVENTS = [
@@ -257,33 +258,18 @@ function Busy({ w }: { w: Dashboard["currentWork"] }) {
);
}
// ─── 要我处理什么:计数 + 前 3 条 ───
function NeedsMe({ n }: { n: Dashboard["needsAttention"] }) {
const list = useDecisions({});
const top = (list.data?.pages[0]?.items ?? []).slice(0, 3);
// ─── 要我处理什么:汇总计数(整理需要处理、等你批准、系统健康),点进去到对应页面 ───
function NeedsMe() {
const q = useAttention();
const rows = attentionRows(q.data);
return (
<Section title="要我处理" icon={AlertTriangle} to={consolePath("inbox")}>
{n.total === 0 ? (
<Section title="要我处理" icon={AlertTriangle}>
{q.isPending ? (
<LoadingState rows={2} />
) : rows.length === 0 ? (
<EmptyState plain icon={CircleCheck} title="没有要你处理的事" className="py-6" />
) : (
<>
<p className="mb-2 text-title-sm font-semibold text-warning tabular-nums">
{n.total}
<span className="ml-1.5 text-caption font-normal text-muted-foreground">
项 · {n.byKind.map((k) => `${decisionKindLabel(k.kind)} ${k.count}`).join(" · ")}
</span>
</p>
<ul className="divide-y divide-border/60">
{top.map((d) => (
<Row key={d.id}>
<Link to={`/console/inbox?kind=${d.kind}`} className="min-w-0 flex-1 hover:underline">
<span className="block truncate">{d.title}</span>
<span className="block truncate text-meta text-muted-foreground">{formatRelative(d.createdAt)}</span>
</Link>
</Row>
))}
</ul>
</>
<AttentionList rows={rows} />
)}
</Section>
);
@@ -350,7 +336,7 @@ export default function Home() {
) : (
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
<Busy w={q.data.currentWork} />
<NeedsMe n={q.data.needsAttention} />
<NeedsMe />
<RecentImports d={q.data} />
</div>
)}