const zh = { common: { help: "帮助说明", refresh: "刷新", refreshing: "刷新中…", query: "查询", clearFilters: "清除筛选", prevPage: "上一页", nextPage: "下一页", perPage: "{{n}}/页", pagerMeta: "共 {{total}} 条 · 第 {{page}}/{{pages}} 页", opFailed: "操作失败", empty: "-", }, workbench: { title: "工作台", backToWorkbench: "返回工作台", openInNewTab: "在新标签页中打开", openModule: "打开或切换到该模块页签", monitoring: "监控", operations: "运维", system: "系统管理", cards: { umeSync: "UME同步", umeSyncDesc: "UME 告警同步、订阅与清单", network: "网络管理", networkDesc: "网元清单、告警、配置同步与监控任务", managedNe: "网元管理", managedNeDesc: "多厂商 SSH/Telnet 网元与连通性测试", collect: "批量采集", collectDesc: "对已连通网元执行定制 CLI 命令并保存日志", webcrt: "WebCRT", webcrtDesc: "浏览器内交互登录已连通网元(SSH/Telnet)", topology: "拓扑管理", topologyDesc: "拖拽编排网元拓扑,支持 LLDP/CDP 发现链路", portTrafficWall: "流量大屏", portTrafficWallDesc: "独立页签打开命名流量大屏", users: "用户管理", usersDesc: "管理员添加、禁用用户并重置密码", audit: "操作审计", auditDesc: "查看登录与操作记录", apiKeys: "API Key", apiKeysDesc: "为用户生成 MCP/脚本用 Token,可设有效期", }, }, network: { title: "网络管理", nav: { detail: "网络详情", tasks: "监控任务", devices: "设备列表", topology: "拓扑信息", alarms: "告警信息", configs: "配置信息", webcrt: "WebCRT", collectTasks: "采集任务", configSync: "配置同步", portTraffic: "流量监控", portTrafficWall: "流量大屏", }, collapseNav: "折叠侧栏", expandNav: "展开侧栏", placeholder: { title: "功能规划中", body: "该能力尚未开放。", }, }, portTraffic: { title: "端口流量监控", create: "添加设备监控", backList: "返回列表", created: "已添加设备监控", createFailed: "创建失败", updated: "已保存", interfacesSaved: "接口已更新", started: "已启动", paused: "已暂停", stopped: "已停止", statusRunning: "运行中", statusPaused: "已暂停", statusStopped: "已停止", collecting: "采集中", deleted: "已删除", confirmDelete: "删除该设备监控及其采样数据?", empty: "暂无设备监控。请先选择网元并勾选接口。", wall: "监控大屏", wallTitle: "端口流量大屏", toDevices: "设备管理", wallEmpty: "暂无监控设备。请先添加设备并勾选接口。", fullscreen: "全屏", exitFullscreen: "退出全屏", board: "大屏", boardPick: "选择大屏", boardPickHint: "请选择或新建一张流量大屏。", boardEmpty: "还没有大屏。可新建一张用于割接/值班监控。", boardDefaultName: "未命名大屏", boardName: "名称", boardCols: "列数", boardCreate: "新建大屏", boardEdit: "编辑布局", boardSave: "保存", boardCancel: "取消", boardSaved: "大屏已保存", boardCreated: "大屏已创建", boardDeleted: "大屏已删除", boardConfirmDelete: "删除该大屏及其图格配置?", boardUnsavedLeave: "有未保存的修改,确定离开?", boardOpenTab: "新页签打开", boardOpen: "打开大屏", boardListHint: "点击条目在独立页签打开大屏;从工作台打开网络管理不会刷新已打开的大屏。", boardPanelCount: "图格数", boardUpdated: "更新时间", boardClosedHint: "可关闭本页签;也可回到网络管理 → 流量大屏列表重新打开。", boardAddPanel: "添加图格", boardNoPanels: "该大屏还没有图格,请编辑并添加监控接口。", boardPickDevice: "选择设备", boardPanelSettings: "图格设置", boardPanelTitle: "标题(可选)", boardColSpan: "跨列", boardPanelStale: "接口已失效或不存在,请重新选择。", boardRetarget: "重选接口", edit: "编辑", save: "保存", start: "启动", pause: "暂停", stop: "停止", delete: "删除", wizStep1: "选设备", wizStep2: "选接口", wizStep3: "参数", step1: "参数", step2: "选网元", step3: "选接口", step4: "确认", prev: "上一步", next: "下一步", fieldTitle: "任务名称", titlePh: "例如:接入侧上联", titleRequired: "请填写任务名称", portsRequired: "请至少选择一个接口", interval: "周期(秒)", retention: "保留(天)", retentionHintWizard: "若需上周同日对比,建议 ≥8 天", concurrency: "并发", note: "备注", notePh: "可选", startNow: "创建后立即启动", neKeywordPh: "名称 / IP / 厂商", deepLinkHint: "已从拓扑跳转:网元 {{ne}}{{ifname}}。请确认选中后继续。", deepLinkIfname: ",接口 {{ifname}}", selectedNe: "已选 {{count}} 台网元", selectedOneNe: "已选", selectedPorts: "已选 {{count}} 个接口", pickNeFirst: "请先选择一台网元", discover: "拉取接口", confirmCreate: "开始监控", wallTask: "任务", wallDevice: "设备", wallPort: "接口", wallDeviceLabel: "网元", pickPort: "选择接口", range: "时间范围", compare: "周期对比", compareOff: "关闭", compareDay: "昨日同时刻", compareWeek: "上周同日", compareShift: "前一窗", compareCustom: "自定义偏移", offsetHours: "偏移(小时)", baseline: "基线", baselineAt: "基线原时刻", baselineDevice: "基线网元", baselinePort: "基线接口", seriesCurrentIn: "当前 In", seriesCurrentOut: "当前 Out", seriesBaselineIn: "基线 In", seriesBaselineOut: "基线 Out", mapBaselinePort: "映射基线接口", mapBaselineTask: "映射基线任务", mapBaselineNone: "不映射", retentionHint: "周对比建议保留天数 ≥ 8;否则基线可能无数据。", collectNow: "立即采集", collectStarted: "已触发采集", collectBusy: "采集进行中", targetError: "接口最近错误", waitSamples: "设备运行后会按周期写入样点;也可点「立即采集」。图会每几秒自动刷新。", waitAfterError: "采集失败,请到「流量监控」操作中的日志查看详情,修复后可点「立即采集」重试。", log: "日志", logTitle: "采集日志", logEmpty: "暂无日志。", logDevice: "设备", logLevel: "级别", logTime: "时间", logMessage: "内容", logClose: "关闭", logHasError: "有错误", kpiLatest: "最新", kpiBw: "带宽", latestAt: "最新样点", hoverPoint: "光标位置", wallLiveTitle: "实时流量", filterView: "视图", filterMap: "映射基线", yMode: "纵轴", yModeAuto: "自动(含基线)", yModeCurrent: "按当前流量", yModeUtil: "利用率 %", kpi: { tasks: "任务数", devices: "监控设备", running: "运行中", ports: "监控接口", samples24h: "24h 样点", }, col: { title: "任务", device: "设备", status: "状态", ports: "接口", interval: "周期", last: "最近采集", actions: "操作", source: "来源", name: "设备", vendor: "厂商", }, }, configSync: { title: "配置同步", syncNow: "立即全量同步", retryFailed: "一键重试失败", pause: "暂停", resume: "继续", stop: "停止", confirmStop: "停止后将取消未执行的网元任务,确定停止本轮同步?", started: "已启动同步周期", paused: "已暂停", resumed: "已继续", stopped: "已停止同步周期", policyTitle: "同步策略", policySaved: "策略已保存", enabled: "启用周期调度", intervalDays: "周期(天)", concurrency: "并发", historyKeep: "历史保留", scope: "范围", scopeAll: "全部网元", scopeSelected: "指定网元", savePolicy: "保存策略", selectedCount: "已选 {{count}} 台", targetKeywordPh: "名称 / IP / 厂商", cyclesTitle: "同步周期", cyclesEmpty: "暂无同步周期", tasksTitle: "周期任务", taskKeywordPh: "名称 / IP / 消息", allStatus: "全部状态", expand: "展开", collapse: "收起", kpi: { snapshots: "配置覆盖数", running: "进行中", idle: "空闲", last: "最近一轮", nextDue: "下次调度", }, col: { source: "来源", name: "设备", vendor: "厂商", trigger: "触发", status: "状态", progress: "进度", started: "开始", ended: "结束", message: "消息", actions: "操作", }, }, networkDevices: { title: "设备列表", keywordPh: "名称 / IP / ID", allSource: "全部来源", empty: "暂无网元。", col: { source: "来源", name: "名称", vendor: "厂商", deviceType: "设备类型", connect: "连通状态", }, }, networkConfigs: { title: "配置信息", keywordPh: "名称 / IP / ID", vendorPh: "厂商", allSource: "全部来源", empty: "暂无已同步配置。请先在「配置同步」执行采集。", view: "查看", export: "导出", exportBoth: "导出全部", exportOk: "配置已导出", close: "关闭", tabSet: "Set 格式", tabHier: "层级格式", col: { name: "设备", vendor: "厂商", source: "来源", size: "大小", collected: "采集时间", }, }, layout: { title: "UME 对接", titleUme: "UME同步", titleNetwork: "网络管理", titleManagedNe: "网元管理", titleCollect: "批量采集", titleWebcrt: "WebCRT", titleTopology: "拓扑管理", titlePortTrafficWall: "流量大屏", titleUsers: "用户管理", titleAudit: "操作审计", titleApiKeys: "API Key", navUme: "UME 对接", netxApi: "netx api", oclawBridge: "oclaw WSS", language: "语言", moreMenu: "更多", langZh: "中文", langEn: "English", }, auth: { loginTitle: "登录 NetX", loginHint: "使用本地账号访问运维平台", username: "用户名", password: "密码", login: "登录", loggingIn: "登录中…", loginFailed: "登录失败", logout: "退出", usersTitle: "用户管理", usersHint: "仅管理员可创建与管理本地账号。", addUser: "添加用户", role: "角色", roleAdmin: "管理员", roleUser: "普通用户", status: "状态", active: "启用", disabled: "禁用", enable: "启用", disable: "禁用", actions: "操作", newPassword: "新密码", resetPassword: "重置密码", userCreated: "用户已创建", userUpdated: "用户已更新", auditTitle: "操作审计", auditHintAdmin: "查看所有用户的登录与操作记录。", auditHintUser: "查看你自己的操作记录。", filterUsername: "用户名筛选", filterAction: "动作筛选", colTime: "时间", colUser: "用户", colAction: "动作", colMethod: "方法", colPath: "路径", colStatus: "状态码", colIp: "IP", apiKeysTitle: "API Key 管理", apiKeysHint: "生成长期 Token 供 MCP/脚本调用;明文仅创建时显示一次。管理员可为其他用户签发。", tokenName: "名称", expiresIn: "有效期", expire7d: "7 天", expire30d: "30 天", expire90d: "90 天", expire365d: "1 年", expireNever: "永不过期", tokenOwner: "所属用户", tokenOwnerSelf: "自己({{user}})", createToken: "生成 Key", tokenCreated: "API Key 已生成", tokenRevoked: "已吊销", tokenOnceHint: "请立即复制保存,关闭后无法再次查看明文:", copyToken: "复制", tokenCopied: "已复制到剪贴板", tokenCopyFailed: "复制失败", expiresAt: "到期时间", lastUsed: "最近使用", tokenStatusActive: "有效", tokenStatusExpired: "已过期", tokenStatusRevoked: "已吊销", revokeToken: "吊销", revokeConfirm: "确定吊销该 API Key?", forceChangeTitle: "请修改初始密码", forceChangeHint: "账号 {{user}} 仍在使用默认密码,登录前必须先修改。", oldPassword: "当前密码", confirmPassword: "确认新密码", savePassword: "保存新密码", savingPassword: "保存中…", passwordTooShort: "新密码至少 6 位", passwordMismatch: "两次输入的新密码不一致", passwordMustChange: "新密码不能与默认/旧密码相同", }, collect: { create: { title: "新建采集任务", hint: "配置命令与网元后创建任务;创建后需在任务列表中点击「开始」执行采集。", selectedTitle: "已选择网元", selectedEmpty: "请从下方筛选并逐个添加网元。", selectedCount: "共 {{count}} 台", clearSelected: "清空已选", remove: "移除", pickTitle: "可选网元(连通性已通过)", pickHint: "仅展示 connect_status=pass 的网元。请先在「网元管理」完成连通性测试。", pickEmpty: "没有匹配的网元。", filterKeyword: "筛选", filterKeywordPh: "名称 / IP / 厂商 / 设备类型", add: "添加", addBatch: "批量添加({{count}})", added: "已添加", create: "创建任务", creating: "创建中…", expand: "展开", collapse: "收起", meta: "已选 {{ne}} 台网元 · {{cmd}} 条命令", }, eligible: { title: "可选网元(连通性已通过)", hint: "仅展示 connect_status=pass 的网元。请先在「网元管理」完成连通性测试。", empty: "暂无已通过连通性测试的网元。", }, form: { title: "采集配置", jobTitle: "任务名称", jobTitlePh: "留空则自动生成", commands: "采集命令(每行一条,# 开头为注释)", commandsPh: "display version\ndisplay current-configuration", commandsHint: "命令将按顺序在每台设备上执行,输出合并为一份文本日志(格式与旧版 NetX 采集一致)。", meta: "已选 {{ne}} 台网元 · {{cmd}} 条命令", start: "开始采集", starting: "提交中…", }, created: "采集任务已创建:{{id}}", started: "采集已开始:{{id}}", paused: "任务已暂停", restarted: "已重新开始采集", retryFailedDone: "已开始重采失败网元", deleted: "任务已删除", nothingToRetry: "没有可重试的失败网元", neBusy: "部分网元正在被其他采集任务占用,请等待其完成后再开始", jobRunning: "该任务已在执行中", confirmDelete: "确定删除该采集任务?相关日志文件将一并删除。", jobs: { title: "采集任务", col: { title: "任务", status: "状态", progress: "进度", created: "创建时间", lastRun: "最近执行", actions: "操作", }, ok: "成功", fail: "失败", expand: "详情", collapse: "收起", pause: "暂停", start: "开始", starting: "启动中…", restart: "重新开始", retryFailed: "重采失败网元", downloadResults: "下载结果", delete: "删除", autoRefresh: "任务进行中,每 2 秒自动刷新", runsInProgress: "部分网元仍在采集中,请稍候…", }, runs: { status: "状态", message: "说明", download: "日志", downloadFile: "下载", filterStatus: "状态筛选", filterDevice: "设备筛选", deviceKeywordPh: "名称 / IP", allStatus: "全部状态", }, }, managedNe: { title: "网元管理", credsNotConfigured: "未配置 NETX_CREDENTIAL_SECRET_KEY,无法保存密码。请在 .env 中设置 Fernet 密钥后重启 API。", add: "新增网元", importBtn: "批量导入", downloadTemplate: "下载导入模板", importing: "导入中…", edit: "编辑", delete: "删除", openTerminal: "终端", confirmDelete: "确定删除该网元?", batchDelete: "批量删除", batchDeleting: "删除中…", batchDeleteConfirm: "确定删除选中的 {{n}} 台网元?此操作不可恢复。", batchDeleteDone: "已删除 {{n}} 台网元", batchDeleteSelectRequired: "请先勾选要删除的网元", keywordPh: "名称 / IP / 用户名 / 标签", allVendors: "全部厂商", allConnectStatus: "全部连通状态", stats: { title: "统计", total: "共 {{n}} 台网元", pass: "已连通", fail: "失败", unknown: "未测试", testing: "测试中", batchProxy: "一键添加代理", batchTest: "一键连通性测试", tagFilter: "按标签筛选", all: "全部", allTag: "全部(无标签筛选)", noTag: "无标签", tagStats: "按标签统计(Top)", confirm: "将对 {{n}} 台网元执行操作,确认继续?", proxyDone: "已为 {{n}} 台网元提交代理配置", testDone: "已提交 {{n}} 台网元连通性测试", loadingIds: "加载中…", }, col: { name: "名称", vendor: "厂商", deviceType: "设备类型", ip: "管理地址", port: "端口", protocol: "协议", user: "用户名", password: "密码", tags: "标签", remark: "备注", connect: "连通性", testedAt: "测试时间", actions: "操作", }, connect: { run: "连通性测试", running: "测试中…", submitted: "已提交 {{n}} 台设备测试", retest: "重新测试", }, connectDetail: "详情", connectDetailTitle: "连通性测试日志", connectDetailEmpty: "暂无日志。请先执行连通性测试;失败时会记录完整错误与跳板上下文(不含密码)。", umeSync: { sync: "同步 UME 网元", syncing: "同步中…", delete: "删除 UME 网元", deleting: "删除中…", deleteConfirm: "确定删除所有通过 UME 同步到网元管理中的网元?此操作不可恢复。", done: "UME 同步完成:新增 {{inserted}},更新 {{updated}},删除 {{deleted}},UME 清单共 {{total}} 台", deletedDone: "已删除 {{n}} 台 UME 同步网元", }, account: { batchAdd: "一键添加账号", batchByTag: "按标签添加账号", batchTitle: "批量添加账号", batchHint: "将以下账号信息应用到已选中的 {{n}} 台网元。", batchByTagHint: "将以下账号信息应用到指定标签下的网元;密码可留空,仅更新用户名。", batchDone: "已为 {{n}} 台网元更新账号", selectRequired: "请先勾选要配置账号的网元", applying: "应用中…", apply: "应用到网元", usernameOrPasswordRequired: "用户名和密码至少填写一项", passwordOptionalBatch: "留空则不修改", }, help: "【批量导入】\n" + "· 必填列:device_type、ip、username、port、protocol、name、vendor;可先下载模板。\n" + "· password 可留空(直连需填;堡垒机托管或后续批量添加代理时可空)。\n" + "· 推荐流程:先导入网元 → 勾选网元 → 点「批量添加代理」统一配置跳板/堡垒机。\n\n" + "【跳板 / 堡垒机】\n" + "· 堡垒机 SSH 用户名模板:{hop_user}@{target_user}@{target_ip}(堡垒机地址单独填在跳板地址);命令行等价:ssh 用户@目标@IP@堡垒机。\n" + "· 堡垒机托管时填「跳板密码」(Vault 密码),目标密码可留空;手动模式需填目标密码。\n" + "· JumpServer/CBH 常用跳板端口 2222,部分现场为 22。\n\n" + "【连通性 / 编辑】\n" + "· 保存密码需配置 NETX_CREDENTIAL_SECRET_KEY。\n" + "· 编辑时密码留空表示不修改;连通性失败请点「详情」查看 hop 上下文(不含密码)。", importResult: { done: "导入完成:新增 {{inserted}},更新 {{updated}},失败 {{failed}} 行", }, form: { requiredHint: "带 * 为必填项", nameConnectHint: "连通性测试成功后将自动更新为设备名称", createTitle: "新增网元", editTitle: "编辑网元", save: "保存", saving: "保存中…", cancel: "取消", created: "网元已创建", updated: "网元已更新", deleted: "网元已删除", passwordRequired: "请填写密码", passwordOptional: "留空则不修改", }, hop: { sectionTitle: "跳板 / 代理", type: "跳板类型", enable: "经跳板登录目标网元", vendor: { zte: "ZTE 设备(CLI 跳登)", huawei: "华为设备(CLI 跳登)", cisco: "思科设备(CLI 跳登)", linux: "Linux 服务器(SSH 隧道)", bastion: "堡垒机(SSH 协议代理)", }, zteHint: "在 ZTE 设备上执行 ssh/telnet 命令跳转到目标,目标账号由二次认证输入。", huaweiHint: "在华为设备上执行 telnet / stelnet(SSH)跳登;stelnet 即 SSH。目标账号由二次认证输入。", ciscoHint: "在思科设备上执行 ssh -vrf / telnet /vrf 跳登,目标账号由二次认证输入。", linuxHint: "先 SSH 登录 Linux 跳板,经 direct-tcpip 隧道连接目标 IP:端口(等同 ProxyJump)。", bastionHint: "SSH 复合用户名直连堡垒机,由堡垒机协议代理到目标。示例:bastion-user@target-user@2.2.2.2@1.1.1.1;密码为 Vault/堡垒机密码。JumpServer/CBH 常用端口 2222。", targetAuthMode: "目标凭据", targetAuthBastionManaged: "堡垒机托管(目标密码可留空)", targetAuthManual: "手动输入(连接后二次认证)", targetAuthHint: "堡垒机托管时仅需堡垒机密码;手动模式需填写目标网元密码。", usernameTemplate: "SSH 用户名模板", templateHintBastion: "默认 {hop_user}@{target_user}@{target_ip},堡垒机地址填「跳板地址」。命令行示例:ssh bastion-user@target-user@2.2.2.2@1.1.1.1。", host: "跳板地址", port: "跳板端口", protocol: "跳板协议", protocolSshStelnet: "ssh(stelnet)", username: "跳板用户名", password: "跳板密码", vrf: "管理 VRF(可选)", vpnInstance: "VPN-Instance(可选)", vrfCisco: "VRF(可选,如 MGMT)", commandTemplate: "跳登命令模板", templateHint: "ZTE 常用:telnet {target_ip}、telnet {target_ip} vrf {vrf}、ssh {target_ip}、ssh {target_ip} vrf {vrf}。按跳板协议与 VRF 自动推荐;留空时后端同样规则。目标账号密码由二次认证提示输入。", templateHintHuawei: "华为常用:telnet {target_ip}、telnet vpn-instance {vrf} {target_ip}、stelnet {target_ip}、stelnet {target_ip} -vpn-instance {vrf}。SSH 协议对应 stelnet。留空时按协议与 VPN-Instance 自动推荐。", templateHintCisco: "思科常用:ssh {target_ip}、ssh -vrf {vrf} {target_ip}、telnet {target_ip}、telnet {target_ip} /vrf {vrf}。留空时按协议与 VRF 自动推荐。", badge: { zte: "ZTE跳板", huawei: "华为跳板", cisco: "思科跳板", linux: "Linux跳板", bastion: "堡垒机", }, hostRequired: "请填写跳板地址", userRequired: "请填写跳板用户名", passwordRequired: "请填写跳板密码", batchAdd: "添加代理", batchTitle: "批量添加代理", batchHint: "将以下跳板配置应用到已选中的 {{n}} 台网元(会覆盖原有跳板设置)。", batchDone: "已为 {{n}} 台网元配置代理", selectRequired: "请先勾选要配置的网元", applying: "应用中…", apply: "应用到选中网元", }, }, ume: { token: { title: "UME Token 状态", disconnected: "disconnected", connected: "connected", connectedRenew: "connected (需续期)", expiresIn: "expires_in", needsRenew: "需续期 / 0s", preview: "preview", refreshStatus: "刷新状态", renewLogin: "手动续期/登录", renewing: "续期中…", disconnect: "断开 token", disconnecting: "断开中…", renewOkChanged: "续期成功,token 已更新", renewOkSame: "续期完成(与此前一致)", disconnectOk: "已断开 UME token", renewHint: "库中 token 缺少有效过期时间或已过期,请点「手动续期/登录」或等待后台自动续期", }, subscription: { title: "UME 告警订阅(WebSocket)", help: "订阅需手动建立/取消;建立后(或重启后若库中仍有有效订阅)后台会自动连接 WSS 接收实时告警。后台任务 alarms_current_ws_consumer 的 pause/resume 会停止或恢复 WSS 连接(不会取消 UME 订阅)。", sub: "订阅", subActive: "已建立", subInactive: "未建立", wssPaused: "已暂停", wssModeBanner: "当前告警由 WSS 实时维护(模式: {{mode}}),定时 REST 全量同步已暂停。需要全量对账时请使用下方「同步当前告警」。", serverLostBanner: "UME 服务器侧告警订阅已丢失或已过期,本地记录可能仍显示「已建立」。请确认清除本地记录后重新订阅。", establish: "建立告警订阅", establishing: "建立订阅…", reestablish: "清除本地并重新订阅", reestablishing: "重新订阅…", cancel: "取消告警订阅", cancelling: "取消订阅…", refreshStatus: "刷新订阅状态", clearLocalOnly: "仅清除本地记录", clearing: "清除中…", opFailed: "订阅操作失败", confirmClearDefault: "UME 侧告警订阅已不存在或已过期(服务器订阅已丢失)。\n\n是否清除本地订阅记录?清除后可点击「建立告警订阅」重新订阅。", confirmReestablish: "将清除本地订阅记录并在 UME 上重新建立告警订阅,是否继续?", titleLoginFirst: "请先登录 UME token", titleReestablish: "清除本地失效记录并重新向 UME 建立订阅", establishInvalid: "建立订阅未返回有效 id/uri", establishExists: "订阅已存在,未重复建立(WSS 将保持/恢复连接)", establishOk: "告警订阅已建立,WSS 将自动连接", clearLocalOk: "已清除本地订阅记录,可重新建立订阅", serverLostMsg: "UME 侧告警订阅已丢失。请确认是否清除本地订阅记录后重新订阅。", cancelFailed: "取消订阅失败:UME 侧订阅可能仍存在,请查看错误详情后重试", cancelOkMissing: "本地已清除(UME 侧订阅此前已不存在)", cancelOk: "告警订阅已取消", wsLogs: "WSS 运行日志", wsActivity: "最近活动 {{time}}", wsAutoRefresh: "自动刷新", wsLogsEmpty: "暂无日志(建立订阅并连接 WSS 后会出现连接、收包、重连等记录)", }, keyAlert: { title: "AI 告警监控(OClaw WhatsApp)", showPanel: "展开", hidePanel: "收起", help: "按 notificationId 精确匹配,或按告警描述关键字模糊匹配(不区分大小写,匹配 nativeProbableCause 等字段);可选限定 UME Inventory 中的网元类型 (ne_type),不选则匹配全部设备。经 OClaw WebSocket 推送到 WhatsApp 群。鉴权与 NETX_OCLAW_ANALYZE_TOKEN 共用。", ws: "OClaw WSS", wsConnected: "已连接", wsDisconnected: "未连接", wsDisabled: "未启用", wsPaused: "已暂停", publishedOk: "发布成功", publishedFail: "发布失败", queue: "待发队列", matchType: "匹配方式", matchNotificationId: "告警码 (notificationId)", matchKeyword: "告警描述关键字", matchValuePhNotificationId: "输入 notificationId", matchValuePhKeyword: "输入匹配关键字(不区分大小写)", label: "规则描述", labelPh: "必填,如 BGP Down", neTypesLabel: "设备类型(可选,多选)", neTypesHint: "不选表示全部设备类型;选项来自 UME Inventory 同步后的 ne_type。", neTypesEmpty: "暂无设备类型,请先同步 Inventory", neTypesAll: "全部", forwardOnClear: "告警清除时也推送", forwardOnClearHelp: "全局开关:对所有监控规则生效。默认只在告警新增/更新时推送;勾选后,UME 上报告警已清除时也会向 WhatsApp 发送清除通知。", add: "添加规则", adding: "添加中…", delete: "删除", edit: "修改", editTitle: "修改监控规则", save: "保存", saving: "保存中…", cancel: "取消", editOk: "规则已更新", pickFromAlarms: "加载当前告警参考", emptyRules: "尚未配置监控规则", colType: "类型", colMatch: "匹配内容", colLabel: "描述", colNeTypes: "设备类型", colForwardClear: "清除推送", colPublished: "发布次数", colAttempts: "尝试次数", colLast: "最近推送", colActions: "操作", colMonitor: "是否监控", monitorOn: "开启", monitorOff: "关闭", filterKeywordPh: "筛选匹配内容 / 描述", filterMatchAll: "全部类型", filterEnabledAll: "全部状态", filterEnabledOn: "监控中", filterEnabledOff: "已暂停", addOk: "已添加监控规则", deleteOk: "已删除", confirmDelete: "确定删除该监控规则?", yes: "是", no: "否", }, sync: { title: "UME 同步", inventory: "同步 Inventory", alarmsCurrent: "同步当前告警", full: "全量同步", failed: "同步失败", }, tasks: { currentTitle: "当前任务", running: "running", noRunning: "当前无运行中的任务", runtimeTitle: "后台任务", runtimeOpFailed: "后台任务操作失败", noRuntime: "暂无后台任务状态", intervalTitle: "Configured sleep between loop iterations (clamped at process start)", lastRunTitle: "Last finished sync for scheduled tasks; refreshed at each loop tick", deletedTitle: "全量对账删除条数:inventory 为网元行,alarms_current 为当前告警行,其余域多为 0", lastErrorCol: "last_error", runtimeError: { startup_alarm_sync_before_ws: "启动中:正在同步当前告警(完成后连接 WSS)…", startup_gate_waiting: "启动 REST 全量同步未完成,定时 REST 与 WSS 均待命", wss_active_skip_rest: "WSS 实时接收中,已跳过 REST 同步", pulling_alarms_current: "正在拉取 UME 当前告警…", alarms_sync_in_progress_skip: "另一条当前告警 REST 同步进行中,已跳过", pulling_inventory: "正在拉取 UME 网元清单…", ume_ws_disabled_no_base_url: "未启用或未配置 UME_BASE_URL", oclaw_fwd_disabled: "未启用或未配置 NETX_OCLAW_ALARM_WS / token / url", resumed_sync_soon: "已恢复:将跳过本轮周期等待并尽快同步", resumed_wss_reconnect: "已恢复:将尽快重连 WSS", resumed_oclaw_wss_reconnect: "已恢复:将尽快重连 OClaw WSS", resumed: "已恢复", keepalive_failed: "Token 保活失败", }, wsState: { init: "初始化", connected: "已连接", connecting: "连接中", disconnected: "已断开", no_subscription: "无订阅", waiting_token: "等待 token", paused: "已暂停", error: "连接异常", reconnecting: "重连等待", subscription_lost: "UME 订阅已丢失", disabled_no_base_url: "未启用或未配置 UME_BASE_URL", }, fwdState: { paused: "已暂停", disabled: "未启用", connecting: "连接中", connected: "已连接", }, runtimeTask: { token_keepalive: "UME Token 保活", alarms_current_auto_sync: "当前告警定时同步", alarms_current_ws_consumer: "UME 告警 WSS", oclaw_alarm_forwarder: "OClaw 关键告警 WSS", inventory_auto_sync: "Inventory 定时同步", }, }, syncStatus: { title: "同步状态", showPanel: "展开", hidePanel: "收起", empty: "暂无同步记录", }, ne: { title: "网元清单", showPanel: "展开", hidePanel: "收起", keywordPh: "keyword(ne_id/ne_name/user_label/ip/host_name)", clearTitle: "清空 keyword,回到第 1 页", expand: "展开详情", collapse: "收起详情", cliConnect: "CLI 连通", }, tabs: { main: "UME 同步", cli: "CLI 连接", }, cli: { title: "UME CLI 连接配置", showPanel: "展开", hidePanel: "收起", hint: "为 UME 清单网元配置统一 SSH 凭据与跳板/堡垒机;OClaw MCP 可通过 ume_ne_id 直接执行 show 命令,无需逐台录入 managed_ne。", statusReady: "CLI 配置已就绪,可对 UME 网元执行命令。", statusNotReady: "请填写目标用户名,并配置跳板/堡垒机(若启用)。", profileName: "配置名称", targetUsername: "目标 SSH 用户名", targetPassword: "目标 SSH 密码", passwordKeep: "留空则不修改", newProfile: "新建配置", deleteConfirm: "确定删除该 CLI 配置?", deleted: "配置已删除", saved: "CLI 配置已保存", connectTestTitle: "样本网元连通性测试", sampleNePh: "ume_ne_id(从下方网元清单复制)", sampleNeRequired: "请填写 ume_ne_id", connectTestSubmitted: "已提交连通性测试", connectTestWaiting: "等待测试结果…", connectTestRunning: "连通性测试中…", connectTestResult: "测试结果", existingProfiles: "已有配置", default: "默认", }, alarms: { title: "当前告警", movedHint: "当前告警查询已迁至网络管理 →", showPanel: "展开", hidePanel: "收起", keywordPh: "keyword(告警键/原因/ne_name/host_name/ip 等)", hostNamePh: "host_name(含匹配)", allSeverity: "全部级别", clearedAll: "is_cleared: all", clearTitle: "清空 keyword、host_name、级别、is_cleared,回到第 1 页", filterByHost: "按该主机名筛选", noHostName: "无 host_name(需先同步网元)", }, }, webcrt: { title: "WebCRT", deviceList: "设备列表", sessionManager: "设备列表", connect: "连接", hint: "选择网元,在浏览器中打开交互式终端。凭据由服务端解密,不会下发到前端。", hintCrt: "在左侧点击网元即可打开终端;支持托管、会话与 UME;也可用菜单「新建会话」快速登录。", filterKeyword: "筛选", filterKeywordPh: "按名称 / IP / 标签筛选", empty: "没有匹配的网元。可切换来源或调整搜索关键字。", open: "打开终端", opening: "连接中…", opened: "已打开 {{name}}", disconnect: "断开", closed: "会话已断开", termPlaceholder: "尚未打开终端会话", sessionMeta: "{{name}} · {{ip}}", source: { all: "全部", managed: "托管", webcrt: "会话", ume: "UME", }, newSession: { title: "新建会话", hint: "填写主机与协议后连接。SSH 弹出用户名/密码(可改);Telnet 进终端交互登录。同名会话自动加 (1)、(2)…,允许相同 IP。", connect: "连接", connecting: "连接中…", protocol: "协议", host: "主机", port: "端口", sessionName: "会话名", sessionNamePh: "可选,默认使用 IP", authTitle: "SSH 登录", savePassword: "保存密码", ipRequired: "请填写主机地址", userRequired: "请填写用户名", passwordRequired: "请填写密码", }, status: { idle: "空闲", connecting: "连接中", connected: "已连接", error: "错误", closed: "已关闭", }, phase: { creating: "创建会话", authenticating: "正在认证", waitingPrompt: "等待设备提示符", hint: "设备较慢时可能需要十几秒,请稍候", }, tabMenu: { close: "关闭", closeOthers: "关闭其他", closeAll: "关闭全部", copyIp: "复制 IP", copyIpOk: "已复制 {{ip}}", copyIpEmpty: "该标签没有 IP", }, treeMenu: { rename: "重命名", renameLabel: "会话名", renameSave: "保存", renameRequired: "请填写会话名", renamed: "会话已重命名", delete: "删除会话", deleteConfirm: "确定删除会话「{{name}}」?此操作不可恢复。", deleted: "会话已删除", }, keywordHl: { title: "关键字突出显示", enabled: "启用", newKeyword: "新建关键字", newKeywordPh: "输入关键字或正则", regex: "正则表达式", add: "添加", colKeyword: "关键字", colRegex: "正则", empty: "尚未添加关键字", moveUp: "上移", moveDown: "下移", remove: "删除", caseSensitive: "区分大小写", color: "字符颜色", saved: "关键字突出显示已保存", }, actions: { reconnect: "重新连接", recordLog: "记录日志", clear: "清空", copy: "拷贝", recording: "记录中", recordingOn: "已开始记录日志", recordingSaved: "日志已保存", copied: "已复制到剪贴板", copyEmpty: "终端内容为空", copyFailed: "复制失败", break: "Break", breakSent: "已发送 Break", broadcast: "广播", broadcastSent: "已广播到全部会话", postLogin: "登录后命令", }, favorites: "收藏", recent: "最近", favorite: "收藏/取消", encoding: "编码", fontSize: "字号", theme: "主题", themeDark: "深色", themeLight: "浅色", colorScheme: "配色方案", backgroundColor: "背景色", foregroundColor: "字体色", scheme: { dark: "深蓝(默认)", blackWhite: "白底黑字", whiteBlack: "黑底白字", greenBlack: "黑底绿字", amberBlack: "黑底琥珀", custom: "自定义", }, copyOnSelect: "选中即复制", pasteDelay: "粘贴最大行间隔", pasteDelayOff: "无延迟(整块发送)", keepalive: "SSH Keepalive", keepaliveOff: "关闭", keepaliveSec: "{{n}} 秒", options: "选项", globalSessionOptions: "全局会话选项", sessionOptionsSave: "保存", sessionOptionsCancel: "取消", sessionOptionsSaved: "已保存全局会话选项", disconnectBanner: "会话已断开", disconnectBannerError: "会话出错或连接中断", broadcastPh: "发送到全部标签…", buttonBarHint: "每行:按钮名|命令", postLoginPrompt: "登录后自动执行(每行一条,仅本设备)", postLoginSaved: "登录后命令已保存", sftp: { title: "SFTP", refresh: "刷新", up: "上级", upload: "上传", uploaded: "上传成功", uploading: "上传 {{done}}/{{total}} · {{name}} {{pct}}", downloading: "下载 {{name}} {{pct}}", uploadPartial: "上传完成 {{ok}} 个,失败 {{failed}} 个", dropHint: "松开以上传到当前目录", dropEmpty: "未识别到可上传的文件", dir: "目录", loading: "正在加载…", enterHint: "双击进入目录", downloadHint: "单击下载文件", colName: "名称", colSize: "大小", colMtime: "修改时间", colOwner: "所有者", colGroup: "组", colMode: "权限", resizeHint: "拖动调整 SFTP / 终端宽度", colResizeHint: "拖动调整列宽", }, term: { findPh: "查找…", findPrev: "上一个", findNext: "下一个", findClose: "关闭查找", copy: "复制", paste: "粘贴", clear: "清空", pasting: "粘贴中 {{done}}/{{total}} 行…", wsError: "[WebSocket 错误]", wsClosed: "[WebSocket 已关闭 code={{code}}]", sessionStatus: "[会话 {{state}}{{detail}}]", outputTruncated: "[输出过快,已丢弃 {{count}} 段]", }, err: { deviceType: "不支持的设备类型", ipConflictRestart: "数据库仍限制 IP 唯一,请重启 netx API 后再试", sessionLimit: "并发会话已达上限,请先关闭其他终端", neNotFound: "网元不存在", credsIncomplete: "网元账号或密码不完整", authRejected: "用户名或密码错误,请重新输入", cliProfile: "UME 网元需要先配置 CLI 连接模板(默认账号/跳板)", connectFailed: "登录设备失败:{{detail}}", sftpHop: "SFTP 暂不支持跳板设备,请使用直连 SSH", sftpSsh: "SFTP 仅支持 SSH 协议", sftpNeedPassword: "SFTP 需要已保存的 SSH 密码(会话弹窗密码不会用于文件传输)", sftpUnsupported: "当前 SSH 会话未提供 SFTP(设备可能未开启)", sftpTooLarge: "文件超过大小限制(默认 512MB)", queueDropped: "终端输出过快,已丢弃约 {{count}} 段,内容可能不完整", websocket: "WebSocket 连接失败", }, }, topology: { title: "拓扑管理", maps: "拓扑图", newMap: "新建", newMapName: "新拓扑图", rename: "重命名", renamePrompt: "拓扑图名称", renameHint: "双击可重命名", renamed: "拓扑图已重命名", deleteMap: "删除图", deleteMapConfirm: "删除拓扑图「{{name}}」?节点与链路会一并删除。", emptyMaps: "还没有拓扑图,先新建一张。", palette: "网元库", paletteHint: "点击或拖到画布添加", filterPh: "输入即筛:名称 / IP / 厂商", save: "保存", saveDirty: "保存 *", unsavedConfirm: "有未保存的更改,确定丢弃并切换吗?", saving: "保存中…", saved: "拓扑已保存", discover: "发现全量链路", discovering: "发现中…", discoverOne: "发现链路", discovered: "发现完成:新增 {{added}},更新 {{updated}},未发现 {{stale}}", discoverFail: "发现失败:{{detail}}", discoverOneNeedNe: "该节点未关联可扫描网元", selectMap: "请选择或新建一张拓扑图", renameNode: "重命名", renameNodePrompt: "网元显示名称", sourcePort: "本端端口", targetPort: "对端端口", canvasHint: "工具栏切换选择/平移/拖动/连线;框选多选;布局可自动构图。蓝虚线=发现链路,红虚线=未发现。快捷键 V/H/A/C,Ctrl+Z 撤销。", selected: "已选节点", selectedEdge: "已选链路", selectedCount: "已选 {{count}}", toolModes: "编辑模式", toolSelect: "选择", toolPan: "平移", toolDrag: "拖动", toolConnect: "连线", layout: "布局", layoutHierarchicalTb: "层次 · 自上而下", layoutHierarchicalLr: "层次 · 从左到右", layoutForce: "力导向", layoutGrid: "网格", layoutRadial: "环形", layoutSelected: "仅布局选中(层次)", layoutNeedSelection: "请先选中要布局的节点", align: "对齐", alignLeft: "左对齐", alignRight: "右对齐", alignTop: "顶对齐", alignBottom: "底对齐", alignHCenter: "水平居中", alignVCenter: "垂直居中", alignHDistribute: "水平分布", alignVDistribute: "垂直分布", alignNeedSelection: "请至少选中两个节点", snapGrid: "网格吸附", autoLayoutDiscover: "发现后自动布局", undo: "撤销", redo: "重做", discoverSelected: "发现选中 ({{count}})", removeSelected: "移除选中 ({{count}})", openWebcrt: "打开终端", openNe: "网元详情", removeNode: "从画布移除", removeEdge: "删除链路", nodeMenu: "网元", selectionMenu: "多选", edgeStyle: "链路样式", edgeColor: "颜色", edgeLineStyle: "线型", edgeLineSolid: "实线", edgeLineDashed: "虚线", edgeLineDotted: "点线", edgeWidth: "粗细", edgeStyleReset: "恢复默认", edgeDefaults: "默认链路样式", edgeDefaultsReset: "恢复出厂", noNeLink: "未关联托管网元", edgeManual: "人工", edgeDiscovered: "发现", edgeStale: "未发现", fit: "适应画布", fullscreen: "全屏显示", exitFullscreen: "退出全屏", display: "显示", hideIp: "隐藏 IP", hideVendor: "隐藏厂商", hidePorts: "隐藏端口", edgeFlow: "链路流动", collapseSidebar: "折叠侧栏", expandSidebar: "展开侧栏", hideAdded: "隐藏已添加", paletteEmpty: "没有匹配的网元。", paletteHiddenAll: "已添加网元已隐藏;取消勾选可重新显示。", paletteSource: "网元来源", paletteManaged: "托管网元", paletteUme: "UME 网元", paletteLoading: "加载中…", discoverReport: "发现进度", discoverClose: "关闭", discoverCancel: "取消发现", discoverProgress: "正在扫描画布上 {{count}} 台托管网元(串行登录采集 LLDP,请稍候)…", discoverProgressLive: "正在扫描 {{index}}/{{total}}:{{name}}", discoverSummary: "扫描 {{scanned}} 台 · 新增 {{added}} · 更新 {{updated}} · 未发现 {{stale}} · 失败 {{failed}}", discoverNeOk: "邻居 {{neighbors}} · 新增 {{added}} · 更新 {{updated}}", discoverNeFail: "采集失败", discoverUnmatched: "未匹配 {{count}}", discoverUnmatchedMore: "另有 {{count}} 条未列出", discoverParserStub: "厂商解析器「{{parser}}」仍为 stub,已采集到输出但未能解析邻居", discoverNoTargets: "画布上没有可扫描网元。请添加托管网元,或添加已配置 CLI 凭据的 UME 网元。", discoverFilter: "结果筛选", discoverFilterIssues: "问题", discoverFilterFail: "失败", discoverFilterWarn: "警告", discoverFilterOk: "成功", discoverFilterAll: "全部", discoverFilterDetail: "详情", discoverListTitle: "发现详情", discoverListEmpty: "当前筛选下没有网元。", discoverShowLimited: "仅显示前 {{shown}} / {{total}} 条(请用筛选缩小范围)", discoverViewDetail: "详情", discoverLinkCount: "链路 {{count}}", discoverLinksTitle: "匹配链路({{count}})", discoverLinksEmpty: "本次未匹配到画布上的对端网元链路。", discoverUnmatchedTitle: "未匹配邻居({{count}})", discoverUnmatchedEmpty: "无未匹配邻居。", discoverColPeer: "对端网元", discoverColRemote: "邻居", discoverColLocalPort: "本端端口", discoverColRemotePort: "对端端口", discoverColProtocol: "协议", discoverColAction: "结果", discoverLinkAdded: "新增", discoverLinkUpdated: "更新", discoverLinkKeptManual: "保留人工", discoverLocatePeer: "定位对端", discoverLocateNe: "定位本端", discoverRawPreview: "采集原文预览(过长会截断,不影响解析)", findNode: "定位", findNodePh: "输入即搜:名称 / IP / 厂商", findNoMatch: "画布上没有匹配的节点", findMore: "另有 {{count}} 条匹配…", locateOnCanvas: "点击定位到画布", openPortTraffic: "打开端口流量", removeStale: "清除未发现 ({{count}})", removeStaleHint: "删除红色标记的未发现链路", staleRemoved: "已删除 {{count}} 条未发现链路", connectHint: "连线模式:依次点击源节点 → 目标节点(Esc 或切回选择退出)", }, }; export default zh;