feat(国际化): 添加运维监控多语言支持

- 添加英文翻译(en.ts)包含 ops 监控所有文案
- 添加中文翻译(zh.ts)包含 ops 监控所有文案
This commit is contained in:
IanShaw027
2026-01-09 20:59:33 +08:00
parent 337a188660
commit fc32b57798
2 changed files with 764 additions and 0 deletions

View File

@@ -131,6 +131,7 @@ export default {
noData: 'No data',
success: 'Success',
error: 'Error',
critical: 'Critical',
warning: 'Warning',
info: 'Info',
active: 'Active',
@@ -145,6 +146,8 @@ export default {
copiedToClipboard: 'Copied to clipboard',
copyFailed: 'Failed to copy',
contactSupport: 'Contact Support',
add: 'Add',
invalidEmail: 'Please enter a valid email address',
selectOption: 'Select an option',
searchPlaceholder: 'Search...',
noOptionsFound: 'No options found',
@@ -177,6 +180,7 @@ export default {
accounts: 'Accounts',
proxies: 'Proxies',
redeemCodes: 'Redeem Codes',
ops: 'Ops',
settings: 'Settings',
myAccount: 'My Account',
lightMode: 'Light Mode',
@@ -1713,6 +1717,370 @@ export default {
failedToLoad: 'Failed to load usage records'
},
// Ops Monitoring
ops: {
title: 'Ops Monitoring',
description: 'Operational monitoring and troubleshooting',
// Dashboard
systemHealth: 'System Health',
overview: 'Overview',
noSystemMetrics: 'No system metrics collected yet.',
collectedAt: 'Collected at:',
window: 'window',
cpu: 'CPU',
memory: 'Memory',
db: 'DB',
redis: 'Redis',
goroutines: 'Goroutines',
jobs: 'Jobs',
active: 'active',
idle: 'idle',
ok: 'ok',
lastRun: 'last_run:',
lastSuccess: 'last_success:',
lastError: 'last_error:',
noData: 'No data.',
loadingText: 'loading',
ready: 'ready',
requestsTotal: 'Requests (total)',
slaScope: 'SLA scope:',
tokens: 'Tokens',
tps: 'TPS:',
current: 'current',
peak: 'peak',
sla: 'SLA (excl business limits)',
businessLimited: 'business_limited:',
errors: 'Errors',
errorRate: 'error_rate:',
upstreamRate: 'upstream_rate:',
latencyDuration: 'Latency (duration_ms)',
ttftLabel: 'TTFT (first_token_ms)',
p50: 'p50:',
p90: 'p90:',
p95: 'p95:',
p99: 'p99:',
avg: 'avg:',
max: 'max:',
qps: 'QPS',
requests: 'Requests',
upstream: 'Upstream',
client: 'Client',
system: 'System',
other: 'Other',
errorsSla: 'Errors (SLA scope)',
upstreamExcl429529: 'Upstream (excl 429/529)',
failedToLoadData: 'Failed to load ops data.',
tpsK: 'TPS (K)',
top: 'Top:',
throughputTrend: 'Throughput Trend',
latencyHistogram: 'Latency Histogram',
errorTrend: 'Error Trend',
errorDistribution: 'Error Distribution',
// Error Log
errorLog: {
timeId: 'Time / ID',
context: 'Context',
status: 'Status',
message: 'Message',
latency: 'Latency',
action: 'Action',
noErrors: 'No errors in this window.',
grp: 'GRP:',
acc: 'ACC:',
details: 'Details',
phase: 'Phase'
},
// Error Details Modal
errorDetails: {
upstreamErrors: 'Upstream Errors',
requestErrors: 'Request Errors',
total: 'Total:',
searchPlaceholder: 'Search request_id / client_request_id / message',
accountIdPlaceholder: 'account_id'
},
// Error Detail Modal
errorDetail: {
loading: 'Loading…',
requestId: 'Request ID',
time: 'Time',
phase: 'Phase',
status: 'Status',
message: 'Message',
basicInfo: 'Basic Info',
platform: 'Platform',
model: 'Model',
latency: 'Latency',
ttft: 'TTFT',
businessLimited: 'Business Limited',
requestPath: 'Request Path',
timings: 'Timings',
auth: 'Auth',
routing: 'Routing',
upstream: 'Upstream',
response: 'Response',
retry: 'Retry',
retryClient: 'Retry (Client)',
retryUpstream: 'Retry (Upstream pinned)',
pinnedAccountId: 'Pinned account_id',
retryNotes: 'Retry Notes',
requestBody: 'Request Body',
errorBody: 'Error Body',
trimmed: 'trimmed',
confirmRetry: 'Confirm Retry',
retrySuccess: 'Retry succeeded',
retryFailed: 'Retry failed',
na: 'N/A',
retryHint: 'Retry will resend the request with the same parameters',
retryClientHint: 'Use client retry (no account pinning)',
retryUpstreamHint: 'Use upstream pinned retry (pin to the error account)',
pinnedAccountIdHint: '(auto from error log)',
retryNote1: 'Retry will use the same request body and parameters',
retryNote2: 'If the original request failed due to account issues, pinned retry may still fail',
retryNote3: 'Client retry will reselect an account',
confirmRetryMessage: 'Confirm retry this request?',
confirmRetryHint: 'Will resend with the same request parameters'
},
requestDetails: {
title: 'Request Details',
details: 'Details',
rangeLabel: 'Window: {range}',
rangeMinutes: '{n} minutes',
rangeHours: '{n} hours',
empty: 'No requests in this window.',
emptyHint: 'Try a different time range or remove filters.',
failedToLoad: 'Failed to load request details',
requestIdCopied: 'Request ID copied',
copyFailed: 'Copy failed',
copy: 'Copy',
viewError: 'View Error',
kind: {
success: 'SUCCESS',
error: 'ERROR'
},
table: {
time: 'Time',
kind: 'Kind',
platform: 'Platform',
model: 'Model',
duration: 'Duration',
status: 'Status',
requestId: 'Request ID',
actions: 'Actions'
}
},
alertEvents: {
title: 'Alert Events',
description: 'Recent alert firing/resolution records (email-only)',
loading: 'Loading...',
empty: 'No alert events',
loadFailed: 'Failed to load alert events',
table: {
time: 'Time',
status: 'Status',
severity: 'Severity',
title: 'Title',
metric: 'Metric / Threshold',
email: 'Email Sent'
}
},
alertRules: {
title: 'Alert Rules',
description: 'Create and manage threshold-based system alerts (email-only)',
loading: 'Loading...',
empty: 'No alert rules',
loadFailed: 'Failed to load alert rules',
saveFailed: 'Failed to save alert rule',
deleteFailed: 'Failed to delete alert rule',
create: 'Create Rule',
createTitle: 'Create Alert Rule',
editTitle: 'Edit Alert Rule',
deleteConfirmTitle: 'Delete this rule?',
deleteConfirmMessage: 'This will remove the rule and its related events. Continue?',
metrics: {
successRate: 'Success Rate (%)',
errorRate: 'Error Rate (%)',
p95: 'P95 Latency (ms)',
p99: 'P99 Latency (ms)',
cpu: 'CPU Usage (%)',
memory: 'Memory Usage (%)',
queueDepth: 'Concurrency Queue Depth'
},
table: {
name: 'Name',
metric: 'Metric',
severity: 'Severity',
enabled: 'Enabled',
actions: 'Actions'
},
form: {
name: 'Name',
description: 'Description',
metric: 'Metric',
operator: 'Operator',
threshold: 'Threshold',
severity: 'Severity',
window: 'Window (minutes)',
sustained: 'Sustained (samples)',
cooldown: 'Cooldown (minutes)',
enabled: 'Enabled',
notifyEmail: 'Send email notifications'
},
validation: {
title: 'Please fix the following issues',
invalid: 'Invalid rule',
nameRequired: 'Name is required',
metricRequired: 'Metric is required',
operatorRequired: 'Operator is required',
thresholdRequired: 'Threshold must be a number',
windowRange: 'Window must be one of: 1, 5, 60 minutes',
sustainedRange: 'Sustained must be between 1 and 1440 samples',
cooldownRange: 'Cooldown must be between 0 and 1440 minutes'
}
},
runtime: {
title: 'Ops Runtime Settings',
description: 'Stored in database; changes take effect without editing config files.',
loading: 'Loading...',
noData: 'No runtime settings available',
loadFailed: 'Failed to load runtime settings',
saveSuccess: 'Runtime settings saved',
saveFailed: 'Failed to save runtime settings',
alertTitle: 'Alert Evaluator',
groupAvailabilityTitle: 'Group Availability Monitor',
evalIntervalSeconds: 'Evaluation Interval (seconds)',
silencing: {
title: 'Alert Silencing (Maintenance Mode)',
enabled: 'Enable silencing',
globalUntil: 'Silence until (RFC3339)',
untilPlaceholder: '2026-01-05T00:00:00Z',
untilHint: 'Leave empty to only toggle silencing without an expiry (not recommended).',
reason: 'Reason',
reasonPlaceholder: 'e.g., planned maintenance',
entries: {
title: 'Advanced: targeted silencing',
hint: 'Optional: silence only certain rules or severities. Leave fields empty to match all.',
add: 'Add Entry',
empty: 'No targeted entries',
entryTitle: 'Entry #{n}',
ruleId: 'Rule ID (optional)',
ruleIdPlaceholder: 'e.g., 1',
severities: 'Severities (optional)',
severitiesPlaceholder: 'e.g., P0,P1 (empty = all)',
until: 'Until (RFC3339)',
reason: 'Reason',
validation: {
untilRequired: 'Entry until time is required',
untilFormat: 'Entry until time must be a valid RFC3339 timestamp',
ruleIdPositive: 'Entry rule_id must be a positive integer',
severitiesFormat: 'Entry severities must be a comma-separated list of P0..P3'
}
},
validation: {
timeFormat: 'Silence time must be a valid RFC3339 timestamp'
}
},
lockEnabled: 'Distributed Lock Enabled',
lockKey: 'Distributed Lock Key',
lockTTLSeconds: 'Distributed Lock TTL (seconds)',
showAdvancedDeveloperSettings: 'Show advanced developer settings (Distributed Lock)',
advancedSettingsSummary: 'Advanced settings (Distributed Lock)',
evalIntervalHint: 'How often the evaluator runs. Keeping the default is recommended.',
validation: {
title: 'Please fix the following issues',
invalid: 'Invalid settings',
evalIntervalRange: 'Evaluation interval must be between 1 and 86400 seconds',
lockKeyRequired: 'Distributed lock key is required when lock is enabled',
lockKeyPrefix: 'Distributed lock key must start with "{prefix}"',
lockKeyHint: 'Recommended: start with "{prefix}" to avoid conflicts',
lockTtlRange: 'Distributed lock TTL must be between 1 and 86400 seconds'
}
},
email: {
title: 'Email Notification',
description: 'Configure alert/report email notifications (stored in database).',
loading: 'Loading...',
noData: 'No email notification config',
loadFailed: 'Failed to load email notification config',
saveSuccess: 'Email notification config saved',
saveFailed: 'Failed to save email notification config',
alertTitle: 'Alert Emails',
reportTitle: 'Report Emails',
recipients: 'Recipients',
recipientsHint: 'If empty, the system may fallback to the first admin email.',
minSeverity: 'Min Severity',
minSeverityAll: 'All severities',
rateLimitPerHour: 'Rate limit per hour',
batchWindowSeconds: 'Batch window (seconds)',
includeResolved: 'Include resolved alerts',
dailySummary: 'Daily summary',
weeklySummary: 'Weekly summary',
errorDigest: 'Error digest',
errorDigestMinCount: 'Min errors for digest',
accountHealth: 'Account health',
accountHealthThreshold: 'Error rate threshold (%)',
cronPlaceholder: 'Cron expression',
reportHint: 'Schedules use cron syntax; leave empty to use defaults.',
validation: {
title: 'Please fix the following issues',
invalid: 'Invalid email notification config',
alertRecipientsRequired: 'Alert emails are enabled but no recipients are configured',
reportRecipientsRequired: 'Report emails are enabled but no recipients are configured',
invalidRecipients: 'One or more recipient emails are invalid',
rateLimitRange: 'Rate limit per hour must be a number ≥ 0',
batchWindowRange: 'Batch window must be between 0 and 86400 seconds',
cronRequired: 'A cron expression is required when schedule is enabled',
cronFormat: 'Cron expression format looks invalid (expected at least 5 parts)',
digestMinCountRange: 'Min errors for digest must be a number ≥ 0',
accountHealthThresholdRange: 'Account health threshold must be between 0 and 100'
}
},
concurrency: {
title: 'Concurrency / Queue',
byPlatform: 'By Platform',
byGroup: 'By Group',
byAccount: 'By Account',
totalRows: '{count} rows',
disabledHint: 'Realtime monitoring is disabled in settings.',
empty: 'No data',
queued: 'Queue {count}',
rateLimited: 'Rate-limited {count}',
errorAccounts: 'Errors {count}',
loadFailed: 'Failed to load concurrency data'
},
realtime: {
connected: 'Realtime connected',
connecting: 'Realtime connecting',
reconnecting: 'Realtime reconnecting',
offline: 'Realtime offline',
closed: 'Realtime closed',
reconnectIn: 'retry in {seconds}s'
},
queryMode: {
auto: 'Auto',
raw: 'Raw',
preagg: 'Preagg'
},
accountAvailability: {
available: 'Available',
unavailable: 'Unavailable',
accountError: 'Error'
},
tooltips: {
throughputTrend: 'Requests/QPS + Tokens/TPS in the selected window.',
latencyHistogram: 'Latency distribution (duration_ms) for successful requests.',
errorTrend: 'Error counts over time (SLA scope excludes business limits; upstream excludes 429/529).',
errorDistribution: 'Error distribution by status code.'
},
charts: {
emptyRequest: 'No requests in this window.',
emptyError: 'No errors in this window.',
resetZoom: 'Reset',
resetZoomHint: 'Reset zoom (if enabled)',
downloadChart: 'Download',
downloadChartHint: 'Download chart as image'
}
},
// Settings
settings: {
title: 'System Settings',
@@ -1803,6 +2171,20 @@ export default {
sending: 'Sending...',
enterRecipientHint: 'Please enter a recipient email address'
},
opsMonitoring: {
title: 'Ops Monitoring',
description: 'Enable ops monitoring for troubleshooting and health visibility',
disabled: 'Ops monitoring is disabled',
enabled: 'Enable Ops Monitoring',
enabledHint: 'Enable the ops monitoring module (admin only)',
realtimeEnabled: 'Enable Realtime Monitoring',
realtimeEnabledHint: 'Enable realtime QPS/metrics push (WebSocket)',
queryMode: 'Default Query Mode',
queryModeHint: 'Default query mode for Ops Dashboard (auto/raw/preagg)',
queryModeAuto: 'Auto (recommended)',
queryModeRaw: 'Raw (most accurate, slower)',
queryModePreagg: 'Preagg (fastest, requires aggregation)'
},
adminApiKey: {
title: 'Admin API Key',
description: 'Global API key for external system integration with full admin access',

View File

@@ -128,6 +128,7 @@ export default {
noData: '暂无数据',
success: '成功',
error: '错误',
critical: '严重',
warning: '警告',
info: '提示',
active: '启用',
@@ -142,6 +143,8 @@ export default {
copiedToClipboard: '已复制到剪贴板',
copyFailed: '复制失败',
contactSupport: '联系客服',
add: '添加',
invalidEmail: '请输入有效的邮箱地址',
selectOption: '请选择',
searchPlaceholder: '搜索...',
noOptionsFound: '无匹配选项',
@@ -175,6 +178,7 @@ export default {
accounts: '账号管理',
proxies: 'IP管理',
redeemCodes: '兑换码',
ops: '运维监控',
settings: '系统设置',
myAccount: '我的账户',
lightMode: '浅色模式',
@@ -1858,6 +1862,370 @@ export default {
failedToLoad: '加载使用记录失败'
},
// Ops Monitoring
ops: {
title: '运维监控',
description: '运维监控与排障',
// Dashboard
systemHealth: '系统健康',
overview: '概览',
noSystemMetrics: '尚未收集系统指标。',
collectedAt: '采集时间:',
window: '窗口',
cpu: 'CPU',
memory: '内存',
db: '数据库',
redis: 'Redis',
goroutines: '协程',
jobs: '后台任务',
active: '活跃',
idle: '空闲',
ok: '正常',
lastRun: '最近运行',
lastSuccess: '最近成功',
lastError: '最近错误',
noData: '暂无数据',
loadingText: '加载中...',
ready: '就绪',
requestsTotal: '请求(总计)',
slaScope: 'SLA 范围:',
tokens: 'Token',
tps: 'TPS',
current: '当前',
peak: '峰值',
sla: 'SLA排除业务限制',
businessLimited: '业务限制:',
errors: '错误',
errorRate: '错误率:',
upstreamRate: '上游错误率:',
latencyDuration: '延迟 (duration_ms)',
ttftLabel: 'TTFT (first_token_ms)',
p50: 'p50',
p90: 'p90',
p95: 'p95',
p99: 'p99',
avg: 'avg',
max: 'max',
qps: 'QPS',
requests: '请求',
upstream: '上游',
client: '客户端',
system: '系统',
other: '其他',
errorsSla: '错误SLA范围',
upstreamExcl429529: '上游排除429/529',
failedToLoadData: '加载运维数据失败',
tpsK: 'TPS (K)',
top: '最高:',
throughputTrend: '吞吐趋势',
latencyHistogram: '延迟分布',
errorTrend: '错误趋势',
errorDistribution: '错误分布',
// Error Log
errorLog: {
timeId: '时间 / ID',
context: '上下文',
status: '状态码',
message: '消息',
latency: '延迟',
action: '操作',
noErrors: '该窗口内暂无错误。',
grp: 'GRP',
acc: 'ACC',
details: '详情',
phase: '阶段'
},
// Error Details Modal
errorDetails: {
upstreamErrors: '上游错误',
requestErrors: '请求错误',
total: '总计:',
searchPlaceholder: '搜索 request_id / client_request_id / message',
accountIdPlaceholder: 'account_id'
},
// Error Detail Modal
errorDetail: {
loading: '加载中…',
requestId: '请求 ID',
time: '时间',
phase: '阶段',
status: '状态码',
message: '消息',
basicInfo: '基本信息',
platform: '平台',
model: '模型',
latency: '延迟',
ttft: 'TTFT',
businessLimited: '业务限制',
requestPath: '请求路径',
timings: '时序信息',
auth: '认证',
routing: '路由',
upstream: '上游',
response: '响应',
retry: '重试',
retryClient: '重试(客户端)',
retryUpstream: '重试(上游固定)',
pinnedAccountId: '固定 account_id',
retryNotes: '重试说明',
requestBody: '请求体',
errorBody: '错误体',
trimmed: '已截断',
confirmRetry: '确认重试',
retrySuccess: '重试成功',
retryFailed: '重试失败',
na: 'N/A',
retryHint: '重试将使用相同的请求参数重新发送请求',
retryClientHint: '使用客户端重试(不固定账号)',
retryUpstreamHint: '使用上游固定重试(固定到错误的账号)',
pinnedAccountIdHint: '(自动从错误日志获取)',
retryNote1: '重试会使用相同的请求体和参数',
retryNote2: '如果原请求失败是因为账号问题,固定重试可能仍会失败',
retryNote3: '客户端重试会重新选择账号',
confirmRetryMessage: '确认要重试该请求吗?',
confirmRetryHint: '将使用相同的请求参数重新发送'
},
requestDetails: {
title: '请求明细',
details: '明细',
rangeLabel: '窗口:{range}',
rangeMinutes: '{n} 分钟',
rangeHours: '{n} 小时',
empty: '该窗口内暂无请求。',
emptyHint: '可尝试调整时间范围或取消部分筛选。',
failedToLoad: '加载请求明细失败',
requestIdCopied: '请求ID已复制',
copyFailed: '复制失败',
copy: '复制',
viewError: '查看错误',
kind: {
success: '成功',
error: '失败'
},
table: {
time: '时间',
kind: '类型',
platform: '平台',
model: '模型',
duration: '耗时',
status: '状态码',
requestId: '请求ID',
actions: '操作'
}
},
alertEvents: {
title: '告警事件',
description: '最近的告警触发/恢复记录(仅邮件通知)',
loading: '加载中...',
empty: '暂无告警事件',
loadFailed: '加载告警事件失败',
table: {
time: '时间',
status: '状态',
severity: '级别',
title: '标题',
metric: '指标 / 阈值',
email: '邮件已发送'
}
},
alertRules: {
title: '告警规则',
description: '创建与管理系统阈值告警(仅邮件通知)',
loading: '加载中...',
empty: '暂无告警规则',
loadFailed: '加载告警规则失败',
saveFailed: '保存告警规则失败',
deleteFailed: '删除告警规则失败',
create: '新建规则',
createTitle: '新建告警规则',
editTitle: '编辑告警规则',
deleteConfirmTitle: '确认删除该规则?',
deleteConfirmMessage: '将删除该规则及其关联的告警事件,是否继续?',
metrics: {
successRate: '成功率 (%)',
errorRate: '错误率 (%)',
p95: 'P95 延迟 (ms)',
p99: 'P99 延迟 (ms)',
cpu: 'CPU 使用率 (%)',
memory: '内存使用率 (%)',
queueDepth: '并发排队深度'
},
table: {
name: '名称',
metric: '指标',
severity: '级别',
enabled: '启用',
actions: '操作'
},
form: {
name: '名称',
description: '描述',
metric: '指标',
operator: '运算符',
threshold: '阈值',
severity: '级别',
window: '统计窗口(分钟)',
sustained: '连续样本数(每分钟)',
cooldown: '冷却期(分钟)',
enabled: '启用',
notifyEmail: '发送邮件通知'
},
validation: {
title: '请先修正以下问题',
invalid: '规则不合法',
nameRequired: '名称不能为空',
metricRequired: '指标不能为空',
operatorRequired: '运算符不能为空',
thresholdRequired: '阈值必须为数字',
windowRange: '统计窗口必须为 1 / 5 / 60 分钟之一',
sustainedRange: '连续样本数必须在 1 到 1440 之间',
cooldownRange: '冷却期必须在 0 到 1440 分钟之间'
}
},
runtime: {
title: '运维监控运行设置',
description: '配置存储在数据库中,无需修改 config 文件即可生效。',
loading: '加载中...',
noData: '暂无运行设置',
loadFailed: '加载运行设置失败',
saveSuccess: '运行设置已保存',
saveFailed: '保存运行设置失败',
alertTitle: '告警评估器',
groupAvailabilityTitle: '分组可用性监控',
evalIntervalSeconds: '评估间隔(秒)',
silencing: {
title: '告警静默(维护模式)',
enabled: '启用静默',
globalUntil: '静默截止时间RFC3339',
untilPlaceholder: '2026-01-05T00:00:00Z',
untilHint: '建议填写截止时间,避免忘记关闭静默。',
reason: '原因',
reasonPlaceholder: '例如:计划维护',
entries: {
title: '高级:定向静默',
hint: '可选:仅静默特定规则或特定级别。字段留空表示匹配全部。',
add: '新增条目',
empty: '暂无定向静默条目',
entryTitle: '条目 #{n}',
ruleId: '规则ID可选',
ruleIdPlaceholder: '例如1',
severities: '级别(可选)',
severitiesPlaceholder: '例如P0,P1留空=全部)',
until: '截止时间RFC3339',
reason: '原因',
validation: {
untilRequired: '条目截止时间不能为空',
untilFormat: '条目截止时间必须为合法的 RFC3339 时间戳',
ruleIdPositive: '条目 rule_id 必须为正整数',
severitiesFormat: '条目级别必须为 P0..P3 的逗号分隔列表'
}
},
validation: {
timeFormat: '静默时间必须为合法的 RFC3339 时间戳'
}
},
lockEnabled: '启用分布式锁',
lockKey: '分布式锁 Key',
lockTTLSeconds: '分布式锁 TTL',
showAdvancedDeveloperSettings: '显示高级开发者设置 (Distributed Lock)',
advancedSettingsSummary: '高级设置 (分布式锁)',
evalIntervalHint: '检测任务的执行频率,建议保持默认。',
validation: {
title: '请先修正以下问题',
invalid: '设置不合法',
evalIntervalRange: '评估间隔必须在 1 到 86400 秒之间',
lockKeyRequired: '启用分布式锁时必须填写 Lock Key',
lockKeyPrefix: '分布式锁 Key 必须以「{prefix}」开头',
lockKeyHint: '建议以「{prefix}」开头以避免冲突',
lockTtlRange: '分布式锁 TTL 必须在 1 到 86400 秒之间'
}
},
email: {
title: '邮件通知配置',
description: '配置告警/报告邮件通知(存储在数据库中)。',
loading: '加载中...',
noData: '暂无邮件通知配置',
loadFailed: '加载邮件通知配置失败',
saveSuccess: '邮件通知配置已保存',
saveFailed: '保存邮件通知配置失败',
alertTitle: '告警邮件',
reportTitle: '报告邮件',
recipients: '收件人',
recipientsHint: '若为空,系统可能会回退使用第一个管理员邮箱。',
minSeverity: '最低级别',
minSeverityAll: '全部级别',
rateLimitPerHour: '每小时限额',
batchWindowSeconds: '合并窗口(秒)',
includeResolved: '包含恢复通知',
dailySummary: '每日摘要',
weeklySummary: '每周摘要',
errorDigest: '错误摘要',
errorDigestMinCount: '错误摘要最小数量',
accountHealth: '账号健康报告',
accountHealthThreshold: '错误率阈值(%',
cronPlaceholder: 'Cron 表达式',
reportHint: '发送时间使用 Cron 语法;留空将使用默认值。',
validation: {
title: '请先修正以下问题',
invalid: '邮件通知配置不合法',
alertRecipientsRequired: '已启用告警邮件,但未配置任何收件人',
reportRecipientsRequired: '已启用报告邮件,但未配置任何收件人',
invalidRecipients: '存在不合法的收件人邮箱',
rateLimitRange: '每小时限额必须为 ≥ 0 的数字',
batchWindowRange: '合并窗口必须在 0 到 86400 秒之间',
cronRequired: '启用定时任务时必须填写 Cron 表达式',
cronFormat: 'Cron 表达式格式可能不正确(至少应包含 5 段)',
digestMinCountRange: '错误摘要最小数量必须为 ≥ 0 的数字',
accountHealthThresholdRange: '账号健康错误率阈值必须在 0 到 100 之间'
}
},
concurrency: {
title: '并发 / 排队',
byPlatform: '按平台',
byGroup: '按分组',
byAccount: '按账号',
totalRows: '共 {count} 项',
disabledHint: '已在设置中关闭实时监控。',
empty: '暂无数据',
queued: '队列 {count}',
rateLimited: '限流 {count}',
errorAccounts: '异常 {count}',
loadFailed: '加载并发数据失败'
},
realtime: {
connected: '实时已连接',
connecting: '实时连接中',
reconnecting: '实时重连中',
offline: '实时离线',
closed: '实时已关闭',
reconnectIn: '重连 {seconds}s'
},
queryMode: {
auto: 'Auto自动',
raw: 'Raw不聚合',
preagg: 'Preagg聚合'
},
accountAvailability: {
available: '可用',
unavailable: '不可用',
accountError: '异常'
},
tooltips: {
throughputTrend: '当前窗口内的请求/QPS 与 token/TPS 趋势。',
latencyHistogram: '成功请求的延迟分布duration_ms。',
errorTrend: '错误趋势SLA 口径排除业务限制;上游错误率排除 429/529。',
errorDistribution: '按状态码统计的错误分布。'
},
charts: {
emptyRequest: '该时间窗口内暂无请求。',
emptyError: '该时间窗口内暂无错误。',
resetZoom: '重置',
resetZoomHint: '重置缩放(若启用)',
downloadChart: '下载',
downloadChartHint: '下载图表图片'
}
},
// Settings
settings: {
title: '系统设置',
@@ -1947,6 +2315,20 @@ export default {
sending: '发送中...',
enterRecipientHint: '请输入收件人邮箱地址'
},
opsMonitoring: {
title: '运维监控',
description: '启用运维监控模块,用于排障与健康可视化',
disabled: '运维监控已关闭',
enabled: '启用运维监控',
enabledHint: '启用 Ops 运维监控模块(仅管理员可见)',
realtimeEnabled: '启用实时监控',
realtimeEnabledHint: '启用实时 QPS/指标推送WebSocket',
queryMode: '默认查询模式',
queryModeHint: 'Ops Dashboard 默认查询模式auto/raw/preagg',
queryModeAuto: '自动(推荐)',
queryModeRaw: 'Raw最准但较慢',
queryModePreagg: 'Preagg最快需预聚合'
},
adminApiKey: {
title: '管理员 API Key',
description: '用于外部系统集成的全局 API Key拥有完整的管理员权限',