i18n(desktop): localize runtime activity titles and details to Chinese
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -211,8 +211,8 @@ export function syncRuntimeSession(next: DesktopRuntimeSessionSyncRequest | null
|
|||||||
clearRuntimeState();
|
clearRuntimeState();
|
||||||
recordActivity(
|
recordActivity(
|
||||||
"info",
|
"info",
|
||||||
"Desktop Runtime Armed",
|
"任务消费端已就绪",
|
||||||
`Client ${normalized.desktop_client?.device_name ?? normalized.desktop_client?.id ?? "unknown"} 已准备消费桌面任务。`,
|
`客户端 ${normalized.desktop_client?.device_name ?? normalized.desktop_client?.id ?? "未知客户端"} 已准备消费桌面任务。`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ function startRuntime(): void {
|
|||||||
state.running = true;
|
state.running = true;
|
||||||
setSchedulerPhase("running");
|
setSchedulerPhase("running");
|
||||||
setSchedulerError(null);
|
setSchedulerError(null);
|
||||||
recordActivity("success", "Desktop Runtime Started", "已启动 SSE、heartbeat 和 pull fallback。");
|
recordActivity("success", "调度节点已启动", "已启动 SSE、心跳上报和兜底拉取。");
|
||||||
|
|
||||||
connectEventStream();
|
connectEventStream();
|
||||||
scheduleHeartbeatLoop();
|
scheduleHeartbeatLoop();
|
||||||
@@ -402,7 +402,7 @@ function connectEventStream(): void {
|
|||||||
state.lastServerTime = payload.server_time;
|
state.lastServerTime = payload.server_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
recordActivity("success", "Desktop Stream Connected", "服务端已建立定向任务事件流。");
|
recordActivity("success", "单点事件流已连接", "服务端已建立定向任务事件流。");
|
||||||
});
|
});
|
||||||
|
|
||||||
sseClient.on("ping", () => {
|
sseClient.on("ping", () => {
|
||||||
@@ -437,14 +437,14 @@ function connectEventStream(): void {
|
|||||||
const message = errorMessage(payload);
|
const message = errorMessage(payload);
|
||||||
state.lastError = message;
|
state.lastError = message;
|
||||||
setSchedulerError(message);
|
setSchedulerError(message);
|
||||||
recordActivity("warn", "Desktop Stream Reconnecting", message);
|
recordActivity("warn", "单点事件流重连中", message);
|
||||||
});
|
});
|
||||||
|
|
||||||
sseClient.on("reconnect", (payload) => {
|
sseClient.on("reconnect", (payload) => {
|
||||||
if (!isReconnectPayload(payload)) {
|
if (!isReconnectPayload(payload)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
recordActivity("info", "Desktop Stream Backoff", `将在 ${payload.delayMs}ms 后重连 SSE。`);
|
recordActivity("info", "单点事件流退避等待", `将在 ${payload.delayMs}ms 后重连 SSE。`);
|
||||||
});
|
});
|
||||||
|
|
||||||
state.sseClient = sseClient;
|
state.sseClient = sseClient;
|
||||||
@@ -510,7 +510,7 @@ async function sendHeartbeat(source: "startup" | "timer"): Promise<void> {
|
|||||||
setSchedulerError(null);
|
setSchedulerError(null);
|
||||||
|
|
||||||
if (source === "startup" || previousStatus === "failed") {
|
if (source === "startup" || previousStatus === "failed") {
|
||||||
recordActivity("success", "Heartbeat Healthy", "client heartbeat 已写回服务端。");
|
recordActivity("success", "心跳连接正常", "客户端心跳已回写到服务端。");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
state.lastHeartbeatAt = Date.now();
|
state.lastHeartbeatAt = Date.now();
|
||||||
@@ -526,7 +526,7 @@ async function sendHeartbeat(source: "startup" | "timer"): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source === "startup" || previousStatus !== "failed") {
|
if (source === "startup" || previousStatus !== "failed") {
|
||||||
recordActivity("danger", "Heartbeat Failed", state.lastError);
|
recordActivity("danger", "心跳连接失败", state.lastError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -635,7 +635,7 @@ async function syncAccounts(source: "startup" | "manual"): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source === "startup") {
|
if (source === "startup") {
|
||||||
recordActivity("info", "Accounts Synced", `已同步 ${state.accounts.length} 个桌面账号。`);
|
recordActivity("info", "本地账号同步", `已同步 ${state.accounts.length} 个桌面账号。`);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshAccountNames();
|
refreshAccountNames();
|
||||||
@@ -650,7 +650,7 @@ async function syncAccounts(source: "startup" | "manual"): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
recordActivity("warn", "Account Sync Failed", message);
|
recordActivity("warn", "账号同步失败", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,7 +686,7 @@ export async function unbindRuntimeAccount(accountId: string, syncVersion: numbe
|
|||||||
if (matchedAccount) {
|
if (matchedAccount) {
|
||||||
recordActivity(
|
recordActivity(
|
||||||
"info",
|
"info",
|
||||||
"Account Unbound",
|
"账号已解绑",
|
||||||
`${matchedAccount.display_name} 已解绑,并清理了当前机器上的本地会话缓存。`,
|
`${matchedAccount.display_name} 已解绑,并清理了当前机器上的本地会话缓存。`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -749,7 +749,7 @@ async function leaseSpecificTask(request: PendingTaskRequest): Promise<void> {
|
|||||||
|
|
||||||
state.lastError = errorMessage(error);
|
state.lastError = errorMessage(error);
|
||||||
setSchedulerError(state.lastError);
|
setSchedulerError(state.lastError);
|
||||||
recordActivity("warn", "Specific Lease Missed", `${request.taskId} 未能成功领取:${state.lastError}`);
|
recordActivity("warn", "指定任务领取失败", `${request.taskId} 未能成功领取:${state.lastError}`);
|
||||||
} finally {
|
} finally {
|
||||||
if (state.leaseInFlight) {
|
if (state.leaseInFlight) {
|
||||||
state.leaseInFlight = false;
|
state.leaseInFlight = false;
|
||||||
@@ -793,7 +793,7 @@ async function pullNextTask(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
recordActivity("warn", "Pull Fallback Failed", state.lastError);
|
recordActivity("warn", "兜底拉取失败", state.lastError);
|
||||||
} finally {
|
} finally {
|
||||||
state.leaseInFlight = false;
|
state.leaseInFlight = false;
|
||||||
}
|
}
|
||||||
@@ -823,13 +823,13 @@ async function executeLeasedTask(
|
|||||||
routing,
|
routing,
|
||||||
attemptId: leased.attempt_id ?? null,
|
attemptId: leased.attempt_id ?? null,
|
||||||
leaseToken: leased.lease_token,
|
leaseToken: leased.lease_token,
|
||||||
summary: `已领取租约,开始执行 ${routing === "rabbitmq-primary" ? "MQ 唤醒" : "pull fallback"} 消费。`,
|
summary: `已领取租约,开始执行 ${routing === "rabbitmq-primary" ? "MQ 唤醒" : "兜底拉取"} 消费。`,
|
||||||
});
|
});
|
||||||
|
|
||||||
recordActivity(
|
recordActivity(
|
||||||
"info",
|
"info",
|
||||||
"Task Leased",
|
"任务已领取",
|
||||||
`${taskRecord.title} 已被当前 desktop client 领取,routing=${routing}。`,
|
`${taskRecord.title} 已由当前客户端领取,路由:${describeRouting(routing)}。`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
@@ -859,10 +859,10 @@ async function executeLeasedTask(
|
|||||||
recordActivity(
|
recordActivity(
|
||||||
execution.status === "failed" ? "danger" : execution.status === "unknown" ? "warn" : "success",
|
execution.status === "failed" ? "danger" : execution.status === "unknown" ? "warn" : "success",
|
||||||
execution.status === "failed"
|
execution.status === "failed"
|
||||||
? "Task Completed As Failed"
|
? "任务执行失败"
|
||||||
: execution.status === "unknown"
|
: execution.status === "unknown"
|
||||||
? "Task Completed As Unknown"
|
? "任务执行结果待确认"
|
||||||
: "Task Succeeded",
|
: "任务执行成功",
|
||||||
`${taskRecord.title} ${execution.summary}`,
|
`${taskRecord.title} ${execution.summary}`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -894,7 +894,7 @@ async function executeLeasedTask(
|
|||||||
}
|
}
|
||||||
|
|
||||||
noteLeaseReleased("failed");
|
noteLeaseReleased("failed");
|
||||||
recordActivity("danger", "Task Failed", `${taskRecord.title} 执行失败:${failureMessage || "unknown_error"}`);
|
recordActivity("danger", "任务执行失败", `${taskRecord.title} 执行失败:${failureMessage || "未知错误"}`);
|
||||||
} finally {
|
} finally {
|
||||||
clearInterval(extendHandle);
|
clearInterval(extendHandle);
|
||||||
state.currentExecutionAbort = null;
|
state.currentExecutionAbort = null;
|
||||||
@@ -922,7 +922,7 @@ async function extendActiveLease(taskId: string, leaseToken: string): Promise<vo
|
|||||||
const message = errorMessage(error);
|
const message = errorMessage(error);
|
||||||
state.lastError = message;
|
state.lastError = message;
|
||||||
setSchedulerError(message);
|
setSchedulerError(message);
|
||||||
recordActivity("warn", "Lease Extend Failed", `${taskId} 续租失败:${message}`);
|
recordActivity("warn", "租约续期失败", `${taskId} 续租失败:${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,7 +1145,7 @@ function handleAuthExpired(error: unknown): void {
|
|||||||
const message = errorMessage(error);
|
const message = errorMessage(error);
|
||||||
state.lastError = message;
|
state.lastError = message;
|
||||||
setTransportAuthState("expired");
|
setTransportAuthState("expired");
|
||||||
recordActivity("danger", "Desktop Client Token Expired", message);
|
recordActivity("danger", "客户端令牌已过期", message);
|
||||||
stopRuntime();
|
stopRuntime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1226,6 +1226,10 @@ function resolveTaskTitle(
|
|||||||
return existing?.title ?? defaultTaskTitle(task.kind, task.platform);
|
return existing?.title ?? defaultTaskTitle(task.kind, task.platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function describeRouting(routing: RuntimeTaskRouting): string {
|
||||||
|
return routing === "rabbitmq-primary" ? "主消息队列通道" : "数据库兜底拉取";
|
||||||
|
}
|
||||||
|
|
||||||
function defaultTaskTitle(kind: "publish" | "monitor", platform?: string): string {
|
function defaultTaskTitle(kind: "publish" | "monitor", platform?: string): string {
|
||||||
return `${kind === "publish" ? "发布任务" : "监控任务"}${platform ? ` · ${platform}` : ""}`;
|
return `${kind === "publish" ? "发布任务" : "监控任务"}${platform ? ` · ${platform}` : ""}`;
|
||||||
}
|
}
|
||||||
@@ -1235,7 +1239,7 @@ function summaryFromTaskStatus(status: RuntimeTaskStatus): string {
|
|||||||
case "queued":
|
case "queued":
|
||||||
return "任务已排队,等待客户端领取租约。";
|
return "任务已排队,等待客户端领取租约。";
|
||||||
case "in_progress":
|
case "in_progress":
|
||||||
return "任务正在执行,结果回写需要携带有效 lease_token。";
|
return "任务正在执行,结果回写需要携带有效租约凭证。";
|
||||||
case "succeeded":
|
case "succeeded":
|
||||||
return "任务执行成功。";
|
return "任务执行成功。";
|
||||||
case "failed":
|
case "failed":
|
||||||
@@ -1250,7 +1254,7 @@ function summaryFromTaskStatus(status: RuntimeTaskStatus): string {
|
|||||||
function summaryFromEventType(type: DesktopTaskEventMessage["type"], status: RuntimeTaskStatus): string {
|
function summaryFromEventType(type: DesktopTaskEventMessage["type"], status: RuntimeTaskStatus): string {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "task_available":
|
case "task_available":
|
||||||
return "RabbitMQ fanout 已送达当前客户端,等待领取租约。";
|
return "主消息队列事件已送达当前客户端,等待领取租约。";
|
||||||
case "task_leased":
|
case "task_leased":
|
||||||
return "服务端已确认租约归属。";
|
return "服务端已确认租约归属。";
|
||||||
case "task_extended":
|
case "task_extended":
|
||||||
|
|||||||
@@ -41,10 +41,41 @@ function translateEventTitle(title: string) {
|
|||||||
"Desktop Stream Connected": "单点事件流已连接",
|
"Desktop Stream Connected": "单点事件流已连接",
|
||||||
"Desktop Runtime Started": "调度节点已启动",
|
"Desktop Runtime Started": "调度节点已启动",
|
||||||
"Desktop Runtime Armed": "任务消费端已就绪",
|
"Desktop Runtime Armed": "任务消费端已就绪",
|
||||||
|
"Desktop Stream Reconnecting": "单点事件流重连中",
|
||||||
|
"Desktop Stream Backoff": "单点事件流退避等待",
|
||||||
|
"Heartbeat Failed": "心跳连接失败",
|
||||||
|
"Account Sync Failed": "账号同步失败",
|
||||||
|
"Account Unbound": "账号已解绑",
|
||||||
|
"Specific Lease Missed": "指定任务领取失败",
|
||||||
|
"Pull Fallback Failed": "兜底拉取失败",
|
||||||
|
"Task Leased": "任务已领取",
|
||||||
|
"Task Completed As Failed": "任务执行失败",
|
||||||
|
"Task Completed As Unknown": "任务执行结果待确认",
|
||||||
|
"Task Succeeded": "任务执行成功",
|
||||||
|
"Task Failed": "任务执行失败",
|
||||||
|
"Lease Extend Failed": "租约续期失败",
|
||||||
|
"Desktop Client Token Expired": "客户端令牌已过期",
|
||||||
};
|
};
|
||||||
return map[title] || title;
|
return map[title] || title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function translateEventDetail(detail: string) {
|
||||||
|
const exactMap: Record<string, string> = {
|
||||||
|
"已启动 SSE、heartbeat 和 pull fallback。": "已启动 SSE、心跳上报和兜底拉取。",
|
||||||
|
"client heartbeat 已写回服务端。": "客户端心跳已回写到服务端。",
|
||||||
|
};
|
||||||
|
|
||||||
|
return (exactMap[detail] || detail)
|
||||||
|
.replace(/\brouting=rabbitmq-primary\b/gi, "路由:主消息队列通道")
|
||||||
|
.replace(/\brouting=db-recovery\b/gi, "路由:数据库兜底拉取")
|
||||||
|
.replace(/\bdesktop client\b/gi, "桌面客户端")
|
||||||
|
.replace(/\bclient heartbeat\b/gi, "客户端心跳")
|
||||||
|
.replace(/\bpull fallback\b/gi, "兜底拉取")
|
||||||
|
.replace(/\bheartbeat\b/gi, "心跳上报")
|
||||||
|
.replace(/\bClient\b/g, "客户端")
|
||||||
|
.replace(/\bunknown_error\b/gi, "未知错误");
|
||||||
|
}
|
||||||
|
|
||||||
function formatUid(uid: string) {
|
function formatUid(uid: string) {
|
||||||
return (uid || "").replace(/^(?:platform:)+/gi, "");
|
return (uid || "").replace(/^(?:platform:)+/gi, "");
|
||||||
}
|
}
|
||||||
@@ -145,7 +176,7 @@ const subsystemCards = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
<small>{{ formatRelativeTime(entry.at) }}</small>
|
<small>{{ formatRelativeTime(entry.at) }}</small>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ entry.detail }}</p>
|
<p>{{ translateEventDetail(entry.detail) }}</p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
<p v-else class="empty-text" style="margin-top: 16px;">当前没有最近事件记录。</p>
|
<p v-else class="empty-text" style="margin-top: 16px;">当前没有最近事件记录。</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user