docs(copy): 日志、计划、运行状态文案按 human-copy 重写

- 「立即执行」统一为「立即运行」,Toast 写「已加入队列」
- 巡检不再提「待处理」:触发条件写「有需要处理的事项时」,开关叫「生成巡检报告」
- 下载巡检触发条件写清包含失败的下载

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-07 01:46:30 +08:00
1 parent 8918fc268e
commit 89795802b5
11 files changed
+27 -27

No files matched your search

+6 -6
View File
@@ -70,10 +70,10 @@ const ACTION_LABEL: Record<string, string> = {
"pi_upstream.oauth_start": "开始订阅登录", "pi_upstream.oauth_start": "开始订阅登录",
"pi_upstream.oauth_login": "完成订阅登录", "pi_upstream.oauth_login": "完成订阅登录",
"pi_upstream.oauth_logout": "退出订阅登录", "pi_upstream.oauth_logout": "退出订阅登录",
"schedule.run_now": "立即执行定时任务", "schedule.run_now": "立即运行定时任务",
"schedule.skip": "跳过定时任务", "schedule.skip": "跳过定时任务",
"schedule.update": "修改定时任务", "schedule.update": "修改定时任务",
"storage.cleanup": "立即清理存储", "storage.cleanup": "清理存储",
"acquisition_plan.manual_submit": "手动提交下载", "acquisition_plan.manual_submit": "手动提交下载",
"acquisition_plan.cancel": "取消下载", "acquisition_plan.cancel": "取消下载",
"capability.invoke": "智能体操作", "capability.invoke": "智能体操作",
@@ -81,7 +81,7 @@ const ACTION_LABEL: Record<string, string> = {
"site.created": "登记站点", "site.created": "登记站点",
"site.updated": "修改站点", "site.updated": "修改站点",
"feed_source.created": "新建 RSS", "feed_source.created": "新建 RSS",
"identity.release_assigned": "指定资源身份", "identity.release_assigned": "为资源指定作品",
"files.mkdir": "新建目录", "files.mkdir": "新建目录",
"files.rename": "重命名", "files.rename": "重命名",
"files.move": "移动文件", "files.move": "移动文件",
@@ -149,13 +149,13 @@ const SCHEDULE_STATUS: Record<string, { label: string; tone: StatusTone }> = {
running: { label: "进行中", tone: "neutral" }, running: { label: "进行中", tone: "neutral" },
}; };
const AGENT_STATUS: Record<string, { label: string; tone: StatusTone }> = { const AGENT_STATUS: Record<string, { label: string; tone: StatusTone }> = {
queued: { label: "排队", tone: "neutral" }, queued: { label: "排队中", tone: "neutral" },
waiting: { label: "等待", tone: "neutral" }, waiting: { label: "等待中", tone: "neutral" },
cancelled: { label: "已停止", tone: "warning" }, cancelled: { label: "已停止", tone: "warning" },
budget_exceeded: { label: "超出预算", tone: "warning" }, budget_exceeded: { label: "超出预算", tone: "warning" },
}; };
const ENGINE_STATUS: Record<string, { label: string; tone: StatusTone }> = { const ENGINE_STATUS: Record<string, { label: string; tone: StatusTone }> = {
pending: { label: "排队", tone: "neutral" }, pending: { label: "排队中", tone: "neutral" },
canceled: { label: "已取消", tone: "warning" }, canceled: { label: "已取消", tone: "warning" },
}; };
+2 -2
View File
@@ -115,7 +115,7 @@ function ScheduleRunBody({ e }: { e: LogEntry }) {
{ to: logsPath({ tab: "schedules", job: jobId }), label: "定时任务设置" }, { to: logsPath({ tab: "schedules", job: jobId }), label: "定时任务设置" },
{ {
to: objectLogsPath("scheduled_job", jobId), to: objectLogsPath("scheduled_job", jobId),
label: "这个定时任务的全部运行", label: "这个定时任务的全部运行记录",
icon: <History className="h-3.5 w-3.5" />, icon: <History className="h-3.5 w-3.5" />,
}, },
] ]
@@ -240,7 +240,7 @@ function RunSheet({
<Button asChild variant="ghost" size="sm"> <Button asChild variant="ghost" size="sm">
<Link to={`/console/tasks/${encodeURIComponent(r.id)}`}> <Link to={`/console/tasks/${encodeURIComponent(r.id)}`}>
<ExternalLink /> <ExternalLink />
独立页面 打开任务页
</Link> </Link>
</Button> </Button>
{entry ? <AskAgentButton entries={[entry]} /> : null} {entry ? <AskAgentButton entries={[entry]} /> : null}
@@ -199,7 +199,7 @@ export function AgentCheckCard({
<footer className="mt-auto flex flex-wrap items-center gap-1.5"> <footer className="mt-auto flex flex-wrap items-center gap-1.5">
<Button size="sm" disabled={!a.canRun} onClick={a.run}> <Button size="sm" disabled={!a.canRun} onClick={a.run}>
{a.runNow.isPending ? <LoaderCircle className="animate-spin" /> : <Play />} {a.runNow.isPending ? <LoaderCircle className="animate-spin" /> : <Play />}
立即执行 立即运行
</Button> </Button>
<Button size="sm" variant="ghost" disabled={!a.canSkip} onClick={a.skipNext}> <Button size="sm" variant="ghost" disabled={!a.canSkip} onClick={a.skipNext}>
<SkipForward /> <SkipForward />
@@ -337,7 +337,7 @@ function AgentCheckDetail({
</Field> </Field>
<Field label="触发条件"> <Field label="触发条件">
{CHECK_TRIGGER_LABEL[c.triggerCondition ?? "always"]} {CHECK_TRIGGER_LABEL[c.triggerCondition ?? "always"]}
{c.reportAsDecision ? <span className="ml-1 text-meta text-muted-foreground">· 结果写入待处理</span> : null} {c.reportAsDecision ? <span className="ml-1 text-meta text-muted-foreground">· 生成巡检报告</span> : null}
</Field> </Field>
<Field label="预算">{budgetParts.length ? budgetParts.join(" · ") : "默认"}</Field> <Field label="预算">{budgetParts.length ? budgetParts.join(" · ") : "默认"}</Field>
<Field label="模型"> <Field label="模型">
@@ -169,11 +169,11 @@ export function AgentCheckDialog({
rows={4} rows={4}
value={d.goal} value={d.goal}
aria-invalid={!!errors.goal} aria-invalid={!!errors.goal}
placeholder="检查 {{openDecisions}} 条待处理事项,给出处理建议" placeholder="检查 {{openDecisions}} 条需要处理的事项,给出处理建议"
onChange={(e) => set("goal", e.target.value)} onChange={(e) => set("goal", e.target.value)}
/> />
</FormField> </FormField>
<FormField label="能力白名单" hint="不选则放行全部只读能力"> <FormField label="能力白名单" hint="不选就允许全部只读能力">
<div className="grid max-h-48 gap-1 overflow-y-auto rounded-tight border border-border/70 px-2.5 py-2 sm:grid-cols-2"> <div className="grid max-h-48 gap-1 overflow-y-auto rounded-tight border border-border/70 px-2.5 py-2 sm:grid-cols-2">
{READONLY_CAPS.map((c) => { {READONLY_CAPS.map((c) => {
const on = d.caps.includes(c.id); const on = d.caps.includes(c.id);
@@ -264,15 +264,15 @@ export function AgentCheckDialog({
<div className="grid gap-2 pb-2"> <div className="grid gap-2 pb-2">
<label htmlFor="ac-report" className="flex items-center justify-between gap-3 text-caption"> <label htmlFor="ac-report" className="flex items-center justify-between gap-3 text-caption">
<span> <span>
写入待处理 生成巡检报告
<span className="ml-2 text-meta text-muted-foreground">结果汇总成一条待处理事项</span> <span className="ml-2 text-meta text-muted-foreground">运行成功后把结果汇总成一条报告</span>
</span> </span>
<Switch id="ac-report" checked={d.reportAsDecision} onCheckedChange={(v) => set("reportAsDecision", v)} /> <Switch id="ac-report" checked={d.reportAsDecision} onCheckedChange={(v) => set("reportAsDecision", v)} />
</label> </label>
<label htmlFor="ac-recover" className="flex items-center justify-between gap-3 text-caption"> <label htmlFor="ac-recover" className="flex items-center justify-between gap-3 text-caption">
<span> <span>
允许授权内恢复 允许授权内恢复
<span className="ml-2 text-meta text-muted-foreground">需有效持续授权,否则只读</span> <span className="ml-2 text-meta text-muted-foreground">可重试任务、重新校验、确认识别;没有有效的持续授权时只读</span>
</span> </span>
<Switch id="ac-recover" checked={d.allowRecover} onCheckedChange={(v) => set("allowRecover", v)} /> <Switch id="ac-recover" checked={d.allowRecover} onCheckedChange={(v) => set("allowRecover", v)} />
</label> </label>
@@ -60,7 +60,7 @@ export function useJobActions(job: ScheduledJob) {
runNow.mutate( runNow.mutate(
{ id: job.id }, { id: job.id },
{ {
onSuccess: (r) => toast.success(r.queued ? "已排队执行" : "已在排队或运行中"), onSuccess: (r) => toast.success(r.queued ? "已加入队列" : "已在排队或运行中"),
onError: (e) => toast.error(errorMessage(e)), onError: (e) => toast.error(errorMessage(e)),
}, },
), ),
@@ -149,8 +149,8 @@ function AutoTaskRow({ job, now, highlight }: { job: ScheduledJob; now: number;
<Button <Button
size="icon-sm" size="icon-sm"
variant="ghost" variant="ghost"
aria-label={`立即执行${job.name}`} aria-label={`立即运行${job.name}`}
title="立即执行" title="立即运行"
disabled={!a.canRun} disabled={!a.canRun}
onClick={a.run} onClick={a.run}
> >
@@ -21,7 +21,7 @@ import { errorMessage } from "~/lib/api.ts";
// 对话里给「检查并启用」卡片,用户在计划页检查、修改后启用。 // 对话里给「检查并启用」卡片,用户在计划页检查、修改后启用。
const EXAMPLES = [ const EXAMPLES = [
"每天早上 9 点前看看有没有失败或卡住的下载,有就写成待处理", "每天早上 9 点前看看有没有失败或卡住的下载,有就汇报",
"每隔 6 小时检查一下站点登录有没有失效", "每隔 6 小时检查一下站点登录有没有失效",
"每周汇报一次订阅追更情况和缺集", "每周汇报一次订阅追更情况和缺集",
]; ];
@@ -14,7 +14,7 @@ describe("计划页标签", () => {
{ text: "巡检待处理(" }, { text: "巡检待处理(" },
{ placeholder: "now", label: "当前时间" }, { placeholder: "now", label: "当前时间" },
{ text: "):有 " }, { text: "):有 " },
{ placeholder: "openDecisions", label: "待处理事项数" }, { placeholder: "openDecisions", label: "需要处理的事项数" },
{ text: " 条,{{unknown}}" }, { text: " 条,{{unknown}}" },
]); ]);
}); });
+3 -3
View File
@@ -48,8 +48,8 @@ export const TRIGGER_LABEL: Record<ScheduleTrigger, string> = {
export const CHECK_TRIGGER_LABEL: Record<AgentCheckTrigger, string> = { export const CHECK_TRIGGER_LABEL: Record<AgentCheckTrigger, string> = {
always: "每次运行", always: "每次运行",
open_decisions: "有待处理时", open_decisions: "有需要处理的事项时",
stalled_downloads: "有下载无进展时", stalled_downloads: "有下载无进展或失败时",
subscriptions_active: "有追踪订阅时", subscriptions_active: "有追踪订阅时",
}; };
@@ -135,7 +135,7 @@ export function formatClock(iso: string | null | undefined): string {
export const GOAL_PLACEHOLDER_LABEL: Record<string, string> = { export const GOAL_PLACEHOLDER_LABEL: Record<string, string> = {
now: "当前时间", now: "当前时间",
date: "今天日期", date: "今天日期",
openDecisions: "待处理事项数", openDecisions: "需要处理的事项数",
stalledDownloads: "异常下载数", stalledDownloads: "异常下载数",
activeSubscriptions: "追踪中的订阅数", activeSubscriptions: "追踪中的订阅数",
}; };
@@ -55,7 +55,7 @@ export function RunsSheet({ job, onClose }: { job: ScheduledJob | null; onClose:
to={consolePath("agent", r.agentRunId)} to={consolePath("agent", r.agentRunId)}
className="w-fit text-meta text-muted-foreground underline-offset-2 hover:text-foreground hover:underline" className="w-fit text-meta text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
> >
查看智能体会话{r.agentStatus ? `(${agentRunLabel(r.agentStatus).label})` : ""} 查看智能体会话{r.agentStatus ? `(${agentRunLabel(r.agentStatus).label})` : ""}
</Link> </Link>
) : null} ) : null}
</li> </li>
@@ -54,7 +54,7 @@ export function Sparkline({
if (!has) if (!has)
return ( return (
<div className="flex items-center text-meta text-muted-foreground" style={{ height }}> <div className="flex items-center text-meta text-muted-foreground" style={{ height }}>
正在采样… 采样中…
</div> </div>
); );
return ( return (
@@ -118,7 +118,7 @@ function CleanupTable({ rows }: { rows: CleanupRow[] }) {
const run = (t: StorageCleanupTarget) => const run = (t: StorageCleanupTarget) =>
clean.mutate(t, { clean.mutate(t, {
onSuccess: (r) => onSuccess: (r) =>
r.queued ? toast.success(`已排入清理:${CLEANUP_LABEL[t]}`) : toast.info(`${CLEANUP_LABEL[t]}已在排队或运行中`), r.queued ? toast.success(`已加入队列:${CLEANUP_LABEL[t]}`) : toast.info(`${CLEANUP_LABEL[t]}已在排队或运行中`),
onError: (e) => toast.error(errorMessage(e)), onError: (e) => toast.error(errorMessage(e)),
}); });
return ( return (
@@ -470,7 +470,7 @@ export function StorageSection({ health }: { health: SystemHealth }) {
<StatementsInfo st={s.db.statements} /> <StatementsInfo st={s.db.statements} />
<Panel title="清理任务" note="立即清理会把对应的维护任务排入执行,结果看运行记录"> <Panel title="清理任务" note="立即清理会把维护任务加入队列,结果在运行记录里看">
<CleanupTable rows={s.cleanup} /> <CleanupTable rows={s.cleanup} />
</Panel> </Panel>
</div> </div>