From d6e4a6a0893df1c5b28230984527fae7d92d364d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E5=93=A5?= <2982212683@qq.com> Date: Sun, 24 May 2026 21:29:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=AD=E8=A8=80=E8=A1=A5?= =?UTF-8?q?=E4=B8=81=E7=9A=84=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4,?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8E=86=E5=8F=B2=E6=97=A5=E5=BF=97=E7=9A=84?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/monitor/routers.py | 184 +- docs/spec/MDS-i18n-Implementation-Proposal.md | 1112 ++++++++++ docs/spec/MDS-i18n-Task-Plan.md | 1926 +++++++++++++++++ static/lib/i18n/de-DE.js | 845 ++++---- static/lib/i18n/en-US.js | 845 ++++---- static/lib/i18n/zh-CN.js | 845 ++++---- static/monitor/history-logs.html | 529 +++-- static/monitor/index.html | 314 +-- static/monitor/js/monitor.js | 358 +-- static/monitor/live-logs.html | 36 +- 10 files changed, 5183 insertions(+), 1811 deletions(-) create mode 100644 docs/spec/MDS-i18n-Implementation-Proposal.md create mode 100644 docs/spec/MDS-i18n-Task-Plan.md diff --git a/apps/common/monitor/routers.py b/apps/common/monitor/routers.py index 6f6e383..d22aeeb 100644 --- a/apps/common/monitor/routers.py +++ b/apps/common/monitor/routers.py @@ -4,6 +4,20 @@ 提供监控相关的 API 端点 """ +import time +import json +import asyncio +from datetime import datetime, timedelta, timezone +from fastapi import APIRouter, HTTPException, WebSocket +from fastapi.responses import JSONResponse, StreamingResponse +from typing import Dict, Any, List, Optional +from tortoise import Tortoise +from .service import monitor_service +from .log_stream_service import log_stream_service +from .storage import request_storage, outbound_request_storage, system_log_storage +from .models import APIRequest, OutboundAPIRequest, SystemLog +from core.settings import TIMEZONE +from globalobjects import logger as log_config import time import json import asyncio @@ -1030,6 +1044,8 @@ async def get_history_by_time_range( http_requests = await request_storage.get_requests_with_filters( utc_start, utc_end, limit, filter_params ) + print(f"[DEBUG] HTTP查询: page={page}, page_size={page_size}, 返回{len(http_requests)}条") + # 列表查询只返回基本字段,不返回request_body/response_body大字段(详情时懒加载) result["http_requests"] = [{ "id": req.id, "timestamp": req.timestamp.isoformat(), @@ -1042,11 +1058,8 @@ async def get_history_by_time_range( "user_agent": req.user_agent, "is_slow": req.is_slow, "is_error": req.is_error, - "error_message": req.error_message, - "request_body": req.request_body, - "response_body": req.response_body, - "request_headers": getattr(req, 'request_headers', None), - "response_headers": getattr(req, 'response_headers', None) + "error_message": req.error_message + # 不返回: request_body, response_body, request_headers, response_headers } for req in http_requests] # 查询发送请求 @@ -1054,6 +1067,8 @@ async def get_history_by_time_range( outbound_requests = await outbound_request_storage.get_requests_with_filters( utc_start, utc_end, limit, filter_params ) + print(f"[DEBUG] Outbound查询: page={page}, page_size={page_size}, 返回{len(outbound_requests)}条") + # 列表查询只返回基本字段,不返回request_body/response_body大字段 result["outbound_requests"] = [{ "id": req.id, "timestamp": req.timestamp.isoformat(), @@ -1064,11 +1079,8 @@ async def get_history_by_time_range( "module": req.module, "is_slow": req.is_slow, "is_error": req.is_error, - "error_message": req.error_message, - "request_body": req.request_body, - "response_body": req.response_body, - "request_headers": req.request_headers, - "response_headers": req.response_headers + "error_message": req.error_message + # 不返回: request_body, response_body, request_headers, response_headers } for req in outbound_requests] # 查询系统日志 @@ -1076,6 +1088,8 @@ async def get_history_by_time_range( logs = await system_log_storage.get_logs_with_filters( utc_start, utc_end, level, limit, filter_params ) + print(f"[DEBUG] Logs查询: page={page}, page_size={page_size}, 返回{len(logs)}条") + # 列表查询不返回stack_trace大字段(详情时懒加载) result["logs"] = [{ "id": log.id, "timestamp": log.timestamp.isoformat(), @@ -1083,18 +1097,25 @@ async def get_history_by_time_range( "module": log.module, "function": log.function, "line_number": log.line_number, - "message": log.message, - "stack_trace": log.stack_trace + "message": log.message[:500] if log.message else None # 截断message,避免超长日志 + # 不返回: stack_trace } for log in logs] - # 计算分页元数据 + # 统计总数(用于结果摘要显示)- 只执行一次count + result["stats"] = { + "http_count": await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_http else 0, + "outbound_count": await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_outbound else 0, + "logs_count": await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params) if should_query_logs else 0 + } + + # 计算分页元数据(复用stats的count结果) total_count = 0 if should_query_http: - total_count = await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) + total_count = result["stats"]["http_count"] elif should_query_outbound: - total_count = await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) + total_count = result["stats"]["outbound_count"] elif should_query_logs: - total_count = await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params) + total_count = result["stats"]["logs_count"] if total_count > 0: total_pages = (total_count + page_size - 1) // page_size @@ -1109,21 +1130,36 @@ async def get_history_by_time_range( "end_index": min(page * page_size, total_count) } - # 统计总数(用于结果摘要显示) - result["stats"] = { - "http_count": await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_http else 0, - "outbound_count": await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_outbound else 0, - "logs_count": await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params) if should_query_logs else 0 - } - - # 统计日志级别分布(仅查询系统日志时) + # 统计日志级别分布(仅查询系统日志时)- 优化:使用GROUP BY聚合,避免查询所有记录 if should_query_logs and result["stats"]["logs_count"] > 0: - level_stats = {} - for lv in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']: - count = await system_log_storage.count_logs_with_filters(utc_start, utc_end, lv, filter_params) - if count > 0: - level_stats[lv] = count - result["stats"]["level_distribution"] = level_stats + try: + # 使用原生SQL的GROUP BY聚合,性能最优 + from .models import SystemLog + from tortoise import connections + + conn = connections.get("default") + + # 构建SQL查询 + sql = "SELECT level, COUNT(*) as count FROM system_logs WHERE 1=1" + params = [] + + if utc_start and utc_end: + sql += " AND timestamp >= $1 AND timestamp <= $2" + params.extend([utc_start, utc_end]) + + if filter_params and filter_params.get('module'): + sql += f" AND module IN ({','.join(['$'+str(i+3) for i in range(len(filter_params['module']))])})" + params.extend(filter_params['module']) + + sql += " GROUP BY level" + + # 执行查询 + rows = await conn.execute_query(sql, params) + level_stats = {row['level']: row['count'] for row in rows[1] if row.get('level')} + result["stats"]["level_distribution"] = level_stats + except Exception as e: + print(f"统计级别分布失败: {e}") + result["stats"]["level_distribution"] = {} return result @@ -1576,3 +1612,91 @@ async def export_history_data( media_type="application/json", headers={"Content-Disposition": f"attachment; filename={filename}"} ) + + +# ========== 详情懒加载端点 ========== + +@router.get("/history/outbound/{request_id}") +async def get_outbound_request_detail(request_id: int): + """ + 获取发送请求详情(懒加载,包含request_body、response_body等大字段) + """ + try: + req = await OutboundAPIRequest.get_or_none(id=request_id) + if not req: + raise HTTPException(status_code=404, detail="请求不存在") + + return { + "id": req.id, + "timestamp": req.timestamp.isoformat(), + "method": req.method, + "url": req.url, + "status_code": req.status_code, + "duration": req.duration * 1000, + "module": req.module, + "is_slow": req.is_slow, + "is_error": req.is_error, + "error_message": req.error_message, + "request_body": req.request_body, + "response_body": req.response_body, + "request_headers": req.request_headers, + "response_headers": req.response_headers + } + except Exception as e: + raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}") + + +@router.get("/history/http/{request_id}") +async def get_http_request_detail(request_id: int): + """ + 获取HTTP请求详情(懒加载,包含request_body、response_body等大字段) + """ + try: + req = await APIRequest.get_or_none(id=request_id) + if not req: + raise HTTPException(status_code=404, detail="请求不存在") + + return { + "id": req.id, + "timestamp": req.timestamp.isoformat(), + "method": req.method, + "path": req.path, + "query_params": req.query_params, + "status_code": req.status_code, + "duration": req.response_time, + "client_ip": req.client_ip, + "user_agent": req.user_agent, + "is_slow": req.is_slow, + "is_error": req.is_error, + "error_message": req.error_message, + "request_body": req.request_body, + "response_body": req.response_body, + "request_headers": getattr(req, 'request_headers', None), + "response_headers": getattr(req, 'response_headers', None) + } + except Exception as e: + raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}") + + +@router.get("/history/log/{log_id}") +async def get_log_detail(log_id: int): + """ + 获取系统日志详情(懒加载,包含stack_trace等大字段) + """ + try: + log = await SystemLog.get_or_none(id=log_id) + if not log: + raise HTTPException(status_code=404, detail="日志不存在") + + return { + "id": log.id, + "timestamp": log.timestamp.isoformat(), + "level": log.level, + "module": log.module, + "function": log.function, + "line_number": log.line_number, + "message": log.message, + "stack_trace": log.stack_trace + } + except Exception as e: + raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}") diff --git a/docs/spec/MDS-i18n-Implementation-Proposal.md b/docs/spec/MDS-i18n-Implementation-Proposal.md new file mode 100644 index 0000000..527c6a1 --- /dev/null +++ b/docs/spec/MDS-i18n-Implementation-Proposal.md @@ -0,0 +1,1112 @@ +# MDS模块国际化实施方案 + +**文档类型**:技术方案 +**创建日期**:2026-05-24 +**版本**:v1.0 +**状态**:待评审 + +--- + +## 一、项目概况 + +### 1.1 背景 + +监控模块(Monitor)已完成国际化支持,支持中文、英文、德语三语切换。现需对MDS(数据清洗管理)模块实施相同的国际化改造。 + +### 1.2 目标 + +- 支持简体中文、英语、德语三种语言(与Monitor模块保持一致) +- 与Monitor模块使用统一的国际化框架 +- 用户切换语言时,Monitor和MDS同时生效 +- 保持代码简洁,避免重复实现 +- 支持无刷新语言切换,保持页面状态 + +### 1.3 范围 + +- 3个HTML页面 +- 7个JavaScript文件 +- 约5,682行代码 +- 约746处中文文本需翻译 + +--- + +## 二、当前状态分析 + +### 2.1 文件结构 + +**HTML页面**(3个): + +| 文件 | 行数 | 用途 | +|------|------|------| +| `index.html` | 318 | 首页:模块卡片导航、全局操作 | +| `user-guide.html` | 202 | 操作指引页面 | +| `pages/template.html` | 258 | 数据操作页面模板 | + +**JavaScript文件**(7个): + +| 文件 | 行数 | 功能 | +|------|------|------| +| `mds-page-controller.js` | 1892 | 页面控制器(核心) | +| `data-table.js` | 1517 | 数据表格组件 | +| `modal-manager.js` | 564 | 模态框管理器 | +| `common.js` | 540 | 公共函数库、状态枚举 | +| `form-renderer.js` | 346 | 表单渲染器 | +| `global-ops-controller.js` | 343 | 全局操作控制器 | +| `status-card.js` | 302 | 状态统计卡片 | + +**总代码量**:5,682行 + +### 2.2 文本分类统计 + +| 优先级 | 类型 | 数量 | 示例 | +|--------|------|------|------| +| P0 | 状态标签 | 28处 | 待处理、已推送 | +| P1 | 操作按钮 | 45处 | 导入、校验、推送 | +| P2 | 导航菜单 | 14处 | 物料、BOM、模具 | +| P3 | 弹窗文本 | 120处 | 确认、取消、提示 | +| P4 | 错误消息 | 85处 | 查询失败、上传失败 | +| P5 | 表格文本 | 150处 | 编辑、删除、分页 | +| P6 | 其他提示 | 304处 | 加载中、暂无数据 | +| **合计** | | **746处** | | + +### 2.3 复杂度评估 + +**等级**:⭐⭐⭐⭐☆(高复杂度) + +**高复杂度因素**: +- 硬编码文本数量庞大(746处) +- 动态拼接文本多(需参数化翻译) +- 组件嵌套深(表格、表单、弹窗多层嵌套) + +**低复杂度因素**: +- 代码结构清晰,模块化设计 +- 页面数量少,模板复用率高 +- 无第三方UI组件库 + +--- + +## 三、语言包组织方案 + +### 3.1 方案对比 + +| 方案 | 目录结构 | 支持语言 | 优点 | 缺点 | 推荐度 | +|------|----------|----------|------|------|--------| +| **A. 统一管理** | `static/lib/i18n/` | 中/英/德 | 框架复用
全局切换
维护简单
与Monitor一致 | 单文件较大 | ⭐⭐⭐⭐⭐ | +| **B. 独立目录** | `static/mds/locales/` | 中/英/德 | 模块独立
按需加载 | 重复代码
切换复杂 | ⭐⭐☆☆☆ | +| **C. 命名空间** | `static/lib/i18n/{module}/` | 中/英/德 | 框架复用
模块隔离 | 需改造框架 | ⭐⭐⭐☆☆ | + +### 3.2 推荐方案:A(统一管理 + 命名空间) + +**目录结构**: +``` +static/lib/i18n/ +├── i18n.js # 统一框架(已存在) +├── zh-CN.js # 中文语言包(扩展) +├── en-US.js # 英文语言包(扩展) +└── de-DE.js # 德语语言包(扩展) +``` + +**语言包结构**(命名空间): +```javascript +// zh-CN.js(简体中文) +window.__i18n_zh_CN__ = { + // ========== 通用文本 ========== + 'common.confirm': '确定', + 'common.cancel': '取消', + 'common.loading': '加载中...', + + // ========== Monitor模块 ========== + 'monitor.page.title': 'MyAPI 系统监控面板', + 'monitor.status.healthy': '● 系统正常', + // ... (现有405条) + + // ========== MDS模块 ========== + 'mds.app.title': '数据清洗管理系统', + 'mds.nav.material': '物料', + 'mds.action.validate': '校验', + 'mds.status.pending': '待处理', + // ... (新增约750条) +}; + +// en-US.js(英语) +window.__i18n_en_US__ = { + // ========== Common ========== + 'common.confirm': 'Confirm', + 'common.cancel': 'Cancel', + 'common.loading': 'Loading...', + + // ========== Monitor Module ========== + 'monitor.page.title': 'MyAPI System Monitor', + 'monitor.status.healthy': '● System Healthy', + // ... (现有405条) + + // ========== MDS Module ========== + 'mds.app.title': 'Data Staging Management System', + 'mds.nav.material': 'Material', + 'mds.action.validate': 'Validate', + 'mds.status.pending': 'Pending', + // ... (新增约750条) +}; + +// de-DE.js(德语) +window.__i18n_de_DE__ = { + // ========== Allgemein ========== + 'common.confirm': 'Bestätigen', + 'common.cancel': 'Abbrechen', + 'common.loading': 'Laden...', + + // ========== Monitor-Modul ========== + 'monitor.page.title': 'MyAPI Systemüberwachung', + 'monitor.status.healthy': '● System gesund', + // ... (现有405条) + + // ========== MDS-Modul ========== + 'mds.app.title': 'Daten-Staging-Verwaltungssystem', + 'mds.nav.material': 'Material', + 'mds.action.validate': 'Validieren', + 'mds.status.pending': 'Ausstehend', + // ... (新增约750条) +}; +``` + +### 3.3 方案优势 + +1. ✅ **框架复用**:Monitor的i18n.js已成熟,无需重复开发 +2. ✅ **全局切换**:用户切换语言,Monitor和MDS同时生效 +3. ✅ **代码简洁**:避免多套i18n实例,降低复杂度 +4. ✅ **维护方便**:语言包集中管理,便于批量修改 +5. ✅ **命名清晰**:通过`monitor.`和`mds.`前缀区分模块 + +### 3.4 语言包大小预估 + +| 模块 | 翻译条目 | +|------|----------| +| Monitor(现有) | 405条 | +| MDS(新增) | 750条 | +| **合并后** | **约1155条/语言** | +| **文件大小** | **约60-80KB** | + +单文件大小可接受,无需拆分。 + +--- + +## 四、实施计划 + +### 4.1 分阶段实施(推荐) + +**Phase 1**:基础准备 + P0/P1(状态+按钮) +- 工作量:4天 +- 输出:框架复用、三语言包创建、状态枚举改造 + +**Phase 2**:P2/P3(导航+弹窗) +- 工作量:5天 +- 输出:HTML改造、弹窗翻译 + +**Phase 3**:P4/P5(错误+表格) +- 工作量:6天 +- 输出:错误处理、表格组件改造 + +**Phase 4**:P6(其他提示) +- 工作量:4天 +- 输出:完成所有翻译、全面测试 + +**总工作量**:19人天(约4周) + +**说明**:相比Monitor模块的4人日,MDS模块工作量更大,原因: +1. 翻译文本数量更多(746处 vs 158处) +2. 三语言翻译工作量增加50% +3. 状态枚举、表格组件改造复杂度高 +4. 动态消息参数化处理更复杂 + +### 4.2 详细实施步骤 + +#### Phase 1: 基础准备(4天) + +**Day 1: 框架复用与语言包创建** +- [ ] 在现有语言包中添加MDS命名空间 +- [ ] 提取P0级文本(状态标签,28处) +- [ ] 提取P1级文本(操作按钮,45处) +- [ ] 编写简体中文、英语、德语三语言翻译 + +**Day 2: 状态枚举改造** +- [ ] 改造`common.js`的`STAGING_STATUS` +- [ ] 将label改为getter动态翻译 +- [ ] 改造`status-card.js` +- [ ] 测试三语言状态标签翻译 + +**Day 3-4: 验证与测试** +- [ ] 测试状态标签三语言翻译 +- [ ] 测试操作按钮三语言翻译 +- [ ] 测试语言切换功能(无刷新) +- [ ] 测试德语文本布局适配 + +#### Phase 2: 导航与弹窗(5天) + +**Day 5-6: HTML改造** +- [ ] `index.html`添加data-i18n属性 +- [ ] `template.html`添加data-i18n属性 +- [ ] `user-guide.html`添加data-i18n属性 +- [ ] 提取P2级文本(导航菜单,14处) +- [ ] 测试三语言HTML文本翻译 + +**Day 7-9: 弹窗改造** +- [ ] 改造`modal-manager.js` +- [ ] 改造`form-renderer.js` +- [ ] 提取P3级文本(弹窗文本,120处) +- [ ] 编写三语言翻译 +- [ ] 测试弹窗三语言显示 + +#### Phase 3: 错误与表格(6天) + +**Day 10-11: 错误处理** +- [ ] 改造错误消息处理函数 +- [ ] 创建后端错误码+参数处理机制 +- [ ] 提取P4级文本(错误消息,85处) +- [ ] 编写三语言翻译 +- [ ] 测试三语言错误提示 + +**Day 12-15: 表格改造** +- [ ] 改造`data-table.js` +- [ ] 改造分页控件 +- [ ] 改造空状态提示 +- [ ] 提取P5级文本(表格文本,150处) +- [ ] 编写三语言翻译 +- [ ] 测试表格三语言显示 + +#### Phase 4: 完成与测试(4天) + +**Day 16-17: 完成翻译** +- [ ] 提取P6级文本(其他提示,304处) +- [ ] 改造`mds-page-controller.js` +- [ ] 改造`global-ops-controller.js` +- [ ] 编写三语言翻译 + +**Day 18-19: 测试验证** +- [ ] 功能测试:所有页面文本翻译 +- [ ] 三语言切换测试(无刷新) +- [ ] 德语文本布局验证 +- [ ] 回归测试:现有功能不受影响 +- [ ] 编写实施文档 + +--- + +## 五、技术方案 + +### 5.1 状态枚举改造 + +**改造前**: +```javascript +const STAGING_STATUS = { + PENDING: { + value: 'pending', + label: '待处理', + color: '#ff9300', + icon: '⏳' + } +}; +``` + +**改造后**: +```javascript +const STAGING_STATUS = { + PENDING: { + value: 'pending', + labelKey: 'mds.status.pending', // 翻译键 + color: '#ff9300', + icon: '⏳', + get label() { + return typeof i18n !== 'undefined' ? + i18n.t(this.labelKey) : '待处理'; + } + } +}; +``` + +### 5.2 动态消息参数化 + +**改造前**: +```javascript +showMessage(`校验完成: 通过${pass}条,失败${fail}条`, 'success'); +``` + +**改造后**: +```javascript +const msg = typeof i18n !== 'undefined' ? + i18n.t('mds.validation.complete', { pass, fail }) : + `校验完成: 通过${pass}条,失败${fail}条`; +showMessage(msg, 'success'); +``` + +**语言包定义**: +```javascript +// zh-CN.js(简体中文) +'mds.validation.complete': '校验完成: 通过{pass}条,失败{fail}条', + +// en-US.js(英语) +'mds.validation.complete': 'Validation: {pass} passed, {fail} failed', + +// de-DE.js(德语) +'mds.validation.complete': 'Validierung: {pass} bestanden, {fail} fehlgeschlagen', +``` + +### 5.3 后端错误消息处理 + +**方案:后端返回错误码+参数,前端统一翻译** + +**后端响应格式**: +```python +# 后端返回错误码和参数 +{ + "success": false, + "error": { + "code": "DUPLICATE_KEY", # 错误码 + "params": { # 动态参数 + "field": "MaterialNo", + "value": "MAT001" + } + } +} +``` + +**前端翻译处理**: +```javascript +// 错误码翻译映射表(在语言包中定义) +// zh-CN.js +'mds.error.DUPLICATE_KEY': '数据重复: {field}={value} 已存在', +'mds.error.INVALID_FORMAT': '格式错误: {field} 格式不正确', +'mds.error.FOREIGN_KEY_VIOLATION': '外键约束违反: {field} 引用不存在', +'mds.error.VALIDATION_FAILED': '校验失败: {reason}', + +// en-US.js +'mds.error.DUPLICATE_KEY': 'Duplicate data: {field}={value} already exists', +'mds.error.INVALID_FORMAT': 'Invalid format: {field} format is incorrect', +'mds.error.FOREIGN_KEY_VIOLATION': 'Foreign key violation: {field} reference not found', +'mds.error.VALIDATION_FAILED': 'Validation failed: {reason}', + +// de-DE.js +'mds.error.DUPLICATE_KEY': 'Doppelter Dateneintrag: {field}={value} bereits vorhanden', +'mds.error.INVALID_FORMAT': 'Ungültiges Format: {field} Format ist fehlerhaft', +'mds.error.FOREIGN_KEY_VIOLATION': 'Fremdschlüssel-Verletzung: {field} Referenz nicht gefunden', +'mds.error.VALIDATION_FAILED': 'Validierung fehlgeschlagen: {reason}', + +// 翻译函数 +function translateError(response) { + if (!response.error) { + return response.message || 'Unknown error'; + } + + const { code, params = {} } = response.error; + const errorKey = `mds.error.${code}`; + + // 使用i18n翻译 + if (typeof i18n !== 'undefined') { + return i18n.t(errorKey, params); + } + + // 回退:返回错误码 + return code; +} + +// 使用示例 +async function handleApiResponse(response) { + if (!response.success) { + const errorMsg = translateError(response); + showError(errorMsg); + } +} +``` + +**方案优势**: +- ✅ 后端无需关心具体翻译文本,只需返回错误码 +- ✅ 前端统一翻译,支持多语言 +- ✅ 错误码和参数分离,灵活性高 +- ✅ 新增错误类型只需在语言包中添加翻译项 + +### 5.4 HTML模板改造 + +**改造前**: +```html + +``` + +**改造后**: +```html + +``` + +**初始化翻译**: +```javascript +// 页面加载后 +document.querySelectorAll('[data-i18n]').forEach(el => { + const key = el.getAttribute('data-i18n'); + const text = typeof i18n !== 'undefined' ? i18n.t(key) : key; + el.textContent = text; +}); +``` + +### 5.5 语言切换UI集成 + +**在导航栏添加语言选择器**: +```html + +``` + +**无刷新语言切换方案**: +```javascript +/** + * 语言切换(无刷新) + * 保持页面状态,动态更新所有文本 + */ +async function switchLanguage(lang) { + if (typeof i18n === 'undefined') { + console.warn('i18n not initialized'); + return; + } + + // 调用i18n框架切换语言 + await i18n.switchLanguage(lang); + + // 更新状态枚举(使用getter动态翻译,已自动更新) + // 无需手动处理 + + // 更新动态生成的DOM元素 + updateDynamicElements(); + + // 触发自定义事件(供组件监听) + window.dispatchEvent(new CustomEvent('languageChanged', { + detail: { lang: lang } + })); + + console.log(`[i18n] Language switched to ${lang} (no page reload)`); +} + +/** + * 更新动态生成的DOM元素 + * 如:表格内容、弹窗内容、状态卡片等 + */ +function updateDynamicElements() { + // 1. 更新表格内容(如果表格已渲染) + if (window.dataTableInstance) { + window.dataTableInstance.refresh(); + } + + // 2. 更新状态卡片 + if (window.statusCardInstance) { + window.statusCardInstance.refresh(); + } + + // 3. 更新已打开的模态框 + const modals = document.querySelectorAll('.modal.show'); + modals.forEach(modal => { + // 重新应用翻译到模态框内的元素 + modal.querySelectorAll('[data-i18n]').forEach(el => { + const key = el.getAttribute('data-i18n'); + el.textContent = i18n.t(key); + }); + }); + + // 4. 更新表格操作按钮(编辑、删除等) + document.querySelectorAll('[data-i18n-action]').forEach(el => { + const key = el.getAttribute('data-i18n-action'); + el.textContent = i18n.t(key); + }); +} + +// 监听语言切换事件(组件可订阅) +window.addEventListener('languageChanged', (e) => { + const newLang = e.detail.lang; + console.log(`Component notified: language changed to ${newLang}`); + + // 组件特定的更新逻辑 + // 例如:重新渲染图表标题、更新提示文本等 +}); +``` + +**i18n框架增强(支持无刷新切换)**: +```javascript +// i18n.js中的switchLanguage方法 +async switchLanguage(lang) { + if (lang === this.currentLang) return; + + try { + // 1. 保存到localStorage + localStorage.setItem('monitor-lang', lang); + + // 2. 加载新语言包 + this.currentLang = lang; + await this.loadLanguage(lang); + + // 3. 应用翻译到所有静态元素 + this.applyTranslations(); + + // 4. 更新语言选择器状态 + this.updateLangSelector(); + + // 5. 触发事件(不刷新页面) + window.dispatchEvent(new CustomEvent('langchange', { + detail: { lang: lang } + })); + + console.log(`[i18n] Language switched to: ${lang} (no reload)`); + } catch (error) { + console.error('[i18n] Language switch failed:', error); + } +} +``` + +**无刷新切换优势**: +- ✅ 保持页面滚动位置 +- ✅ 保持表单输入状态 +- ✅ 保持表格筛选条件 +- ✅ 保持分页状态 +- ✅ 用户体验流畅,无白屏闪烁 + +--- + +## 六、风险与对策 + +### 6.1 风险清单 + +| 风险 | 级别 | 影响 | 对策 | +|------|------|------|------| +| 后端错误消息硬编码 | 高 | 错误提示无法翻译 | 后端返回错误码+参数,前端统一翻译 | +| 动态消息参数化 | 中 | 翻译不准确 | 使用i18n插值功能,三语言测试验证 | +| Bootstrap弹窗动态生成 | 中 | 弹窗内容不更新 | 弹窗打开时重新应用翻译,语言切换事件监听 | +| 状态枚举多处使用 | 中 | 改造遗漏 | 改造为getter动态翻译,无需手动刷新 | +| 德语文本较长 | 中 | 布局溢出 | CSS增加文本自适应,德语专项布局测试 | +| 三语言翻译质量 | 低 | 德语翻译不准确 | 使用专业翻译工具+人工校对 | +| 工作量大 | 低 | 实施周期长 | 分阶段实施,P0优先,三语言并行翻译 | + +### 6.2 质量保证措施 + +1. **代码审查**:每个阶段完成后进行代码审查 +2. **单元测试**:编写翻译函数单元测试 +3. **回归测试**:确保现有功能不受影响 +4. **性能测试**:验证语言包加载性能 +5. **用户验收**:邀请用户测试语言切换功能 + +--- + +## 七、翻译示例 + +### 7.1 核心翻译键设计 + +#### 7.1.1 简体中文(zh-CN.js) + +```javascript +// zh-CN.js 扩展内容 +{ + // ========== MDS模块 ========== + + // 应用标题 + 'mds.app.title': '数据清洗管理系统', + 'mds.app.guide': '操作指引', + 'mds.app.apiDoc': 'API文档', + + // 导航菜单 + 'mds.nav.material': '物料', + 'mds.nav.matVer': '产线版本', + 'mds.nav.workcenter': '工作中心', + 'mds.nav.matWc': '工艺路线', + 'mds.nav.bom': 'BOM', + 'mds.nav.mold': '模具', + 'mds.nav.matWcMold': '机台模具', + + // 操作按钮 + 'mds.action.import': '导入', + 'mds.action.validate': '校验', + 'mds.action.sync': '推送', + 'mds.action.query': '查询', + 'mds.action.reset': '重置', + 'mds.action.save': '保存', + 'mds.action.delete': '删除', + 'mds.action.cancel': '取消', + 'mds.action.confirm': '确定', + + // 状态标签 + 'mds.status.all': '全部', + 'mds.status.pending': '待处理', + 'mds.status.compliancePass': '初检通过', + 'mds.status.complianceError': '初检错误', + 'mds.status.relationPass': '联检通过', + 'mds.status.relationError': '联检错误', + 'mds.status.syncError': '推送失败', + 'mds.status.synced': '已推送', + + // 校验相关 + 'mds.validation.complete': '校验完成: 通过{pass}条,失败{fail}条', + 'mds.validation.noPending': '没有待处理的记录', + 'mds.validation.confirmStart': '缺失的字段值将自动填充为默认值,确定开始校验吗?', + 'mds.validation.processing': '校验中', + 'mds.validation.failed': '校验失败', + 'mds.validation.progress': '已处理 {current}/{total}', + + // 推送相关 + 'mds.sync.complete': '推送完成: {accounts}个账套, 成功{synced}条, 去重失败{dedup}条, 其他失败{failed}条', + 'mds.sync.noData': '没有【联合校验通过】或【同步失败】的记录可推送', + 'mds.sync.selectTarget': '请至少选择一个目标账套', + 'mds.sync.selectMode': '选择推送模式', + 'mds.sync.incremental': '增量推送', + 'mds.sync.refresh': '刷新推送', + 'mds.sync.confirmRefresh': '刷新推送将删除正式表所有数据,请谨慎操作!', + + // 上传相关 + 'mds.upload.success': '导入完成: 成功{inserted}条, 跳过{skipped}条', + 'mds.upload.invalidType': '请上传Excel或CSV文件', + 'mds.upload.noFile': '请先选择文件', + 'mds.upload.dragDrop': '点击或拖拽文件上传(支持 .xlsx, .xls, .csv)', + + // 表格相关 + 'mds.table.noData': '暂无数据', + 'mds.table.loading': '加载中...', + 'mds.table.selectAll': '全选', + 'mds.table.perPage': '条/页', + 'mds.table.total': '共 {count} 条', + 'mds.table.edit': '编辑', + 'mds.table.delete': '删除', + 'mds.table.export': '导出模板', + + // 弹窗相关 + 'mds.modal.confirm': '确认', + 'mds.modal.cancel': '取消', + 'mds.modal.close': '关闭', + 'mds.modal.importTitle': '导入Excel数据', + 'mds.modal.filterTitle': '精准筛选', + 'mds.modal.editTitle': '编辑记录', + 'mds.modal.validationRules': '校验规则', + + // 错误消息 + 'mds.error.queryFailed': '查询失败', + 'mds.error.uploadFailed': '上传失败', + 'mds.error.timeout': '请求超时', + 'mds.error.loadFailed': '加载失败,请重试' +} +``` + +#### 7.1.2 英语(en-US.js) + +```javascript +// en-US.js 扩展内容 +{ + // ========== MDS Module ========== + + // Application Title + 'mds.app.title': 'Data Staging Management System', + 'mds.app.guide': 'User Guide', + 'mds.app.apiDoc': 'API Documentation', + + // Navigation Menu + 'mds.nav.material': 'Material', + 'mds.nav.matVer': 'Material Version', + 'mds.nav.workcenter': 'Work Center', + 'mds.nav.matWc': 'Routing', + 'mds.nav.bom': 'BOM', + 'mds.nav.mold': 'Mold', + 'mds.nav.matWcMold': 'Machine Mold', + + // Action Buttons + 'mds.action.import': 'Import', + 'mds.action.validate': 'Validate', + 'mds.action.sync': 'Sync', + 'mds.action.query': 'Query', + 'mds.action.reset': 'Reset', + 'mds.action.save': 'Save', + 'mds.action.delete': 'Delete', + 'mds.action.cancel': 'Cancel', + 'mds.action.confirm': 'Confirm', + + // Status Labels + 'mds.status.all': 'All', + 'mds.status.pending': 'Pending', + 'mds.status.compliancePass': 'Compliance Pass', + 'mds.status.complianceError': 'Compliance Error', + 'mds.status.relationPass': 'Relation Pass', + 'mds.status.relationError': 'Relation Error', + 'mds.status.syncError': 'Sync Failed', + 'mds.status.synced': 'Synced', + + // Validation Related + 'mds.validation.complete': 'Validation: {pass} passed, {fail} failed', + 'mds.validation.noPending': 'No pending records', + 'mds.validation.confirmStart': 'Missing field values will be filled with defaults. Proceed?', + 'mds.validation.processing': 'Validating', + 'mds.validation.failed': 'Validation Failed', + 'mds.validation.progress': 'Processed {current}/{total}', + + // Sync Related + 'mds.sync.complete': 'Sync complete: {accounts} accounts, {synced} synced, {dedup} dedup failed, {failed} other failed', + 'mds.sync.noData': 'No [Relation Pass] or [Sync Failed] records to sync', + 'mds.sync.selectTarget': 'Please select at least one target account', + 'mds.sync.selectMode': 'Select Sync Mode', + 'mds.sync.incremental': 'Incremental Sync', + 'mds.sync.refresh': 'Refresh Sync', + 'mds.sync.confirmRefresh': 'Refresh sync will delete all data in the main table. Proceed with caution!', + + // Upload Related + 'mds.upload.success': 'Import complete: {inserted} inserted, {skipped} skipped', + 'mds.upload.invalidType': 'Please upload Excel or CSV file', + 'mds.upload.noFile': 'Please select a file first', + 'mds.upload.dragDrop': 'Click or drag file to upload (supports .xlsx, .xls, .csv)', + + // Table Related + 'mds.table.noData': 'No data', + 'mds.table.loading': 'Loading...', + 'mds.table.selectAll': 'Select All', + 'mds.table.perPage': 'per page', + 'mds.table.total': 'Total {count} records', + 'mds.table.edit': 'Edit', + 'mds.table.delete': 'Delete', + 'mds.table.export': 'Export Template', + + // Modal Related + 'mds.modal.confirm': 'Confirm', + 'mds.modal.cancel': 'Cancel', + 'mds.modal.close': 'Close', + 'mds.modal.importTitle': 'Import Excel Data', + 'mds.modal.filterTitle': 'Advanced Filter', + 'mds.modal.editTitle': 'Edit Record', + 'mds.modal.validationRules': 'Validation Rules', + + // Error Messages + 'mds.error.queryFailed': 'Query Failed', + 'mds.error.uploadFailed': 'Upload Failed', + 'mds.error.timeout': 'Request Timeout', + 'mds.error.loadFailed': 'Load Failed, Please Retry' +} +``` + +#### 7.1.3 德语(de-DE.js) + +```javascript +// de-DE.js 扩展内容 +{ + // ========== MDS-Modul ========== + + // Anwendungstitel + 'mds.app.title': 'Daten-Staging-Verwaltungssystem', + 'mds.app.guide': 'Benutzerhandbuch', + 'mds.app.apiDoc': 'API-Dokumentation', + + // Navigationsmenü + 'mds.nav.material': 'Material', + 'mds.nav.matVer': 'Materialversion', + 'mds.nav.workcenter': 'Arbeitsplatz', + 'mds.nav.matWc': 'Arbeitsplan', + 'mds.nav.bom': 'Stückliste', + 'mds.nav.mold': 'Werkzeug', + 'mds.nav.matWcMold': 'Maschinen-Werkzeug', + + // Aktionsschaltflächen + 'mds.action.import': 'Importieren', + 'mds.action.validate': 'Validieren', + 'mds.action.sync': 'Synchronisieren', + 'mds.action.query': 'Abfragen', + 'mds.action.reset': 'Zurücksetzen', + 'mds.action.save': 'Speichern', + 'mds.action.delete': 'Löschen', + 'mds.action.cancel': 'Abbrechen', + 'mds.action.confirm': 'Bestätigen', + + // Statusbezeichnungen + 'mds.status.all': 'Alle', + 'mds.status.pending': 'Ausstehend', + 'mds.status.compliancePass': 'Compliance bestanden', + 'mds.status.complianceError': 'Compliance fehlerhaft', + 'mds.status.relationPass': 'Relation bestanden', + 'mds.status.relationError': 'Relation fehlerhaft', + 'mds.status.syncError': 'Sync fehlgeschlagen', + 'mds.status.synced': 'Synchronisiert', + + // Validierungsbezogen + 'mds.validation.complete': 'Validierung: {pass} bestanden, {fail} fehlgeschlagen', + 'mds.validation.noPending': 'Keine ausstehenden Datensätze', + 'mds.validation.confirmStart': 'Fehlende Feldwerte werden mit Standardwerten gefüllt. Fortfahren?', + 'mds.validation.processing': 'Validierung läuft', + 'mds.validation.failed': 'Validierung fehlgeschlagen', + 'mds.validation.progress': 'Verarbeitet {current}/{total}', + + // Synchronisationsbezogen + 'mds.sync.complete': 'Sync abgeschlossen: {accounts} Konten, {synced} synchronisiert, {dedup} Dedup fehlgeschlagen, {failed} sonstige fehlgeschlagen', + 'mds.sync.noData': 'Keine [Relation bestanden] oder [Sync fehlgeschlagen] Datensätze zum Synchronisieren', + 'mds.sync.selectTarget': 'Bitte mindestens ein Zielkonto auswählen', + 'mds.sync.selectMode': 'Synchronisationsmodus wählen', + 'mds.sync.incremental': 'Inkrementelle Synchronisation', + 'mds.sync.refresh': 'Aktualisierungs-Sync', + 'mds.sync.confirmRefresh': 'Aktualisierungs-Sync löscht alle Daten in der Haupttabelle. Mit Vorsicht fortfahren!', + + // Upload-bezogen + 'mds.upload.success': 'Import abgeschlossen: {inserted} eingefügt, {skipped} übersprungen', + 'mds.upload.invalidType': 'Bitte Excel- oder CSV-Datei hochladen', + 'mds.upload.noFile': 'Bitte zuerst eine Datei auswählen', + 'mds.upload.dragDrop': 'Klicken oder Datei ziehen (unterstützt .xlsx, .xls, .csv)', + + // Tabellenbezogen + 'mds.table.noData': 'Keine Daten', + 'mds.table.loading': 'Laden...', + 'mds.table.selectAll': 'Alle auswählen', + 'mds.table.perPage': 'pro Seite', + 'mds.table.total': 'Gesamt {count} Datensätze', + 'mds.table.edit': 'Bearbeiten', + 'mds.table.delete': 'Löschen', + 'mds.table.export': 'Vorlage exportieren', + + // Modal-bezogen + 'mds.modal.confirm': 'Bestätigen', + 'mds.modal.cancel': 'Abbrechen', + 'mds.modal.close': 'Schließen', + 'mds.modal.importTitle': 'Excel-Daten importieren', + 'mds.modal.filterTitle': 'Erweiterter Filter', + 'mds.modal.editTitle': 'Datensatz bearbeiten', + 'mds.modal.validationRules': 'Validierungsregeln', + + // Fehlermeldungen + 'mds.error.queryFailed': 'Abfrage fehlgeschlagen', + 'mds.error.uploadFailed': 'Upload fehlgeschlagen', + 'mds.error.timeout': 'Anfrage-Timeout', + 'mds.error.loadFailed': 'Laden fehlgeschlagen, bitte erneut versuchen' +} +``` + +--- + +## 八、验收标准 + +### 8.1 功能验收 + +- [ ] 所有页面支持语言切换(简体中文、英语、德语) +- [ ] 三语言文本正确显示 +- [ ] 状态枚举动态翻译 +- [ ] 操作按钮文本翻译 +- [ ] 弹窗内容翻译 +- [ ] 表单验证消息翻译 +- [ ] 错误提示翻译(支持参数化) +- [ ] 表格空状态翻译 +- [ ] 分页控件翻译 +- [ ] 无刷新语言切换(保持页面状态) + +### 8.2 性能验收 + +- [ ] 语言包加载时间 < 300ms(三语言包总计约120KB) +- [ ] 语言切换响应时间 < 100ms(无刷新) +- [ ] 内存占用增加 < 8MB(三语言包加载) +- [ ] 无刷新切换无白屏闪烁 + +### 8.3 兼容性验收 + +- [ ] Chrome浏览器兼容 +- [ ] Firefox浏览器兼容 +- [ ] Edge浏览器兼容 +- [ ] Safari浏览器兼容(如有条件) +- [ ] 德语文本在不同浏览器下正确显示(无乱码) + +### 8.4 文档验收 + +- [ ] 实施文档完整 +- [ ] 翻译键命名规范 +- [ ] 代码注释清晰 + +--- + +## 九、后续维护 + +### 9.1 新增翻译流程 + +1. 在代码中使用翻译键:`i18n.t('mds.new.key')` +2. 在所有语言包中添加对应翻译 +3. 更新翻译键文档 +4. 测试验证 + +### 9.2 翻译质量保证 + +- 使用统一的翻译键命名规范 +- 定期检查未使用的翻译键 +- 保持翻译文本简洁准确 + +### 9.3 扩展其他语言 + +如需支持其他语言(如日语、法语等): +1. 创建新语言包文件(如`ja-JP.js`) +2. 复制`zh-CN.js`作为模板 +3. 翻译所有文本 +4. 在语言选择器中添加选项 + +--- + +## 十、附录 + +### 10.1 相关文档 + +- [Monitor模块国际化实施计划](./Monitor-i18n-Implementation-Plan.md) +- [Monitor模块国际化测试报告](./Monitor-i18n-Test-Report.md) +- [AGENTS.md 开发指南](../../AGENTS.md) + +### 10.2 参考资料 + +- i18next官方文档:https://www.i18next.com/ +- Bootstrap国际化最佳实践 +- FastAPI国际化方案 + +### 10.3 变更历史 + +| 版本 | 日期 | 变更内容 | 作者 | +|------|------|----------|------| +| v1.0 | 2026-05-24 | 初版创建 | CodeArts | +| v1.1 | 2026-05-24 | 优化技术方案:支持简体中文/英语/德语三语言、无刷新语言切换、后端错误码+参数化处理 | CodeArts | + +--- + +**文档状态**:待评审 +**下一步**:评审通过后开始Phase 1实施 + +--- + +## 十一、三语言支持补充说明 + +### 11.1 语言包文件规划 + +基于Monitor模块已实现的三语言支持,MDS模块将复用相同的语言包文件: + +``` +static/lib/i18n/ +├── i18n.js # 核心框架(已存在,无需修改) +├── zh-CN.js # 简体中文(扩展MDS命名空间) +├── en-US.js # 英语(扩展MDS命名空间) +└── de-DE.js # 德语(扩展MDS命名空间) +``` + +### 11.2 德语翻译注意事项 + +**1. 文本长度** +德语文本通常比中文和英文长20%-40%,需特别注意: +- 按钮文本:如"Validieren"(德语)vs "Validate"(英语) +- 表格列名:需预留足够的列宽 +- 错误提示:可能需要自动换行或省略 + +**2. 特殊字符** +德语包含特殊字符(ä, ö, ü, ß),需确保: +- HTML文件使用UTF-8编码 +- 语言包文件保存为UTF-8无BOM格式 +- 服务器响应头正确设置Content-Type + +**3. 复合词** +德语倾向使用复合词,翻译时需考虑: +- 可读性:适当使用连字符提高可读性 +- 一致性:统一术语翻译规则 + +**示例对比**: +| 中文 | 英语 | 德语 | 长度对比 | +|------|------|------|----------| +| 数据清洗管理系统 | Data Staging Management System | Daten-Staging-Verwaltungssystem | 德语最长 | +| 校验 | Validate | Validieren | 德语较长 | +| 待处理 | Pending | Ausstehend | 德语较长 | + +### 11.3 三语言翻译流程 + +**流程图**: +``` +1. 提取中文文本 → 2. 编写中文翻译键 + ↓ +3. 翻译为英语 → 4. 校验英语翻译准确性 + ↓ +5. 翻译为德语 → 6. 校验德语翻译准确性 + ↓ +7. 三语言对比测试 → 8. 布局适配验证 +``` + +**翻译工具建议**: +- DeepL(德语翻译质量较高) +- Google Translate +- 人工校对(关键术语和用户界面文本) + +### 11.4 三语言切换用户体验 + +**无刷新切换优势**: +- ✅ 保持表格筛选条件 +- ✅ 保持分页状态 +- ✅ 保持表单输入 +- ✅ 保持滚动位置 +- ✅ 无白屏闪烁,体验流畅 + +**切换流程**: +``` +用户选择语言 → i18n.switchLanguage(lang) + ↓ +更新localStorage → 加载新语言包 + ↓ +应用翻译到DOM → 更新动态元素 + ↓ +触发语言切换事件 → 组件响应更新 + ↓ +完成(无刷新) +``` + +### 11.5 与Monitor模块协同 + +**共享机制**: +- 同一个i18n实例 +- 同一个语言选择器 +- 同一个localStorage存储键(`monitor-lang`) + +**切换同步**: +- 用户在Monitor页面切换语言 → MDS页面同时生效 +- 用户在MDS页面切换语言 → Monitor页面同时生效 +- 无需重复切换,全局生效 + +**命名空间隔离**: +```javascript +// Monitor模块使用 monitor. 前缀 +'monitor.page.title': 'MyAPI System Monitor' + +// MDS模块使用 mds. 前缀 +'mds.app.title': 'Data Staging Management System' + +// 避免键冲突,清晰区分 +``` + +--- + +## 十二、实施检查清单(三语言) + +### 12.1 Phase 1 检查清单 + +- [ ] zh-CN.js添加MDS命名空间(约750条) +- [ ] en-US.js添加MDS命名空间(约750条) +- [ ] de-DE.js添加MDS命名空间(约750条) +- [ ] 三语言翻译项数量一致 +- [ ] 状态枚举getter动态翻译测试通过 +- [ ] 三语言切换无报错 +- [ ] 德语文本无乱码 + +### 12.2 Phase 2 检查清单 + +- [ ] HTML三语言文本正确显示 +- [ ] 弹窗三语言翻译测试通过 +- [ ] 德语文本无溢出 +- [ ] 导航菜单三语言正确 + +### 12.3 Phase 3 检查清单 + +- [ ] 错误码+参数机制测试通过 +- [ ] 三语言错误提示正确 +- [ ] 表格三语言显示正确 +- [ ] 分页控件三语言正确 + +### 12.4 Phase 4 检查清单 + +- [ ] 所有页面三语言完整测试 +- [ ] 无刷新切换测试通过 +- [ ] 德语布局专项测试通过 +- [ ] 与Monitor模块协同测试通过 +- [ ] 性能验收通过 +- [ ] 浏览器兼容性测试通过 + +--- + +**补充说明结束** diff --git a/docs/spec/MDS-i18n-Task-Plan.md b/docs/spec/MDS-i18n-Task-Plan.md new file mode 100644 index 0000000..526781e --- /dev/null +++ b/docs/spec/MDS-i18n-Task-Plan.md @@ -0,0 +1,1926 @@ +# MDS模块国际化编码任务规划 + +**文档类型**: 实施任务清单 +**创建日期**: 2026-05-24 +**版本**: v1.0 +**状态**: 待执行 + +--- + +## 一、任务总览 + +### 1.1 项目信息 + +- **项目名称**: MDS模块国际化改造 +- **目标**: 支持简体中文、英语、德语三语言切换 +- **总工作量**: 19人天(约4周) +- **实施方式**: 分4个阶段递进实施 + +### 1.2 任务统计 + +| 阶段 | 任务数 | 工作量 | 优先级 | +|------|--------|--------|--------| +| Phase 1: 基础准备 | 14个任务 | 4天 | P0+P1 | +| Phase 2: 导航与弹窗 | 16个任务 | 5天 | P2+P3 | +| Phase 3: 错误与表格 | 18个任务 | 6天 | P4+P5 | +| Phase 4: 完成与测试 | 14个任务 | 4天 | P6 | +| **合计** | **62个任务** | **19天** | | + +### 1.3 核心目标 + +- [x] 复用Monitor模块的i18n框架 +- [x] 扩展现有语言包(增加MDS命名空间) +- [x] 实现无刷新语言切换 +- [x] 状态枚举动态翻译 +- [x] 后端错误码+参数化处理 +- [x] 三语言翻译质量保证 + +--- + +## 二、Phase 1任务清单(基础准备,4天) + +### 2.1 语言包创建(Day 1) + +#### 任务1.1: 扩展zh-CN.js语言包 + +**任务描述**: 在现有中文语言包中添加MDS模块命名空间 + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` + +**具体工作**: +- 提取P0级文本(状态标签,28处): mds.status.* +- 提取P1级文本(操作按钮,45处): mds.action.* +- 编写翻译键,遵循命名规范 +- 添加注释分隔模块 + +**预期产出**: +```javascript +// zh-CN.js 新增内容 +{ + // ========== MDS模块 ========== + 'mds.status.pending': '待处理', + 'mds.status.compliancePass': '初检通过', + 'mds.status.complianceError': '初检错误', + 'mds.status.relationPass': '联检通过', + 'mds.status.relationError': '联检错误', + 'mds.status.syncError': '推送失败', + 'mds.status.synced': '已推送', + + 'mds.action.import': '导入', + 'mds.action.validate': '校验', + 'mds.action.sync': '推送', + 'mds.action.query': '查询', + 'mds.action.reset': '重置', + // ... 共约73条 +} +``` + +**验收标准**: +- [ ] 翻译键数量符合预期(约73条) +- [ ] 键命名规范统一(mds.status.*, mds.action.*) +- [ ] 注释清晰分隔模块 +- [ ] 无重复键定义 + +**工作量**: 1天 + +--- + +#### 任务1.2: 扩展en-US.js语言包 + +**任务描述**: 在现有英文语言包中添加MDS模块翻译 + +**涉及文件**: +- `static/lib/i18n/en-US.js` + +**具体工作**: +- 将zh-CN.js中的MDS翻译键翻译为英文 +- 对应翻译键与zh-CN.js保持一致 +- 使用专业术语(如Compliance Pass, Sync) + +**预期产出**: +```javascript +// en-US.js 新增内容 +{ + // ========== MDS Module ========== + 'mds.status.pending': 'Pending', + 'mds.status.compliancePass': 'Compliance Pass', + 'mds.status.complianceError': 'Compliance Error', + 'mds.status.relationPass': 'Relation Pass', + 'mds.status.relationError': 'Relation Error', + 'mds.status.syncError': 'Sync Failed', + 'mds.status.synced': 'Synced', + + 'mds.action.import': 'Import', + 'mds.action.validate': 'Validate', + 'mds.action.sync': 'Sync', + // ... 共约73条 +} +``` + +**验收标准**: +- [ ] 翻译键数量与zh-CN.js一致 +- [ ] 英文翻译准确、专业 +- [ ] 键顺序与zh-CN.js对应 + +**工作量**: 0.5天 + +--- + +#### 任务1.3: 扩展de-DE.js语言包 + +**任务描述**: 在现有德语语言包中添加MDS模块翻译 + +**涉及文件**: +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 将zh-CN.js中的MDS翻译键翻译为德语 +- 注意德语特殊字符(ä, ö, ü, ß) +- 关注德语文本长度(可能比英文长20%-40%) + +**预期产出**: +```javascript +// de-DE.js 新增内容 +{ + // ========== MDS-Modul ========== + 'mds.status.pending': 'Ausstehend', + 'mds.status.compliancePass': 'Compliance bestanden', + 'mds.status.complianceError': 'Compliance fehlerhaft', + 'mds.status.relationPass': 'Relation bestanden', + 'mds.status.relationError': 'Relation fehlerhaft', + 'mds.status.syncError': 'Sync fehlgeschlagen', + 'mds.status.synced': 'Synchronisiert', + + 'mds.action.import': 'Importieren', + 'mds.action.validate': 'Validieren', + 'mds.action.sync': 'Synchronisieren', + // ... 共约73条 +} +``` + +**验收标准**: +- [ ] 翻译键数量与zh-CN.js一致 +- [ ] 德语翻译准确,使用专业术语 +- [ ] 特殊字符正确编码(UTF-8) +- [ ] 文件保存为UTF-8无BOM格式 + +**工作量**: 0.5天 + +--- + +### 2.2 状态枚举改造(Day 2) + +#### 任务1.4: 改造STAGING_STATUS枚举 + +**任务描述**: 将common.js中的STAGING_STATUS改造为动态翻译 + +**涉及文件**: +- `static/mds/js/common.js` + +**具体工作**: +- 将label字段改为labelKey +- 添加getter动态获取翻译 +- 确保i18n未初始化时的回退机制 + +**改造前**: +```javascript +const STAGING_STATUS = { + PENDING: { + value: 'pending', + label: '待处理', + color: '#ff9300', + icon: '⏳' + } +}; +``` + +**改造后**: +```javascript +const STAGING_STATUS = { + PENDING: { + value: 'pending', + labelKey: 'mds.status.pending', + color: '#ff9300', + icon: '⏳', + get label() { + return typeof i18n !== 'undefined' ? + i18n.t(this.labelKey) : '待处理'; + } + } +}; +``` + +**验收标准**: +- [ ] 所有状态枚举都使用getter +- [ ] i18n未初始化时显示中文回退 +- [ ] 语言切换后状态标签自动更新 +- [ ] 控制台无报错 + +**工作量**: 0.5天 + +--- + +#### 任务1.5: 改造status-card.js组件 + +**任务描述**: 改造状态统计卡片组件,支持动态翻译 + +**涉及文件**: +- `static/mds/js/status-card.js` + +**具体工作**: +- 渲染状态卡片时使用STAGING_STATUS.label +- 监听languageChanged事件,刷新卡片 +- 确保切换语言后数据正确显示 + +**关键代码**: +```javascript +// 渲染状态卡片 +function renderStatusCards() { + const statuses = Object.values(STAGING_STATUS); + statuses.forEach(status => { + // label自动动态翻译 + const label = status.label; + // ... + }); +} + +// 监听语言切换事件 +window.addEventListener('languageChanged', () => { + renderStatusCards(); +}); +``` + +**验收标准**: +- [ ] 状态卡片显示三语言文本 +- [ ] 语言切换后卡片自动刷新 +- [ ] 数据统计正确 + +**工作量**: 0.5天 + +--- + +#### 任务1.6: 改造其他枚举对象 + +**任务描述**: 改造其他包含中文label的枚举对象 + +**涉及文件**: +- `static/mds/js/common.js` + +**具体工作**: +- 检查其他枚举对象(如BUTTON_TEXT, ERROR_MSG等) +- 统一改造为labelKey + getter模式 +- 确保所有硬编码文本都被翻译键替换 + +**验收标准**: +- [ ] 所有枚举都支持动态翻译 +- [ ] 无遗漏的硬编码中文文本 +- [ ] 三语言切换测试通过 + +**工作量**: 0.5天 + +--- + +### 2.3 验证与测试(Day 3-4) + +#### 任务1.7: 创建语言切换UI + +**任务描述**: 在导航栏添加三语言选择器 + +**涉及文件**: +- `static/mds/index.html` + +**具体工作**: +- 添加语言选择下拉框 +- 复用Monitor的语言选择器样式 +- 绑定切换事件处理函数 + +**预期产出**: +```html + +``` + +**验收标准**: +- [ ] 语言选择器正确显示 +- [ ] 样式与Monitor一致 +- [ ] 三语言图标正确 + +**工作量**: 0.5天 + +--- + +#### 任务1.8: 实现无刷新语言切换 + +**任务描述**: 实现语言切换功能,无刷新更新页面文本 + +**涉及文件**: +- `static/mds/js/mds-page-controller.js` (新增函数) + +**具体工作**: +- 实现switchLanguage函数 +- 调用i18n.switchLanguage切换语言 +- 更新动态元素(表格、卡片、弹窗) +- 触发languageChanged事件 + +**关键代码**: +```javascript +async function switchLanguage(lang) { + if (typeof i18n === 'undefined') { + console.warn('i18n not initialized'); + return; + } + + await i18n.switchLanguage(lang); + updateDynamicElements(); + + window.dispatchEvent(new CustomEvent('languageChanged', { + detail: { lang: lang } + })); +} + +function updateDynamicElements() { + // 更新状态卡片 + if (window.statusCardInstance) { + window.statusCardInstance.refresh(); + } + + // 更新表格 + if (window.dataTableInstance) { + window.dataTableInstance.refresh(); + } + + // 更新已打开的模态框 + const modals = document.querySelectorAll('.modal.show'); + modals.forEach(modal => { + modal.querySelectorAll('[data-i18n]').forEach(el => { + const key = el.getAttribute('data-i18n'); + el.textContent = i18n.t(key); + }); + }); +} +``` + +**验收标准**: +- [ ] 语言切换无页面刷新 +- [ ] 保持表格筛选条件 +- [ ] 保持分页状态 +- [ ] 保持滚动位置 +- [ ] 无白屏闪烁 + +**工作量**: 1天 + +--- + +#### 任务1.9: 测试状态枚举翻译 + +**任务描述**: 测试状态枚举在三种语言下的翻译 + +**涉及文件**: +- 所有使用STAGING_STATUS的文件 + +**具体工作**: +- 切换到中文,验证状态标签显示"待处理"等 +- 切换到英文,验证显示"Pending"等 +- 切换到德语,验证显示"Ausstehend"等 +- 测试语言切换后的自动更新 + +**验收标准**: +- [ ] 中英德三语言翻译正确 +- [ ] 语言切换后立即更新 +- [ ] 控制台无报错 + +**工作量**: 0.5天 + +--- + +#### 任务1.10: 测试操作按钮翻译 + +**任务描述**: 测试操作按钮在三语言下的翻译 + +**具体工作**: +- 测试"导入"、"校验"、"推送"等按钮 +- 验证三语言显示 +- 测试德语长文本布局 + +**验收标准**: +- [ ] 所有按钮文本翻译正确 +- [ ] 德语文本无溢出 +- [ ] 按钮样式正常 + +**工作量**: 0.5天 + +--- + +#### 任务1.11: 测试无刷新切换 + +**任务描述**: 测试无刷新语言切换功能 + +**具体工作**: +- 在表格筛选状态下切换语言 +- 在分页状态下切换语言 +- 在表单输入状态下切换语言 +- 验证状态保持 + +**验收标准**: +- [ ] 筛选条件不丢失 +- [ ] 分页状态保持 +- [ ] 表单输入不丢失 +- [ ] 滚动位置保持 + +**工作量**: 0.5天 + +--- + +#### 任务1.12: 测试德语布局适配 + +**任务描述**: 测试德语长文本的布局适配 + +**具体工作**: +- 检查所有按钮是否溢出 +- 检查表格列宽是否足够 +- 检查弹窗是否显示完整 +- 必要时调整CSS样式 + +**验收标准**: +- [ ] 无文本溢出 +- [ ] 无布局错乱 +- [ ] 德语特殊字符正确显示 + +**工作量**: 0.5天 + +--- + +#### 任务1.13: 编写Phase 1测试报告 + +**任务描述**: 记录Phase 1的测试结果 + +**涉及文件**: +- `docs/spec/MDS-i18n-Phase1-Test-Report.md` (新建) + +**具体工作**: +- 记录测试用例 +- 记录测试结果 +- 记录发现的问题 +- 记录解决方案 + +**验收标准**: +- [ ] 测试报告完整 +- [ ] 所有问题已解决 + +**工作量**: 0.5天 + +--- + +#### 任务1.14: Phase 1总结与评审 + +**任务描述**: 总结Phase 1工作,进行代码评审 + +**具体工作**: +- 检查代码质量 +- 检查翻译键命名规范 +- 检查三语言包一致性 +- 进行代码评审 + +**验收标准**: +- [ ] 代码质量合格 +- [ ] 翻译键规范统一 +- [ ] 三语言包键数量一致 +- [ ] 评审通过 + +**工作量**: 0.5天 + +--- + +## 三、Phase 2任务清单(导航与弹窗,5天) + +### 3.1 HTML页面改造(Day 5-6) + +#### 任务2.1: 改造index.html + +**任务描述**: 为index.html添加data-i18n属性 + +**涉及文件**: +- `static/mds/index.html` + +**具体工作**: +- 提取所有硬编码中文文本 +- 为文本元素添加data-i18n属性 +- 提取P2级文本(导航菜单,14处) + +**改造示例**: +```html + +
数据清洗管理系统
+ + +
数据清洗管理系统
+``` + +**预期产出**: +- 导航菜单翻译: mds.nav.material, mds.nav.bom等 +- 全局操作按钮翻译 +- 卡片标题翻译 + +**验收标准**: +- [ ] 所有中文文本都添加data-i18n +- [ ] 翻译键命名规范 +- [ ] 页面结构不变 + +**工作量**: 1天 + +--- + +#### 任务2.2: 改造template.html + +**任务描述**: 为数据操作页面模板添加data-i18n属性 + +**涉及文件**: +- `static/mds/pages/template.html` + +**具体工作**: +- 提取所有硬编码中文文本 +- 添加data-i18n属性 +- 包括表格、筛选框、分页控件等 + +**改造示例**: +```html + + + + + +``` + +**验收标准**: +- [ ] 所有文本元素都有data-i18n +- [ ] 动态生成的内容预留翻译钩子 +- [ ] 页面功能不变 + +**工作量**: 1天 + +--- + +#### 任务2.3: 改造user-guide.html + +**任务描述**: 为操作指引页面添加data-i18n属性 + +**涉及文件**: +- `static/mds/user-guide.html` + +**具体工作**: +- 提取操作指引文本 +- 添加data-i18n属性 +- 翻译指引说明 + +**验收标准**: +- [ ] 所有文本都有翻译 +- [ ] 三语言显示正确 +- [ ] 布局不变 + +**工作量**: 0.5天 + +--- + +#### 任务2.4: 提取P2级翻译键 + +**任务描述**: 提取导航菜单等P2级文本的翻译键 + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` +- `static/lib/i18n/en-US.js` +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 提取导航菜单文本(14处) +- 添加到三语言包 +- 编写翻译 + +**预期产出**: +```javascript +// zh-CN.js +'mds.nav.material': '物料', +'mds.nav.matVer': '产线版本', +'mds.nav.workcenter': '工作中心', +'mds.nav.matWc': '工艺路线', +'mds.nav.bom': 'BOM', +'mds.nav.mold': '模具', +'mds.nav.matWcMold': '机台模具', +``` + +**验收标准**: +- [ ] 翻译键数量正确(约14处) +- [ ] 三语言翻译准确 + +**工作量**: 0.5天 + +--- + +#### 任务2.5: 测试HTML页面翻译 + +**任务描述**: 测试三个HTML页面的翻译效果 + +**具体工作**: +- 测试index.html三语言显示 +- 测试template.html三语言显示 +- 测试user-guide.html三语言显示 +- 测试语言切换功能 + +**验收标准**: +- [ ] 所有页面文本正确翻译 +- [ ] 语言切换后立即更新 +- [ ] 无布局错乱 + +**工作量**: 0.5天 + +--- + +### 3.2 弹窗组件改造(Day 7-9) + +#### 任务2.6: 改造modal-manager.js基础函数 + +**任务描述**: 改造模态框管理器的基础函数 + +**涉及文件**: +- `static/mds/js/modal-manager.js` + +**具体工作**: +- 改造showConfirm函数,支持翻译键 +- 改造showAlert函数 +- 改造showPrompt函数 +- 确保弹窗标题、内容支持翻译 + +**改造示例**: +```javascript +// 改造前 +function showConfirm(title, message, onConfirm) { + // ... +} + +// 改造后 +function showConfirm(titleKey, messageKey, onConfirm, params = {}) { + const title = typeof i18n !== 'undefined' ? + i18n.t(titleKey) : titleKey; + const message = typeof i18n !== 'undefined' ? + i18n.t(messageKey, params) : messageKey; + // ... +} +``` + +**验收标准**: +- [ ] 所有弹窗函数支持翻译键 +- [ ] 支持参数化翻译 +- [ ] 控制台无报错 + +**工作量**: 1天 + +--- + +#### 任务2.7: 改造导入弹窗 + +**任务描述**: 改造Excel导入弹窗的翻译 + +**涉及文件**: +- `static/mds/js/modal-manager.js` +- `static/lib/i18n/zh-CN.js`等 + +**具体工作**: +- 改造弹窗标题翻译 +- 改造拖拽提示翻译 +- 改造按钮翻译 +- 提取P3级弹窗文本 + +**预期产出**: +```javascript +// 翻译键 +'mds.modal.importTitle': '导入Excel数据', +'mds.upload.dragDrop': '点击或拖拽文件上传(支持 .xlsx, .xls, .csv)', +'mds.modal.confirm': '确认', +'mds.modal.cancel': '取消', +``` + +**验收标准**: +- [ ] 弹窗标题翻译正确 +- [ ] 拖拽提示翻译正确 +- [ ] 按钮翻译正确 + +**工作量**: 1天 + +--- + +#### 任务2.8: 改造筛选弹窗 + +**任务描述**: 改造精准筛选弹窗的翻译 + +**涉及文件**: +- `static/mds/js/modal-manager.js` + +**具体工作**: +- 改造筛选弹窗标题 +- 改造筛选条件文本 +- 改造按钮文本 + +**验收标准**: +- [ ] 弹窗内容翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 0.5天 + +--- + +#### 任务2.9: 改造编辑弹窗 + +**任务描述**: 改造记录编辑弹窗的翻译 + +**涉及文件**: +- `static/mds/js/form-renderer.js` + +**具体工作**: +- 改造form-renderer.js +- 改造表单标签翻译 +- 改造表单验证消息翻译 +- 改造按钮文本 + +**验收标准**: +- [ ] 表单标签翻译正确 +- [ ] 验证消息翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 1天 + +--- + +#### 任务2.10: 提取P3级翻译键 + +**任务描述**: 提取弹窗相关文本的翻译键(约120处) + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` +- `static/lib/i18n/en-US.js` +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 提取所有弹窗文本 +- 编写三语言翻译 +- 添加到语言包 + +**验收标准**: +- [ ] 翻译键数量正确(约120处) +- [ ] 三语言翻译准确 +- [ ] 键命名规范统一 + +**工作量**: 1天 + +--- + +#### 任务2.11: 实现弹窗语言切换监听 + +**任务描述**: 实现弹窗在语言切换时的动态更新 + +**涉及文件**: +- `static/mds/js/modal-manager.js` + +**具体工作**: +- 监听languageChanged事件 +- 更新已打开弹窗的文本 +- 确保切换语言后弹窗内容更新 + +**关键代码**: +```javascript +window.addEventListener('languageChanged', () => { + const modals = document.querySelectorAll('.modal.show'); + modals.forEach(modal => { + modal.querySelectorAll('[data-i18n]').forEach(el => { + const key = el.getAttribute('data-i18n'); + el.textContent = i18n.t(key); + }); + }); +}); +``` + +**验收标准**: +- [ ] 语言切换后弹窗内容更新 +- [ ] 不关闭弹窗 +- [ ] 数据不丢失 + +**工作量**: 0.5天 + +--- + +#### 任务2.12: 测试弹窗翻译 + +**任务描述**: 测试所有弹窗的翻译效果 + +**具体工作**: +- 测试导入弹窗三语言显示 +- 测试筛选弹窗三语言显示 +- 测试编辑弹窗三语言显示 +- 测试确认弹窗三语言显示 + +**验收标准**: +- [ ] 所有弹窗翻译正确 +- [ ] 语言切换后弹窗更新 +- [ ] 功能正常 + +**工作量**: 0.5天 + +--- + +#### 任务2.13: 测试德语弹窗布局 + +**任务描述**: 测试德语环境下弹窗的布局 + +**具体工作**: +- 检查弹窗宽度是否足够 +- 检查按钮文本是否溢出 +- 必要时调整弹窗样式 + +**验收标准**: +- [ ] 无文本溢出 +- [ ] 无布局错乱 +- [ ] 弹窗美观 + +**工作量**: 0.5天 + +--- + +#### 任务2.14: 编写Phase 2测试报告 + +**任务描述**: 记录Phase 2的测试结果 + +**涉及文件**: +- `docs/spec/MDS-i18n-Phase2-Test-Report.md` (新建) + +**验收标准**: +- [ ] 测试报告完整 +- [ ] 所有问题已解决 + +**工作量**: 0.5天 + +--- + +#### 任务2.15: Phase 2总结与评审 + +**任务描述**: 总结Phase 2工作,进行代码评审 + +**验收标准**: +- [ ] 代码质量合格 +- [ ] 翻译键规范统一 +- [ ] 评审通过 + +**工作量**: 0.5天 + +--- + +#### 任务2.16: 提交Phase 2代码 + +**任务描述**: 提交Phase 2的代码变更 + +**具体工作**: +- 检查代码变更 +- 编写提交信息 +- 提交代码 + +**验收标准**: +- [ ] 代码提交成功 +- [ ] 提交信息清晰 + +**工作量**: 0.5天 + +--- + +## 四、Phase 3任务清单(错误与表格,6天) + +### 4.1 错误消息处理(Day 10-11) + +#### 任务3.1: 设计错误码映射表 + +**任务描述**: 设计后端错误码到翻译键的映射表 + +**涉及文件**: +- `static/mds/js/common.js` (新增ERROR_CODE_MAP) + +**具体工作**: +- 定义错误码常量 +- 创建错误码到翻译键的映射 +- 定义参数化错误模板 + +**预期产出**: +```javascript +// 错误码常量 +const ERROR_CODES = { + DUPLICATE_KEY: 'DUPLICATE_KEY', + INVALID_FORMAT: 'INVALID_FORMAT', + FOREIGN_KEY_VIOLATION: 'FOREIGN_KEY_VIOLATION', + VALIDATION_FAILED: 'VALIDATION_FAILED' +}; + +// 错误码到翻译键的映射 +const ERROR_CODE_MAP = { + DUPLICATE_KEY: 'mds.error.DUPLICATE_KEY', + INVALID_FORMAT: 'mds.error.INVALID_FORMAT', + FOREIGN_KEY_VIOLATION: 'mds.error.FOREIGN_KEY_VIOLATION', + VALIDATION_FAILED: 'mds.error.VALIDATION_FAILED' +}; +``` + +**验收标准**: +- [ ] 错误码定义完整 +- [ ] 映射关系正确 +- [ ] 命名规范统一 + +**工作量**: 0.5天 + +--- + +#### 任务3.2: 实现错误翻译函数 + +**任务描述**: 实现后端错误消息的统一翻译函数 + +**涉及文件**: +- `static/mds/js/common.js` (新增translateError函数) + +**具体工作**: +- 实现translateError函数 +- 处理错误码和参数 +- 支持参数化翻译 +- 提供回退机制 + +**关键代码**: +```javascript +function translateError(response) { + // 检查是否有错误对象 + if (!response.error) { + return response.message || 'Unknown error'; + } + + const { code, params = {} } = response.error; + const errorKey = ERROR_CODE_MAP[code] || `mds.error.${code}`; + + // 使用i18n翻译 + if (typeof i18n !== 'undefined') { + const translated = i18n.t(errorKey, params); + // 如果翻译键不存在,返回错误码 + if (translated !== errorKey) { + return translated; + } + } + + // 回退:返回错误码 + return `Error: ${code}`; +} +``` + +**验收标准**: +- [ ] 函数正确处理错误码 +- [ ] 支持参数化翻译 +- [ ] 回退机制有效 + +**工作量**: 1天 + +--- + +#### 任务3.3: 改造API错误处理 + +**任务描述**: 改造所有API调用的错误处理 + +**涉及文件**: +- `static/mds/js/mds-page-controller.js` +- `static/mds/js/data-table.js` +- `static/mds/js/global-ops-controller.js` + +**具体工作**: +- 查找所有API调用 +- 改造错误处理逻辑 +- 使用translateError函数 + +**改造示例**: +```javascript +// 改造前 +async function handleResponse(response) { + if (!response.success) { + showError(response.message); + } +} + +// 改造后 +async function handleResponse(response) { + if (!response.success) { + const errorMsg = translateError(response); + showError(errorMsg); + } +} +``` + +**验收标准**: +- [ ] 所有API错误都使用translateError +- [ ] 错误消息支持三语言 +- [ ] 功能正常 + +**工作量**: 1天 + +--- + +#### 任务3.4: 提取P4级翻译键 + +**任务描述**: 提取错误消息相关的翻译键(约85处) + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` +- `static/lib/i18n/en-US.js` +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 提取所有错误消息文本 +- 编写三语言翻译 +- 支持参数化翻译 + +**预期产出**: +```javascript +// zh-CN.js +'mds.error.DUPLICATE_KEY': '数据重复: {field}={value} 已存在', +'mds.error.INVALID_FORMAT': '格式错误: {field} 格式不正确', +'mds.error.FOREIGN_KEY_VIOLATION': '外键约束违反: {field} 引用不存在', +'mds.error.VALIDATION_FAILED': '校验失败: {reason}', +'mds.error.queryFailed': '查询失败', +'mds.error.uploadFailed': '上传失败', +'mds.error.timeout': '请求超时', +// ... 共约85条 +``` + +**验收标准**: +- [ ] 翻译键数量正确(约85处) +- [ ] 三语言翻译准确 +- [ ] 参数化翻译正确 + +**工作量**: 1天 + +--- + +#### 任务3.5: 测试错误消息翻译 + +**任务描述**: 测试各种错误消息的翻译效果 + +**具体工作**: +- 模拟各种错误响应 +- 测试三语言错误提示 +- 测试参数化翻译 + +**验收标准**: +- [ ] 所有错误消息翻译正确 +- [ ] 参数化翻译正确 +- [ ] 回退机制有效 + +**工作量**: 0.5天 + +--- + +### 4.2 表格组件改造(Day 12-15) + +#### 任务3.6: 改造data-table.js基础函数 + +**任务描述**: 改造数据表格组件的基础函数 + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 改造表格列标题翻译 +- 改造空状态提示 +- 改造加载状态提示 +- 添加语言切换事件监听 + +**验收标准**: +- [ ] 表格列标题支持翻译 +- [ ] 空状态提示支持翻译 +- [ ] 加载状态提示支持翻译 + +**工作量**: 1天 + +--- + +#### 任务3.7: 改造分页控件 + +**任务描述**: 改造表格分页控件的翻译 + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 改造"条/页"文本 +- 改造"共X条"文本 +- 改造"上一页"、"下一页"文本 +- 改造页码显示 + +**预期产出**: +```javascript +// 翻译键 +'mds.table.perPage': '条/页', +'mds.table.total': '共 {count} 条', +'mds.table.prevPage': '上一页', +'mds.table.nextPage': '下一页', +``` + +**验收标准**: +- [ ] 分页控件文本翻译正确 +- [ ] 三语言显示正确 +- [ ] 功能正常 + +**工作量**: 1天 + +--- + +#### 任务3.8: 改造表格操作按钮 + +**任务描述**: 改造表格中的操作按钮(编辑、删除等) + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 改造"编辑"按钮 +- 改造"删除"按钮 +- 改造"导出"按钮 +- 使用data-i18n属性 + +**验收标准**: +- [ ] 操作按钮文本翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 0.5天 + +--- + +#### 任务3.9: 改造空状态提示 + +**任务描述**: 改造表格无数据时的提示文本 + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 改造"暂无数据"文本 +- 改造"加载中..."文本 +- 支持动态翻译 + +**预期产出**: +```javascript +// 翻译键 +'mds.table.noData': '暂无数据', +'mds.table.loading': '加载中...', +``` + +**验收标准**: +- [ ] 空状态提示翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 0.5天 + +--- + +#### 任务3.10: 改造全选控件 + +**任务描述**: 改造表格全选复选框的文本 + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 改造"全选"文本 +- 支持动态翻译 + +**验收标准**: +- [ ] 全选文本翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 0.5天 + +--- + +#### 任务3.11: 提取P5级翻译键 + +**任务描述**: 提取表格相关文本的翻译键(约150处) + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` +- `static/lib/i18n/en-US.js` +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 提取所有表格文本 +- 编写三语言翻译 +- 支持参数化翻译 + +**验收标准**: +- [ ] 翻译键数量正确(约150处) +- [ ] 三语言翻译准确 + +**工作量**: 1天 + +--- + +#### 任务3.12: 实现表格语言切换监听 + +**任务描述**: 实现表格在语言切换时的刷新 + +**涉及文件**: +- `static/mds/js/data-table.js` + +**具体工作**: +- 监听languageChanged事件 +- 实现refresh方法 +- 重新渲染表格 + +**关键代码**: +```javascript +class DataTable { + refresh() { + // 重新渲染列标题 + this.renderHeaders(); + // 重新渲染分页控件 + this.renderPagination(); + // 重新渲染空状态 + if (this.data.length === 0) { + this.renderEmptyState(); + } + } +} + +// 监听语言切换 +window.addEventListener('languageChanged', () => { + if (window.dataTableInstance) { + window.dataTableInstance.refresh(); + } +}); +``` + +**验收标准**: +- [ ] 语言切换后表格刷新 +- [ ] 数据不丢失 +- [ ] 分页状态保持 + +**工作量**: 0.5天 + +--- + +#### 任务3.13: 测试表格翻译 + +**任务描述**: 测试表格组件的翻译效果 + +**具体工作**: +- 测试表格列标题翻译 +- 测试分页控件翻译 +- 测试空状态提示翻译 +- 测试操作按钮翻译 + +**验收标准**: +- [ ] 所有表格文本翻译正确 +- [ ] 语言切换后表格更新 +- [ ] 功能正常 + +**工作量**: 0.5天 + +--- + +#### 任务3.14: 测试德语表格布局 + +**任务描述**: 测试德语环境下表格的布局 + +**具体工作**: +- 检查列宽是否足够 +- 检查按钮是否溢出 +- 必要时调整CSS样式 + +**验收标准**: +- [ ] 无文本溢出 +- [ ] 无布局错乱 +- [ ] 表格美观 + +**工作量**: 0.5天 + +--- + +#### 任务3.15: 编写Phase 3测试报告 + +**任务描述**: 记录Phase 3的测试结果 + +**涉及文件**: +- `docs/spec/MDS-i18n-Phase3-Test-Report.md` (新建) + +**验收标准**: +- [ ] 测试报告完整 +- [ ] 所有问题已解决 + +**工作量**: 0.5天 + +--- + +#### 任务3.16: Phase 3总结与评审 + +**任务描述**: 总结Phase 3工作,进行代码评审 + +**验收标准**: +- [ ] 代码质量合格 +- [ ] 翻译键规范统一 +- [ ] 评审通过 + +**工作量**: 0.5天 + +--- + +#### 任务3.17: 提交Phase 3代码 + +**任务描述**: 提交Phase 3的代码变更 + +**验收标准**: +- [ ] 代码提交成功 +- [ ] 提交信息清晰 + +**工作量**: 0.5天 + +--- + +#### 任务3.18: 改造表格筛选控件 + +**任务描述**: 改造表格筛选区域的文本翻译 + +**涉及文件**: +- `static/mds/js/data-table.js` +- `static/mds/pages/template.html` + +**具体工作**: +- 改造筛选按钮文本 +- 改造筛选条件显示 +- 改造重置按钮文本 + +**验收标准**: +- [ ] 筛选控件文本翻译正确 +- [ ] 三语言显示正确 + +**工作量**: 0.5天 + +--- + +## 五、Phase 4任务清单(完成与测试,4天) + +### 5.1 完成剩余翻译(Day 16-17) + +#### 任务4.1: 改造mds-page-controller.js + +**任务描述**: 完成页面控制器的剩余翻译 + +**涉及文件**: +- `static/mds/js/mds-page-controller.js` + +**具体工作**: +- 查找所有硬编码中文文本 +- 替换为i18n.t()调用 +- 确保所有文本都支持翻译 + +**验收标准**: +- [ ] 无硬编码中文文本 +- [ ] 所有文本支持翻译 +- [ ] 功能正常 + +**工作量**: 1天 + +--- + +#### 任务4.2: 改造global-ops-controller.js + +**任务描述**: 完成全局操作控制器的翻译 + +**涉及文件**: +- `static/mds/js/global-ops-controller.js` + +**具体工作**: +- 改造全局操作按钮 +- 改造操作提示消息 +- 改造确认对话框 + +**验收标准**: +- [ ] 所有文本支持翻译 +- [ ] 功能正常 + +**工作量**: 0.5天 + +--- + +#### 任务4.3: 提取P6级翻译键 + +**任务描述**: 提取剩余文本的翻译键(约304处) + +**涉及文件**: +- `static/lib/i18n/zh-CN.js` +- `static/lib/i18n/en-US.js` +- `static/lib/i18n/de-DE.js` + +**具体工作**: +- 提取所有剩余文本 +- 编写三语言翻译 +- 检查翻译键完整性 + +**验收标准**: +- [ ] 翻译键数量正确(约304处) +- [ ] 三语言翻译准确 +- [ ] 无遗漏文本 + +**工作量**: 1天 + +--- + +#### 任务4.4: 检查翻译键完整性 + +**任务描述**: 检查所有文件中使用的翻译键是否都存在 + +**具体工作**: +- 扫描所有JS文件中的i18n.t()调用 +- 提取所有翻译键 +- 对比语言包中的键 +- 补充缺失的翻译键 + +**验收标准**: +- [ ] 无缺失的翻译键 +- [ ] 三语言包键数量一致 +- [ ] 无未使用的翻译键 + +**工作量**: 0.5天 + +--- + +#### 任务4.5: 清理调试代码 + +**任务描述**: 清理临时添加的调试代码和注释 + +**涉及文件**: +- 所有修改过的文件 + +**具体工作**: +- 删除console.log调试语句 +- 删除临时注释 +- 整理代码格式 + +**验收标准**: +- [ ] 无调试代码 +- [ ] 代码整洁 +- [ ] 注释清晰 + +**工作量**: 0.5天 + +--- + +### 5.2 全面测试(Day 18-19) + +#### 任务4.6: 功能测试-所有页面 + +**任务描述**: 测试所有页面的翻译功能 + +**具体工作**: +- 测试index.html所有文本翻译 +- 测试template.html所有文本翻译 +- 测试user-guide.html所有文本翻译 +- 测试所有弹窗文本翻译 + +**验收标准**: +- [ ] 所有页面文本正确翻译 +- [ ] 三语言显示正确 +- [ ] 功能正常 + +**工作量**: 1天 + +--- + +#### 任务4.7: 功能测试-三语言切换 + +**任务描述**: 测试三语言之间的切换功能 + +**具体工作**: +- 测试中文切换到英文 +- 测试英文切换到德语 +- 测试德语切换到中文 +- 测试语言选择的持久化 + +**验收标准**: +- [ ] 切换流畅,无白屏 +- [ ] 状态保持 +- [ ] 语言持久化到localStorage + +**工作量**: 0.5天 + +--- + +#### 任务4.8: 功能测试-无刷新切换 + +**任务描述**: 测试无刷新语言切换的所有场景 + +**具体工作**: +- 测试表格筛选状态下切换 +- 测试分页状态下切换 +- 测试表单输入状态下切换 +- 测试弹窗打开状态下切换 +- 测试滚动位置保持 + +**验收标准**: +- [ ] 筛选条件不丢失 +- [ ] 分页状态保持 +- [ ] 表单输入保持 +- [ ] 弹窗不关闭 +- [ ] 滚动位置保持 + +**工作量**: 0.5天 + +--- + +#### 任务4.9: 性能测试 + +**任务描述**: 测试国际化功能对性能的影响 + +**具体工作**: +- 测试语言包加载时间 +- 测试语言切换响应时间 +- 测试内存占用 +- 对比改造前后的性能 + +**验收标准**: +- [ ] 语言包加载时间 < 300ms +- [ ] 语言切换响应时间 < 100ms +- [ ] 内存占用增加 < 8MB + +**工作量**: 0.5天 + +--- + +#### 任务4.10: 浏览器兼容性测试 + +**任务描述**: 测试不同浏览器的兼容性 + +**具体工作**: +- Chrome浏览器测试 +- Firefox浏览器测试 +- Edge浏览器测试 +- Safari浏览器测试(如有条件) + +**验收标准**: +- [ ] 所有浏览器正常运行 +- [ ] 德语特殊字符正确显示 +- [ ] 无布局错乱 + +**工作量**: 0.5天 + +--- + +#### 任务4.11: 德语专项测试 + +**任务描述**: 德语环境的专项测试 + +**具体工作**: +- 测试德语所有文本显示 +- 测试德语特殊字符 +- 测试德语长文本布局 +- 测试德语文本换行 + +**验收标准**: +- [ ] 德语所有文本正确显示 +- [ ] 特殊字符无乱码 +- [ ] 长文本布局合理 + +**工作量**: 0.5天 + +--- + +#### 任务4.12: 回归测试 + +**任务描述**: 确保国际化改造不影响现有功能 + +**具体工作**: +- 测试数据导入功能 +- 测试数据校验功能 +- 测试数据推送功能 +- 测试数据查询功能 +- 测试所有业务流程 + +**验收标准**: +- [ ] 所有业务功能正常 +- [ ] 无功能退化 +- [ ] 无新增bug + +**工作量**: 1天 + +--- + +#### 任务4.13: 编写最终测试报告 + +**任务描述**: 编写完整的测试报告 + +**涉及文件**: +- `docs/spec/MDS-i18n-Final-Test-Report.md` (新建) + +**具体工作**: +- 记录所有测试用例 +- 记录所有测试结果 +- 记录性能数据 +- 记录浏览器兼容性结果 + +**验收标准**: +- [ ] 测试报告完整 +- [ ] 数据准确 +- [ ] 问题已解决 + +**工作量**: 0.5天 + +--- + +#### 任务4.14: 编写实施文档 + +**任务描述**: 编写完整的实施文档 + +**涉及文件**: +- `docs/spec/MDS-i18n-Implementation-Summary.md` (新建) + +**具体工作**: +- 记录实施过程 +- 记录技术方案 +- 记录关键决策 +- 记录维护指南 + +**验收标准**: +- [ ] 文档完整 +- [ ] 内容清晰 +- [ ] 可维护性强 + +**工作量**: 0.5天 + +--- + +## 六、任务依赖关系图 + +### 6.1 Phase内部依赖 + +``` +Phase 1: +任务1.1 → 任务1.2 → 任务1.3 (语言包创建,串行) +任务1.4 → 任务1.5 → 任务1.6 (状态枚举改造,串行) +任务1.7 → 任务1.8 (UI实现,串行) +任务1.9, 1.10, 1.11, 1.12 (测试,并行,依赖1.1-1.8) +任务1.13 → 任务1.14 (文档与评审,串行) + +Phase 2: +任务2.1, 2.2, 2.3 (HTML改造,并行) +任务2.4 (翻译键提取,依赖2.1-2.3) +任务2.6 → 任务2.7 → 任务2.8 → 任务2.9 (弹窗改造,串行) +任务2.10 (翻译键提取,依赖2.6-2.9) +任务2.11 (语言切换监听,依赖2.6) +任务2.12, 2.13 (测试,并行,依赖2.1-2.11) +任务2.14 → 任务2.15 → 任务2.16 (文档与提交,串行) + +Phase 3: +任务3.1 → 任务3.2 → 任务3.3 (错误处理,串行) +任务3.4 (翻译键提取,依赖3.1-3.3) +任务3.5 (测试,依赖3.1-3.4) +任务3.6 → 任务3.7 → 任务3.8 → 任务3.9 → 任务3.10 (表格改造,串行) +任务3.11 (翻译键提取,依赖3.6-3.10) +任务3.12 (语言切换监听,依赖3.6) +任务3.13, 3.14, 3.18 (测试,并行,依赖3.6-3.12) +任务3.15 → 任务3.16 → 任务3.17 (文档与提交,串行) + +Phase 4: +任务4.1, 4.2 (代码改造,并行) +任务4.3 (翻译键提取,依赖4.1-4.2) +任务4.4 → 任务4.5 (检查与清理,串行) +任务4.6, 4.7, 4.8, 4.9, 4.10, 4.11, 4.12 (全面测试,并行) +任务4.13 → 任务4.14 (文档编写,串行) +``` + +### 6.2 Phase间依赖 + +``` +Phase 1完成 → Phase 2开始 +Phase 2完成 → Phase 3开始 +Phase 3完成 → Phase 4开始 +``` + +### 6.3 关键路径 + +``` +任务1.1 → 任务1.4 → 任务1.8 → 任务2.6 → 任务3.1 → 任务3.6 → 任务4.1 → 任务4.6 → 任务4.12 +``` + +关键路径上的任务不可延误,否则会影响整体进度。 + +--- + +## 七、风险应对预案 + +### 7.1 技术风险 + +#### 风险1: i18n框架兼容性问题 + +**风险描述**: Monitor模块的i18n框架可能不兼容MDS模块 + +**应对措施**: +- Phase 1先测试框架复用可行性 +- 如不兼容,独立实现轻量级i18n +- 预留1天应急时间 + +**触发条件**: Phase 1任务1.8测试失败 + +**应急方案**: 创建独立的MDS-i18n实例 + +--- + +#### 风险2: 状态枚举改造复杂度超预期 + +**风险描述**: 状态枚举在多处使用,改造难度超预期 + +**应对措施**: +- 先梳理所有使用场景 +- 采用渐进式改造 +- 预留0.5天应急时间 + +**触发条件**: 任务1.4-1.6耗时超过1.5天 + +**应急方案**: 分批改造,优先P0级 + +--- + +#### 风险3: 后端错误码改造复杂 + +**风险描述**: 后端返回错误码格式不统一 + +**应对措施**: +- 先调研现有错误格式 +- 设计兼容多种格式的translateError +- 与后端协调统一错误格式 + +**触发条件**: 任务3.2发现错误格式不统一 + +**应急方案**: 前端增加错误格式适配逻辑 + +--- + +### 7.2 进度风险 + +#### 风险4: 翻译工作量超预期 + +**风险描述**: 翻译文本数量超出预估(746处) + +**应对措施**: +- 使用脚本批量提取中文文本 +- 使用翻译工具辅助翻译 +- 分优先级,P0-P3优先 + +**触发条件**: Phase 2结束时翻译完成度<80% + +**应急方案**: 延长Phase 3时间,压缩Phase 4测试时间 + +--- + +#### 风险5: 测试发现大量问题 + +**风险描述**: Phase 4测试发现大量翻译错误或功能bug + +**应对措施**: +- 每个Phase完成后立即测试 +- 及时修复发现的问题 +- 避免问题积累到Phase 4 + +**触发条件**: Phase 4测试发现严重问题>5个 + +**应急方案**: 回退到上一个Phase,修复后重新测试 + +--- + +### 7.3 质量风险 + +#### 风险6: 德语翻译质量差 + +**风险描述**: 德语翻译不准确或不符合德语习惯 + +**应对措施**: +- 使用专业翻译工具(DeepL) +- 德语文本专项测试 +- 必要时人工校对 + +**触发条件**: 德语专项测试发现翻译错误>10处 + +**应急方案**: 重新翻译德语文本,人工校对 + +--- + +#### 风险7: 德语文本布局问题 + +**风险描述**: 德语文本过长导致布局错乱 + +**应对措施**: +- Phase 1即开始布局测试 +- 使用CSS自适应样式 +- 必要时调整组件宽度 + +**触发条件**: 德语布局测试发现溢出>5处 + +**应急方案**: 调整CSS样式,增加德语专项布局适配 + +--- + +### 7.4 协作风险 + +#### 风险8: 与Monitor模块冲突 + +**风险描述**: MDS的i18n改造影响Monitor模块 + +**应对措施**: +- 使用命名空间隔离(monitor., mds.) +- 测试Monitor模块功能 +- 确保向后兼容 + +**触发条件**: Monitor模块功能异常 + +**应急方案**: 回退MDS改造,检查命名空间冲突 + +--- + +#### 风险9: 浏览器兼容性问题 + +**风险描述**: 某些浏览器显示异常 + +**应对措施**: +- 早期进行浏览器测试 +- 使用标准API,避免浏览器特定特性 +- 提供降级方案 + +**触发条件**: 浏览器测试发现兼容性问题 + +**应急方案**: 针对特定浏览器提供降级方案 + +--- + +### 7.5 风险监控 + +**监控频率**: 每日检查 + +**监控指标**: +- 当前进度vs计划进度 +- 测试通过率 +- 发现问题数量 +- 代码质量指标 + +**预警阈值**: +- 进度偏差 > 20% +- 测试通过率 < 80% +- 严重问题 > 3个 + +**应对流程**: +1. 发现风险 → 评估影响 → 制定应对方案 → 执行应对 → 跟踪效果 + +--- + +## 八、附录 + +### 8.1 翻译键命名规范 + +**命名规则**: `{module}.{category}.{item}` + +**示例**: +- `mds.status.pending` - MDS模块的状态文本 +- `mds.action.validate` - MDS模块的操作按钮 +- `mds.error.DUPLICATE_KEY` - MDS模块的错误消息 +- `mds.modal.confirm` - MDS模块的弹窗文本 +- `mds.table.noData` - MDS模块的表格文本 + +**分类**: +- `status` - 状态标签 +- `action` - 操作按钮 +- `nav` - 导航菜单 +- `modal` - 弹窗文本 +- `error` - 错误消息 +- `table` - 表格文本 +- `upload` - 上传相关 +- `validation` - 校验相关 +- `sync` - 推送相关 + +--- + +### 8.2 相关文档 + +- [MDS-i18n实施方案](./MDS-i18n-Implementation-Proposal.md) +- [Monitor-i18n实施计划](./Monitor-i18n-Implementation-Plan.md) +- [AGENTS.md开发指南](../../AGENTS.md) + +--- + +### 8.3 变更历史 + +| 版本 | 日期 | 变更内容 | 作者 | +|------|------|----------|------| +| v1.0 | 2026-05-24 | 初版创建,基于实施方案生成详细任务清单 | CodeArts | + +--- + +**文档状态**: 待执行 +**下一步**: 开始Phase 1任务1.1 - 扩展zh-CN.js语言包 diff --git a/static/lib/i18n/de-DE.js b/static/lib/i18n/de-DE.js index 506fbf6..750a918 100644 --- a/static/lib/i18n/de-DE.js +++ b/static/lib/i18n/de-DE.js @@ -4,497 +4,507 @@ */ window.__i18n_de_DE__ = { // ============ Seitentitel ============ - 'page.title': 'MyAPI Systemüberwachung', - 'page.live_logs': 'Echtzeit-Logs - Systemüberwachung', - 'page.history_logs': 'Protokollverlauf - Systemüberwachung', + 'monitor.page.title': 'MyAPI Systemüberwachung', + 'monitor.page.live_logs': 'Echtzeit-Logs - Systemüberwachung', + 'monitor.page.history_logs': 'Protokollverlauf - Systemüberwachung', // ============ Navigation ============ - 'nav.overview': '📊 Übersicht', - 'nav.database': '🗃️ Datenbank', - 'nav.events': '☎️ Ereignisse', - 'nav.scheduler': '⏰ Planer', - 'nav.http_requests': '📥 HTTP-Anfragen', - 'nav.outbound_requests': '📤 Ausgehend', - 'nav.logs': '📋 Protokolle', + 'monitor.nav.overview': '📊 Übersicht', + 'monitor.nav.database': '🗃️ Datenbank', + 'monitor.nav.events': '☎️ Ereignisse', + 'monitor.nav.scheduler': '⏰ Planer', + 'monitor.nav.http_requests': '📥 HTTP-Anfragen', + 'monitor.nav.outbound_requests': '📤 Ausgehend', + 'monitor.nav.logs': '📋 Protokolle', // ============ Tabs ============ - 'tab.overview': 'Übersicht', - 'tab.database': 'Datenbank', - 'tab.events': 'Ereignisse', - 'tab.scheduler': 'Planer', - 'tab.http': 'HTTP-Anfragen', - 'tab.outbound': 'Ausgehend', - 'tab.logs': 'Systemprotokolle', - 'tab.timeline': 'Zeitachse', - 'tab.chart': 'Diagramme', + 'monitor.tab.overview': 'Übersicht', + 'monitor.tab.database': 'Datenbank', + 'monitor.tab.events': 'Ereignisse', + 'monitor.tab.scheduler': 'Planer', + 'monitor.tab.http': 'HTTP-Anfragen', + 'monitor.tab.outbound': 'Ausgehend', + 'monitor.tab.logs': 'Systemprotokolle', + 'monitor.tab.timeline': 'Zeitachse', + 'monitor.tab.chart': 'Diagramme', // ============ Karten ============ - 'card.resource': 'Ressourcennutzung', - 'card.db_status': 'Datenbankstatus', - 'card.db_connections': 'Datenbankverbindungen', - 'card.event_helpers': 'Ereignis-Helfer', - 'card.scheduler': 'Aufgabenplaner', - 'card.api_requests': 'HTTP-Anfragen', - 'card.outbound_requests': 'Ausgehende Anfragen', - 'card.redis': 'Redis-Status', - 'card.event_listener': 'Ereignis-Listener', - 'card.recent_alerts': 'Aktuelle Warnungen', - 'card.mysql': 'MySQL', - 'card.http_requests_log': 'HTTP-Anfragedatensätze', - 'card.scheduler_detail': 'Planer-Details', - 'card.outbound_requests_log': 'Ausgehende Anfragedatensätze', - 'card.callback_tracker': 'Callback-Tracker', - 'card.event_deduplicator': 'Ereignis-Deduplikator', + 'monitor.card.resource': 'Ressourcennutzung', + 'monitor.card.db_status': 'Datenbankstatus', + 'monitor.card.db_connections': 'Datenbankverbindungen', + 'monitor.card.event_helpers': 'Ereignis-Helfer', + 'monitor.card.scheduler': 'Aufgabenplaner', + 'monitor.card.api_requests': 'HTTP-Anfragen', + 'monitor.card.outbound_requests': 'Ausgehende Anfragen', + 'monitor.card.redis': 'Redis-Status', + 'monitor.card.event_listener': 'Ereignis-Listener', + 'monitor.card.recent_alerts': 'Aktuelle Warnungen', + 'monitor.card.mysql': 'MySQL', + 'monitor.card.http_requests_log': 'HTTP-Anfragedatensätze', + 'monitor.card.scheduler_detail': 'Planer-Details', + 'monitor.card.outbound_requests_log': 'Ausgehende Anfragedatensätze', + 'monitor.card.callback_tracker': 'Callback-Tracker', + 'monitor.card.event_deduplicator': 'Ereignis-Deduplikator', // ============ Kennzahlen ============ - 'metric.cpu': 'CPU-Auslastung', - 'metric.memory': 'Speichernutzung', - 'metric.threads': 'Threads', - 'metric.uptime': 'Laufzeit', - 'metric.total_connections': 'Verbindungen', - 'metric.healthy': 'Gesund', - 'metric.unhealthy': 'Fehlerhaft', - 'metric.degraded': 'Eingeschränkt', - 'metric.total': 'Gesamt', - 'metric.success': 'Erfolg', - 'metric.failed': 'Fehler', - 'metric.pending': 'Ausstehend', - 'metric.active': 'Aktiv', - 'metric.idle': 'Inaktiv', - 'metric.unknown': 'Unbekannt', - 'metric.warning': 'Warnung', - 'metric.events_received': 'Empfangene Ereignisse', - 'metric.events_processed': 'Verarbeitete Ereignisse', - 'metric.events_failed': 'Fehlgeschlagene Ereignisse', - 'metric.jobs_running': 'Laufende Aufgaben', - 'metric.jobs_pending': 'Ausstehende Aufgaben', - 'metric.requests_total': 'Anfragen Gesamt', - 'metric.requests_slow': 'Langsame Anfragen', - 'metric.requests_error': 'Fehlerhafte Anfragen', - 'metric.error_rate': 'Fehlerquote', - 'metric.avg_time': 'Durchschn. Antwort', - 'metric.connection_status': 'Verbindungsstatus', - 'metric.host': 'Host', - 'metric.port': 'Port', - 'metric.database': 'Datenbank', - 'metric.used_connections': 'Verwendete Verbindungen', - 'metric.max_connections': 'Max. Verbindungen', - 'metric.connection_usage': 'Verbindungsnutzung', - 'metric.buffer_size': 'Puffergröße', - 'metric.buffer_threshold': 'Pufferschwellwert', - 'metric.buffer_usage': 'Puffernutzung', - 'metric.events_interrupted': 'Unterbrochen', - 'metric.overall_success_rate': 'Gesamterfolgsquote', - 'metric.active_event_types': 'Aktive Ereignistypen', - 'metric.backpressure_status': 'Rückstau-Status', - 'metric.backpressure_pending': 'Ausstehende Ereignisse', - 'metric.backpressure_usage': 'Rückstau-Nutzung', - 'metric.event_loop_status': 'Ereignisschleifen-Status', - 'metric.pending_callbacks': 'Ausstehende Callbacks', - 'metric.max_retries': 'Max. Wiederholungen', - 'metric.pending_retries': 'Ausstehende Wiederholungen', - 'metric.total_entries': 'Gesamteinträge', - 'metric.active_items': 'Aktive Elemente', - 'metric.ttl_seconds': 'TTL (Sekunden)', - 'metric.max_entries': 'Max. Einträge', - 'metric.dl_total': 'DL-Gesamt', - 'metric.recent_dl': 'Aktuelle DL', - 'metric.process_success_rate': 'Verarbeitungserfolgsquote', - 'metric.scheduler_status': 'Planer-Status', - 'metric.job_count': 'Aufgabenanzahl', - 'metric.pending_events': 'Ausstehende Ereignisse', - 'metric.total_events': 'Gesamtereignisse', - 'metric.file_size': 'Dateigröße', - 'metric.running_status': 'Betriebsstatus', + 'monitor.metric.cpu': 'CPU-Auslastung', + 'monitor.metric.memory': 'Speichernutzung', + 'monitor.metric.threads': 'Threads', + 'monitor.metric.uptime': 'Laufzeit', + 'monitor.metric.total_connections': 'Verbindungen', + 'monitor.metric.healthy': 'Gesund', + 'monitor.metric.unhealthy': 'Fehlerhaft', + 'monitor.metric.degraded': 'Eingeschränkt', + 'monitor.metric.total': 'Gesamt', + 'monitor.metric.success': 'Erfolg', + 'monitor.metric.failed': 'Fehler', + 'monitor.metric.pending': 'Ausstehend', + 'monitor.metric.active': 'Aktiv', + 'monitor.metric.idle': 'Inaktiv', + 'monitor.metric.unknown': 'Unbekannt', + 'monitor.metric.warning': 'Warnung', + 'monitor.metric.events_received': 'Empfangene Ereignisse', + 'monitor.metric.events_processed': 'Verarbeitete Ereignisse', + 'monitor.metric.events_failed': 'Fehlgeschlagene Ereignisse', + 'monitor.metric.jobs_running': 'Laufende Aufgaben', + 'monitor.metric.jobs_pending': 'Ausstehende Aufgaben', + 'monitor.metric.requests_total': 'Anfragen Gesamt', + 'monitor.metric.requests_slow': 'Langsame Anfragen', + 'monitor.metric.requests_error': 'Fehlerhafte Anfragen', + 'monitor.metric.error_rate': 'Fehlerquote', + 'monitor.metric.avg_time': 'Durchschn. Antwort', + 'monitor.metric.connection_status': 'Verbindungsstatus', + 'monitor.metric.host': 'Host', + 'monitor.metric.port': 'Port', + 'monitor.metric.database': 'Datenbank', + 'monitor.metric.used_connections': 'Verwendete Verbindungen', + 'monitor.metric.max_connections': 'Max. Verbindungen', + 'monitor.metric.connection_usage': 'Verbindungsnutzung', + 'monitor.metric.buffer_size': 'Puffergröße', + 'monitor.metric.buffer_threshold': 'Pufferschwellwert', + 'monitor.metric.buffer_usage': 'Puffernutzung', + 'monitor.metric.events_interrupted': 'Unterbrochen', + 'monitor.metric.overall_success_rate': 'Gesamterfolgsquote', + 'monitor.metric.active_event_types': 'Aktive Ereignistypen', + 'monitor.metric.backpressure_status': 'Rückstau-Status', + 'monitor.metric.backpressure_pending': 'Ausstehende Ereignisse', + 'monitor.metric.backpressure_usage': 'Rückstau-Nutzung', + 'monitor.metric.event_loop_status': 'Ereignisschleifen-Status', + 'monitor.metric.pending_callbacks': 'Ausstehende Callbacks', + 'monitor.metric.max_retries': 'Max. Wiederholungen', + 'monitor.metric.pending_retries': 'Ausstehende Wiederholungen', + 'monitor.metric.total_entries': 'Gesamteinträge', + 'monitor.metric.active_items': 'Aktive Elemente', + 'monitor.metric.ttl_seconds': 'TTL (Sekunden)', + 'monitor.metric.max_entries': 'Max. Einträge', + 'monitor.metric.dl_total': 'DL-Gesamt', + 'monitor.metric.recent_dl': 'Aktuelle DL', + 'monitor.metric.process_success_rate': 'Verarbeitungserfolgsquote', + 'monitor.metric.scheduler_status': 'Planer-Status', + 'monitor.metric.job_count': 'Aufgabenanzahl', + 'monitor.metric.pending_events': 'Ausstehende Ereignisse', + 'monitor.metric.total_events': 'Gesamtereignisse', + 'monitor.metric.file_size': 'Dateigröße', + 'monitor.metric.running_status': 'Betriebsstatus', // ============ Status ============ - 'status.healthy': '● System gesund', - 'status.unhealthy': '● System fehlerhaft', - 'status.degraded': '● System eingeschränkt', - 'status.running': 'Läuft', - 'status.checking': 'Prüfe', - 'status.stopped': 'Gestoppt', - 'status.loading': 'Laden...', - 'status.querying': 'Abfrage...', - 'status.exporting': 'Exportiere...', - 'status.no_data': 'Keine Daten', - 'status.connected': 'Verbunden', - 'status.connecting': 'Verbinde...', - 'status.disconnected': 'Getrennt', - 'status.reconnecting': 'Verbinde neu...', - 'status.paused': 'Pausiert', - 'status.enabled': 'Aktiviert', - 'status.disabled': 'Deaktiviert', - 'status.no_db_connections': 'Keine Datenbankverbindungen', - 'status.no_scheduler': 'Keine geplanten Aufgaben', - 'status.no_http_requests': 'Keine HTTP-Anfragen', - 'status.no_alerts': 'Keine Warnungen', - 'status.no_logs': 'Keine Protokolle', - 'status.no_events': 'Keine Ereignisstatistiken', - 'status.no_api_requests': 'Keine API-Anfragedatensätze', - 'status.no_outbound_requests': 'Keine ausgehenden Anfragedatensätze', - 'status.no_dead_letters': 'Keine DL', - 'status.partial_warnings': '● Teilweise Warnungen', - 'status.monitoring': 'Überwachung', + 'monitor.status.healthy': '● System gesund', + 'monitor.status.unhealthy': '● System fehlerhaft', + 'monitor.status.degraded': '● System eingeschränkt', + 'monitor.status.running': 'Läuft', + 'monitor.status.checking': 'Prüfe', + 'monitor.status.stopped': 'Gestoppt', + 'monitor.status.loading': 'Laden...', + 'monitor.status.querying': 'Abfrage...', + 'monitor.status.exporting': 'Exportiere...', + 'monitor.status.no_data': 'Keine Daten', + 'monitor.status.connected': 'Verbunden', + 'monitor.status.connecting': 'Verbinde...', + 'monitor.status.disconnected': 'Getrennt', + 'monitor.status.reconnecting': 'Verbinde neu...', + 'monitor.status.paused': 'Pausiert', + 'monitor.status.enabled': 'Aktiviert', + 'monitor.status.disabled': 'Deaktiviert', + 'monitor.status.no_db_connections': 'Keine Datenbankverbindungen', + 'monitor.status.no_scheduler': 'Keine geplanten Aufgaben', + 'monitor.status.no_http_requests': 'Keine HTTP-Anfragen', + 'monitor.status.no_alerts': 'Keine Warnungen', + 'monitor.status.no_logs': 'Keine Protokolle', + 'monitor.status.no_events': 'Keine Ereignisstatistiken', + 'monitor.status.no_api_requests': 'Keine API-Anfragedatensätze', + 'monitor.status.no_outbound_requests': 'Keine ausgehenden Anfragedatensätze', + 'monitor.status.no_dead_letters': 'Keine DL', + 'monitor.status.partial_warnings': '● Teilweise Warnungen', + 'monitor.status.monitoring': 'Überwachung', // ============ Schaltflächen ============ - 'btn.query': 'Abfrage', - 'btn.reset': 'Zurücksetzen', - 'btn.refresh': 'Aktualisieren', - 'btn.export': 'Exportieren', - 'btn.export_csv': 'CSV Export', - 'btn.export_json': 'JSON Export', - 'btn.detail': 'Details', - 'btn.pause': 'Pause', - 'btn.resume': 'Fortsetzen', - 'btn.clear': 'Löschen', - 'btn.save': 'Speichern', - 'btn.delete': 'Löschen', - 'btn.close': 'Schließen', - 'btn.confirm': 'Bestätigen', - 'btn.cancel': 'Abbrechen', - 'btn.test': 'Testen', - 'btn.apply': 'Anwenden', - 'btn.filter': 'Filtern', - 'btn.clear_all': 'Alle löschen', - 'btn.realtime_on': 'Echtzeit: AN', - 'btn.realtime_off': 'Echtzeit: AUS', - 'btn.precise_locate': '± 60s', - 'btn.precise_cancel': '± 60s - Klick zum Abbrechen', - 'btn.reset_stats': 'Statistik zurücksetzen', - 'btn.flush_all': 'Alle leeren', - 'btn.new_window': 'Neues Fenster', - 'btn.auto_scroll': 'Auto-Scroll', - 'btn.live_logs': 'Echtzeit-Protokolle', - 'btn.history_query': 'Verlaufsanfrage', - 'btn.mark_all_read': 'Alle als gelesen markieren', - 'btn.clear_read_status': 'Lesestatus löschen', + 'monitor.btn.query': 'Abfrage', + 'monitor.btn.reset': 'Zurücksetzen', + 'monitor.btn.refresh': 'Aktualisieren', + 'monitor.btn.export': 'Exportieren', + 'monitor.btn.export_csv': 'CSV Export', + 'monitor.btn.export_json': 'JSON Export', + 'monitor.btn.detail': 'Details', + 'monitor.btn.pause': 'Pause', + 'monitor.btn.resume': 'Fortsetzen', + 'monitor.btn.clear': 'Löschen', + 'monitor.btn.save': 'Speichern', + 'monitor.btn.delete': 'Löschen', + 'monitor.btn.close': 'Schließen', + 'monitor.btn.confirm': 'Bestätigen', + 'monitor.btn.cancel': 'Abbrechen', + 'monitor.btn.test': 'Testen', + 'monitor.btn.apply': 'Anwenden', + 'monitor.btn.filter': 'Filtern', + 'monitor.btn.clear_all': 'Alle löschen', + 'monitor.btn.realtime_on': 'Echtzeit: AN', + 'monitor.btn.realtime_off': 'Echtzeit: AUS', + 'monitor.btn.precise_locate': '± 60s', + 'monitor.btn.precise_cancel': '± 60s - Klick zum Abbrechen', + 'monitor.btn.reset_stats': 'Statistik zurücksetzen', + 'monitor.btn.flush_all': 'Alle leeren', + 'monitor.btn.new_window': 'Neues Fenster', + 'monitor.btn.auto_scroll': 'Auto-Scroll', + 'monitor.btn.live_logs': 'Echtzeit-Protokolle', + 'monitor.btn.history_query': 'Verlaufsanfrage', + 'monitor.btn.mark_all_read': 'Alle als gelesen markieren', + 'monitor.btn.clear_read_status': 'Lesestatus löschen', // ============ Tabellenspalten ============ - 'col.index': '#', - 'col.time': 'Zeit', - 'col.level': 'Stufe', - 'col.module': 'Modul', - 'col.message': 'Nachricht', - 'col.method': 'Methode', - 'col.path': 'Pfad', - 'col.url': 'URL', - 'col.status': 'Status', - 'col.duration': 'Dauer', - 'col.client_ip': 'Client-IP', - 'col.source': 'Quelle', - 'col.function': 'Funktion', - 'col.line': 'Zeile', - 'col.operation': 'Aktion', - 'col.count': 'Anzahl', - 'col.avg_time': 'Durchschn. Zeit', - 'col.max_time': 'Max. Zeit', - 'col.db_name': 'DB-Name', - 'col.last_check': 'Letzte Prüfung', - 'col.current_connections': 'Aktuell', - 'col.max_connections': 'Max', - 'col.min_connections': 'Min', - 'col.idle_connections': 'Inaktiv', - 'col.used_connections': 'Verwendet', - 'col.usage': 'Nutzung', - 'col.processed_records': 'Verarbeitet', - 'col.timestamp': 'Zeitstempel', - 'col.query_params': 'Abfrageparameter', - 'col.error_message': 'Fehlermeldung', - 'col.url': 'URL', - 'col.is_read': 'Gelesen', - 'col.description': 'Beschreibung', - 'col.total_received': 'Gesamt empfangen', - 'col.pending': 'Ausstehend', - 'col.processed': 'Verarbeitet', - 'col.interrupted': 'Unterbrochen', - 'col.completion_rate': 'Abschlussrate', - 'col.avg_latency': 'Durchschn. Latenz', - 'col.last_action': 'Letzte Aktion', - 'col.id': 'ID', - 'col.event_type': 'Ereignistyp', - 'col.table': 'Tabelle', + 'monitor.col.index': '#', + 'monitor.col.time': 'Zeit', + 'monitor.col.level': 'Stufe', + 'monitor.col.module': 'Modul', + 'monitor.col.message': 'Nachricht', + 'monitor.col.method': 'Methode', + 'monitor.col.path': 'Pfad', + 'monitor.col.url': 'URL', + 'monitor.col.status': 'Status', + 'monitor.col.duration': 'Dauer', + 'monitor.col.client_ip': 'Client-IP', + 'monitor.col.source': 'Quelle', + 'monitor.col.function': 'Funktion', + 'monitor.col.line': 'Zeile', + 'monitor.col.operation': 'Aktion', + 'monitor.col.count': 'Anzahl', + 'monitor.col.avg_time': 'Durchschn. Zeit', + 'monitor.col.max_time': 'Max. Zeit', + 'monitor.col.db_name': 'DB-Name', + 'monitor.col.last_check': 'Letzte Prüfung', + 'monitor.col.current_connections': 'Aktuell', + 'monitor.col.max_connections': 'Max', + 'monitor.col.min_connections': 'Min', + 'monitor.col.idle_connections': 'Inaktiv', + 'monitor.col.used_connections': 'Verwendet', + 'monitor.col.usage': 'Nutzung', + 'monitor.col.processed_records': 'Verarbeitet', + 'monitor.col.timestamp': 'Zeitstempel', + 'monitor.col.query_params': 'Abfrageparameter', + 'monitor.col.error_message': 'Fehlermeldung', + 'monitor.col.url': 'URL', + 'monitor.col.is_read': 'Gelesen', + 'monitor.col.description': 'Beschreibung', + 'monitor.col.total_received': 'Gesamt empfangen', + 'monitor.col.pending': 'Ausstehend', + 'monitor.col.processed': 'Verarbeitet', + 'monitor.col.interrupted': 'Unterbrochen', + 'monitor.col.completion_rate': 'Abschlussrate', + 'monitor.col.avg_latency': 'Durchschn. Latenz', + 'monitor.col.last_action': 'Letzte Aktion', + 'monitor.col.id': 'ID', + 'monitor.col.event_type': 'Ereignistyp', + 'monitor.col.table': 'Tabelle', // ============ Schnellzeit ============ - 'time.start_time': 'Startzeit', - 'time.end_time': 'Endzeit', - 'time.last_10m': 'Letzte 10 Min', - 'time.last_30m': 'Letzte 30 Min', - 'time.last_1h': 'Letzte Stunde', - 'time.last_6h': 'Letzte 6 Stunden', - 'time.last_24h': 'Letzte 24 Stunden', - 'time.range': 'Zeitbereich', + 'monitor.time.start_time': 'Startzeit', + 'monitor.time.end_time': 'Endzeit', + 'monitor.time.last_10m': 'Letzte 10 Min', + 'monitor.time.last_30m': 'Letzte 30 Min', + 'monitor.time.last_1h': 'Letzte Stunde', + 'monitor.time.last_6h': 'Letzte 6 Stunden', + 'monitor.time.last_24h': 'Letzte 24 Stunden', + 'monitor.time.range': 'Zeitbereich', // ============ Filter ============ - 'filter.level': 'Alle Stufen', - 'filter.type': 'Alle Typen', - 'filter.module': 'Modul', - 'filter.keyword': 'Schlüsselwort', - 'filter.method': 'Methode', - 'filter.client_ip': 'Client-IP', - 'filter.status_range': 'Statusbereich', - 'filter.duration_range': 'Dauerbereich', - 'filter.advanced': 'Erweiterte Filter', - 'filter.collapse': 'Einklappen', - 'filter.expand': 'Ausklappen', - 'filter.clear': 'Löschen', - 'filter.active': 'Aktive Filter', - 'filter.module_placeholder': 'Modulname eingeben', - 'filter.keyword_placeholder': 'Schlüsselwort eingeben', - 'filter.ip_placeholder': 'Client-IP eingeben', - 'filter.status_placeholder': 'z.B.: 400-499', - 'filter.duration_placeholder': 'z.B.: >1000', - 'filter.all_logs': 'Alle Protokolle', + 'monitor.filter.level': 'Alle Stufen', + 'monitor.filter.type': 'Alle Typen', + 'monitor.filter.module': 'Modul', + 'monitor.filter.keyword': 'Schlüsselwort', + 'monitor.filter.method': 'Methode', + 'monitor.filter.client_ip': 'Client-IP', + 'monitor.filter.status_range': 'Statusbereich', + 'monitor.filter.duration_range': 'Dauerbereich', + 'monitor.filter.advanced': 'Erweiterte Filter', + 'monitor.filter.collapse': 'Einklappen', + 'monitor.filter.expand': 'Ausklappen', + 'monitor.filter.clear': 'Löschen', + 'monitor.filter.active': 'Aktive Filter', + 'monitor.filter.module_placeholder': 'Modulname eingeben', + 'monitor.filter.keyword_placeholder': 'Schlüsselwort eingeben', + 'monitor.filter.ip_placeholder': 'Client-IP eingeben', + 'monitor.filter.status_placeholder': 'z.B.: 400-499', + 'monitor.filter.duration_placeholder': 'z.B.: >1000', + 'monitor.filter.all_logs': 'Alle Protokolle', // ============ Diagramme ============ - 'chart.request_trend': '📊 Anfragentrend', - 'chart.level_distribution': '📊 Protokollstufen-Verteilung', - 'chart.status_distribution': '📈 Statuscode-Verteilung', - 'chart.slow_requests': '⏱️ Langsame Anfragen TOP10', - 'chart.total_requests': 'Anfragen Gesamt', - 'chart.error_count': 'Fehler', - 'chart.slow_count': 'Langsame Anfragen', - 'chart.log_count': 'Protokolle Gesamt', - 'chart.no_slow': '✅ Keine langsamen Anfragen', - 'chart.query_required': 'Bitte zuerst Abfrage ausführen', - 'chart.load_failed': '❌ Diagramm-Daten laden fehlgeschlagen, bitte erneut versuchen', - 'chart.redis_connections': 'Redis Verbindungspool-Nutzung', - 'chart.redis_buffer': 'Redis Puffergrößen-Änderungen', - 'chart.cpu': 'CPU', - 'chart.memory': 'Speicher', - 'chart.upload': 'Upload', - 'chart.download': 'Download', - 'chart.cpu_memory_axis': 'CPU / Speicher (%)', - 'chart.network_axis': 'Netzwerk-Upload / Download (KB/s)', - 'chart.used_connections': 'Verwendete Verbindungen', - 'chart.buffer_size_mb': 'Puffergröße (MB)', + 'monitor.chart.request_trend': '📊 Anfragentrend', + 'monitor.chart.level_distribution': '📊 Protokollstufen-Verteilung', + 'monitor.chart.status_distribution': '📈 Statuscode-Verteilung', + 'monitor.chart.slow_requests': '⏱️ Langsame Anfragen TOP10', + 'monitor.chart.total_requests': 'Anfragen Gesamt', + 'monitor.chart.error_count': 'Fehler', + 'monitor.chart.slow_count': 'Langsame Anfragen', + 'monitor.chart.log_count': 'Protokolle Gesamt', + 'monitor.chart.no_slow': '✅ Keine langsamen Anfragen', + 'monitor.chart.query_required': 'Bitte zuerst Abfrage ausführen', + 'monitor.chart.load_failed': '❌ Diagramm-Daten laden fehlgeschlagen, bitte erneut versuchen', + 'monitor.chart.no_data': 'Keine Daten', + 'monitor.chart.no_trend': 'Keine Trenddaten', + 'monitor.chart.redis_connections': 'Redis Verbindungspool-Nutzung', + 'monitor.chart.redis_buffer': 'Redis Puffergrößen-Änderungen', + 'monitor.chart.cpu': 'CPU', + 'monitor.chart.memory': 'Speicher', + 'monitor.chart.upload': 'Upload', + 'monitor.chart.download': 'Download', + 'monitor.chart.cpu_memory_axis': 'CPU / Speicher (%)', + 'monitor.chart.network_axis': 'Netzwerk-Upload / Download (KB/s)', + 'monitor.chart.used_connections': 'Verwendete Verbindungen', + 'monitor.chart.buffer_size_mb': 'Puffergröße (MB)', // ============ Fehler ============ - 'error.time_range_invalid': 'Startzeit kann nicht größer als Endzeit sein', - 'error.time_range_required': 'Bitte Startzeit und Endzeit auswählen', - 'error.query_failed': 'Abfrage fehlgeschlagen, bitte erneut versuchen', - 'error.export_failed': 'Export fehlgeschlagen, bitte erneut versuchen', - 'error.connection_failed': 'Verbindung fehlgeschlagen, bitte Seite aktualisieren', - 'error.max_templates': 'Maximal 10 Vorlagen erlaubt, bitte zuerst einige löschen', - 'error.auto_pause': 'Echtzeit-Verfolgung automatisch pausiert (über 10 Minuten)', - 'error.load_failed': 'Laden fehlgeschlagen, bitte erneut versuchen', - 'error.invalid_params': 'Ungültige Parameter', - 'error.clear_dl_failed': 'DeadLetter-Warteschlange löschen fehlgeschlagen', + 'monitor.error.time_range_invalid': 'Startzeit kann nicht größer als Endzeit sein', + 'monitor.error.time_range_required': 'Bitte Startzeit und Endzeit auswählen', + 'monitor.error.query_failed': 'Abfrage fehlgeschlagen, bitte erneut versuchen', + 'monitor.error.export_failed': 'Export fehlgeschlagen, bitte erneut versuchen', + 'monitor.error.connection_failed': 'Verbindung fehlgeschlagen, bitte Seite aktualisieren', + 'monitor.error.max_templates': 'Maximal 10 Vorlagen erlaubt, bitte zuerst einige löschen', + 'monitor.error.auto_pause': 'Echtzeit-Verfolgung automatisch pausiert (über 10 Minuten)', + 'monitor.error.load_failed': 'Laden fehlgeschlagen, bitte erneut versuchen', + 'monitor.error.invalid_params': 'Ungültige Parameter', + 'monitor.error.clear_dl_failed': 'DeadLetter-Warteschlange löschen fehlgeschlagen', // ============ Erfolg ============ - 'success.query_complete': 'Abfrage abgeschlossen', - 'success.export_complete': 'Export abgeschlossen', - 'success.template_saved': 'Vorlage "{name}" gespeichert', - 'success.logs_cleared': 'Protokolle gelöscht', - 'success.operation_success': 'Operation erfolgreich', - 'success.dl_cleared': 'DeadLetter-Warteschlange gelöscht', + 'monitor.success.query_complete': 'Abfrage abgeschlossen', + 'monitor.success.export_complete': 'Export abgeschlossen', + 'monitor.success.template_saved': 'Vorlage "{name}" gespeichert', + 'monitor.success.logs_cleared': 'Protokolle gelöscht', + 'monitor.success.operation_success': 'Operation erfolgreich', + 'monitor.success.dl_cleared': 'DeadLetter-Warteschlange gelöscht', // ============ Zeitachse ============ - 'timeline.title': 'Zeitachse', - 'timeline.no_data': 'Keine Daten, bitte zuerst Abfrage ausführen', - 'timeline.anomaly_detected': '⚠️ {count} Anomalien erkannt', - 'timeline.error_burst': '{count} aufeinanderfolgende FEHLER-Protokolle', - 'timeline.slow_anomaly': 'Langsame Anfrage Anomalie ({duration}ms > durchschn. {avg}ms×3)', - 'timeline.duplicate_error': 'Duplizierter Fehler "{msg}" {count} mal aufgetreten', - 'timeline.http_request': 'HTTP-Anfrage', - 'timeline.outbound_request': 'Ausgehende Anfrage', - 'timeline.system_log': 'Systemprotokoll', + 'monitor.timeline.title': 'Zeitachse', + 'monitor.timeline.no_data': 'Keine Daten, bitte zuerst Abfrage ausführen', + 'monitor.timeline.anomaly_detected': '⚠️ {count} Anomalien erkannt', + 'monitor.timeline.error_burst': '{count} aufeinanderfolgende FEHLER-Protokolle', + 'monitor.timeline.slow_anomaly': 'Langsame Anfrage Anomalie ({duration}ms > durchschn. {avg}ms×3)', + 'monitor.timeline.duplicate_error': 'Duplizierter Fehler "{msg}" {count} mal aufgetreten', + 'monitor.timeline.http_request': 'HTTP-Anfrage', + 'monitor.timeline.outbound_request': 'Ausgehende Anfrage', + 'monitor.timeline.system_log': 'Systemprotokoll', + 'monitor.timeline.summary_title': '📊 Timeline-Statistiken', + 'monitor.timeline.total_events': 'Gesamtereignisse', + 'monitor.timeline.http_requests': 'HTTP-Anfragen', + 'monitor.timeline.outbound_requests': 'Ausgehende Anfragen', + 'monitor.timeline.system_logs': 'Systemprotokolle', + 'monitor.timeline.errors': 'Fehler', + 'monitor.timeline.warnings': 'Warnungen', + 'monitor.timeline.slow_requests': 'Langsame Anfragen', // ============ Paginierung ============ - 'pagination.page': 'Seite', - 'pagination.of': 'von', - 'pagination.items': 'Einträge', - 'pagination.showing': 'Anzeigen', - 'pagination.per_page': 'Pro Seite', - 'pagination.first': 'Erste', - 'pagination.last': 'Letzte', - 'pagination.prev': 'Vorherige', - 'pagination.next': 'Nächste', - 'pagination.go_to': 'Gehe zu', + 'monitor.pagination.page': 'Seite', + 'monitor.pagination.of': 'von', + 'monitor.pagination.items': 'Einträge', + 'monitor.pagination.showing': 'Anzeigen', + 'monitor.pagination.per_page': 'Pro Seite', + 'monitor.pagination.first': 'Erste', + 'monitor.pagination.last': 'Letzte', + 'monitor.pagination.prev': 'Vorherige', + 'monitor.pagination.next': 'Nächste', + 'monitor.pagination.go_to': 'Gehe zu', // ============ Export ============ - 'export.current_page': 'Aktuelle Seite exportieren', - 'export.all_data': 'Alle Daten exportieren', - 'export.format_csv': 'CSV-Format', - 'export.format_json': 'JSON-Format', - 'export.select_format': 'Format auswählen', + 'monitor.export.current_page': 'Aktuelle Seite exportieren', + 'monitor.export.all_data': 'Alle Daten exportieren', + 'monitor.export.format_csv': 'CSV-Format', + 'monitor.export.format_json': 'JSON-Format', + 'monitor.export.select_format': 'Format auswählen', // ============ Vorlagen ============ - 'template.saved_queries': 'Gespeicherte Abfragen...', - 'template.save': 'Abfrage speichern', - 'template.manage': 'Vorlagen verwalten', - 'template.name': 'Vorlagenname', - 'template.description': 'Beschreibung', - 'template.delete_confirm': 'Diese Vorlage löschen?', - 'template.empty': 'Keine gespeicherten Vorlagen', + 'monitor.template.saved_queries': 'Gespeicherte Abfragen...', + 'monitor.template.save': 'Abfrage speichern', + 'monitor.template.manage': 'Vorlagen verwalten', + 'monitor.template.name': 'Vorlagenname', + 'monitor.template.description': 'Beschreibung', + 'monitor.template.delete_confirm': 'Diese Vorlage löschen?', + 'monitor.template.empty': 'Keine gespeicherten Vorlagen', // ============ Statistiken ============ - 'stats.time_range': 'Abfragezeitbereich', - 'stats.http_requests': 'HTTP-Anfragen', - 'stats.outbound_requests': 'Ausgehende Anfragen', - 'stats.system_logs': 'Systemprotokolle', - 'stats.level_distribution': 'Stufenverteilung', - 'stats.all_time': 'Gesamte Zeit', + 'monitor.stats.time_range': 'Abfragezeitbereich', + 'monitor.stats.http_requests': 'HTTP-Anfragen', + 'monitor.stats.outbound_requests': 'Ausgehende Anfragen', + 'monitor.stats.system_logs': 'Systemprotokolle', + 'monitor.stats.level_distribution': 'Stufenverteilung', + 'monitor.stats.all_time': 'Gesamte Zeit', // ============ Sonstiges ============ - 'other.last_update': 'Letzte Aktualisierung', - 'other.auto_reconnect': 'Neuverbindung in 5s', - 'other.waiting_logs': 'Warte auf Protokolldaten...', - 'other.no_matching_logs': 'Keine passenden Protokolle', - 'other.precise_mode': 'Präziser Modus', - 'other.saved_queries': 'Gespeicherte Abfragen...', - 'other.all_time': 'Gesamte Zeit', - 'other.linked_query': 'Verknüpfte Abfrage', - 'other.seconds': 'Sekunden', - 'other.minutes': 'Minuten', - 'other.hours': 'Stunden', - 'other.days': 'Tage', - 'other.ms': 'ms', - 'other.times': 'mal', - 'other.view_detail': 'Details anzeigen', - 'other.copy': 'Kopieren', - 'other.expand': 'Ausklappen', - 'other.collapse': 'Einklappen', - 'other.show_internal': 'Intern anzeigen', - 'other.show_read': 'Gelesen anzeigen', + 'monitor.other.last_update': 'Letzte Aktualisierung', + 'monitor.other.auto_reconnect': 'Neuverbindung in 5s', + 'monitor.other.waiting_logs': 'Warte auf Protokolldaten...', + 'monitor.other.no_matching_logs': 'Keine passenden Protokolle', + 'monitor.other.precise_mode': 'Präziser Modus', + 'monitor.other.saved_queries': 'Gespeicherte Abfragen...', + 'monitor.other.all_time': 'Gesamte Zeit', + 'monitor.other.linked_query': 'Verknüpfte Abfrage', + 'monitor.other.seconds': 'Sekunden', + 'monitor.other.minutes': 'Minuten', + 'monitor.other.hours': 'Stunden', + 'monitor.other.days': 'Tage', + 'monitor.other.ms': 'ms', + 'monitor.other.times': 'mal', + 'monitor.other.view_detail': 'Details anzeigen', + 'monitor.other.copy': 'Kopieren', + 'monitor.other.expand': 'Ausklappen', + 'monitor.other.collapse': 'Einklappen', + 'monitor.other.show_internal': 'Intern anzeigen', + 'monitor.other.show_read': 'Gelesen anzeigen', // ============ Datum ============ - 'date.today': 'Heute', - 'date.yesterday': 'Gestern', + 'monitor.date.today': 'Heute', + 'monitor.date.yesterday': 'Gestern', // ============ Sprache ============ - 'lang.select': 'Sprache auswählen', - 'lang.zh': '中文', - 'lang.en': 'English', - 'lang.de': 'Deutsch', + 'monitor.lang.select': 'Sprache auswählen', + 'monitor.lang.zh': '中文', + 'monitor.lang.en': 'English', + 'monitor.lang.de': 'Deutsch', // ============ HTTP-Methoden ============ - 'method.get': 'GET', - 'method.post': 'POST', - 'method.put': 'PUT', - 'method.delete': 'DELETE', - 'method.patch': 'PATCH', + 'monitor.method.get': 'GET', + 'monitor.method.post': 'POST', + 'monitor.method.put': 'PUT', + 'monitor.method.delete': 'DELETE', + 'monitor.method.patch': 'PATCH', // ============ Protokollstufen ============ - 'level.debug': 'DEBUG', - 'level.info': 'INFO', - 'level.warning': 'WARNING', - 'level.error': 'ERROR', - 'level.critical': 'CRITICAL', + 'monitor.level.debug': 'DEBUG', + 'monitor.level.info': 'INFO', + 'monitor.level.warning': 'WARNING', + 'monitor.level.error': 'ERROR', + 'monitor.level.critical': 'CRITICAL', // ============ Planer ============ - 'scheduler.rule': 'Planungsregel', - 'scheduler.last_run': 'Letzte Ausführung', - 'scheduler.max_time': 'Max. Zeit', - 'scheduler.never_run': 'Nie ausgeführt', - 'scheduler.default': 'Standard', - 'scheduler.running': 'Läuft', - 'scheduler.not_scheduled': 'Nicht geplant', + 'monitor.scheduler.rule': 'Planungsregel', + 'monitor.scheduler.last_run': 'Letzte Ausführung', + 'monitor.scheduler.max_time': 'Max. Zeit', + 'monitor.scheduler.never_run': 'Nie ausgeführt', + 'monitor.scheduler.default': 'Standard', + 'monitor.scheduler.running': 'Läuft', + 'monitor.scheduler.not_scheduled': 'Nicht geplant', // ============ Relative Zeit ============ - 'time.just_now': 'Gerade eben', - 'time.minutes_ago': 'vor {n} Min.', - 'time.hours_ago': 'vor {n} Stunden', - 'time.days_ago': 'vor {n} Tagen', - 'time.day_before_yesterday': 'Vorgestern', + 'monitor.time.just_now': 'Gerade eben', + 'monitor.time.minutes_ago': 'vor {n} Min.', + 'monitor.time.hours_ago': 'vor {n} Stunden', + 'monitor.time.days_ago': 'vor {n} Tagen', + 'monitor.time.day_before_yesterday': 'Vorgestern', // ============ Warnungstypen ============ - 'alert.warning': 'Warnung', - 'alert.error': 'Fehler', - 'alert.critical': 'Kritisch', - 'alert.normal': 'Normal', + 'monitor.alert.warning': 'Warnung', + 'monitor.alert.error': 'Fehler', + 'monitor.alert.critical': 'Kritisch', + 'monitor.alert.normal': 'Normal', // ============ Verbindungsstatus ============ - 'connection.failed': 'Verbindung fehlgeschlagen', - 'connection.reconnecting': 'Verbinde neu', - 'connection.connected': 'Verbunden', - 'connection.disconnected': 'Getrennt', + 'monitor.connection.failed': 'Verbindung fehlgeschlagen', + 'monitor.connection.reconnecting': 'Verbinde neu', + 'monitor.connection.connected': 'Verbunden', + 'monitor.connection.disconnected': 'Getrennt', // ============ Überwachungsstatus ============ - 'monitor.paused': '● Überwachung pausiert (inaktiv)', - 'monitor.panel': 'Überwachungstafel', - 'monitor.last_update': 'Letzte Aktualisierung', - 'monitor.reset_stats_confirm': 'Alle Ereignisstatistiken zurücksetzen?', + 'monitor.monitor.paused': '● Überwachung pausiert (inaktiv)', + 'monitor.monitor.panel': 'Überwachungstafel', + 'monitor.monitor.last_update': 'Letzte Aktualisierung', + 'monitor.monitor.reset_stats_confirm': 'Alle Ereignisstatistiken zurücksetzen?', // ============ Hervorhebung ============ - 'highlight.on': 'Hervorgehoben', - 'highlight.off': 'Hervorheben', + 'monitor.highlight.on': 'Hervorgehoben', + 'monitor.highlight.off': 'Hervorheben', // ============ Kopieren ============ - 'copy.success': 'Kopiert', - 'copy.failed': 'Kopieren fehlgeschlagen, bitte manuell kopieren', - 'copy.error': 'Kopieren fehlgeschlagen', + 'monitor.copy.success': 'Kopiert', + 'monitor.copy.failed': 'Kopieren fehlgeschlagen, bitte manuell kopieren', + 'monitor.copy.error': 'Kopieren fehlgeschlagen', // ============ Eingabeaufforderungen ============ - 'prompt.select_date': 'Bitte Datum auswählen', - 'prompt.fetch_failed': 'Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen', - 'prompt.fetch_outbound_failed': 'Ausgehende Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen', - 'prompt.reset_failed': 'Zurücksetzen fehlgeschlagen, bitte erneut versuchen', + 'monitor.prompt.select_date': 'Bitte Datum auswählen', + 'monitor.prompt.fetch_failed': 'Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen', + 'monitor.prompt.fetch_outbound_failed': 'Ausgehende Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen', + 'monitor.prompt.reset_failed': 'Zurücksetzen fehlgeschlagen, bitte erneut versuchen', // ============ Seitentitel ============ - 'page.http_requests_log': 'HTTP-Anfragedatensätze', - 'page.outbound_requests_log': 'Ausgehende Anfragedatensätze', + 'monitor.page.http_requests_log': 'HTTP-Anfragedatensätze', + 'monitor.page.outbound_requests_log': 'Ausgehende Anfragedatensätze', // ============ Zeit ============ - 'time.tomorrow': 'Morgen', - 'time.day_after_tomorrow': 'Übermorgen', - 'time.over_24h': 'Über 24 Stunden', - 'time.expired': 'Abgelaufen', - 'time.days_hours_later': 'In {days}T {hours}Std.', - 'time.unknown': 'Unbekannt', - 'time.month_day': '{day}.{month}.', + 'monitor.time.tomorrow': 'Morgen', + 'monitor.time.day_after_tomorrow': 'Übermorgen', + 'monitor.time.over_24h': 'Über 24 Stunden', + 'monitor.time.expired': 'Abgelaufen', + 'monitor.time.days_hours_later': 'In {days}T {hours}Std.', + 'monitor.time.unknown': 'Unbekannt', + 'monitor.time.month_day': '{day}.{month}.', // ============ Aufgabentypen ============ - 'task.system': 'System', - 'task.project': 'Projekt', - 'task.avg_time': 'Durchschn. Ausführungszeit', + 'monitor.task.system': 'System', + 'monitor.task.project': 'Projekt', + 'monitor.task.avg_time': 'Durchschn. Ausführungszeit', // ============ Detail-Modal ============ - 'modal.outbound_detail': 'Ausgehende Anfrage-Details', - 'modal.timestamp': 'Zeitstempel:', - 'modal.method': 'Methode:', - 'modal.status_code': 'Statuscode:', - 'modal.response_time': 'Antwortzeit:', - 'modal.module': 'Modul:', - 'modal.error_msg': 'Fehlermeldung:', + 'monitor.modal.outbound_detail': 'Ausgehende Anfrage-Details', + 'monitor.modal.timestamp': 'Zeitstempel:', + 'monitor.modal.method': 'Methode:', + 'monitor.modal.status_code': 'Statuscode:', + 'monitor.modal.response_time': 'Antwortzeit:', + 'monitor.modal.module': 'Modul:', + 'monitor.modal.error_msg': 'Fehlermeldung:', // ============ Anfrage/Antwort-Bereiche ============ - 'section.request_headers': 'Anfrage-Header', - 'section.request_body': 'Anfrage-Body', - 'section.response_headers': 'Antwort-Header', - 'section.response_body': 'Antwort-Body', - 'section.no_response': 'Keine Antwort-Body-Daten', - 'section.response_failed': 'Antwort-Body-Verarbeitung fehlgeschlagen: ', - 'section.truncated': '[Inhalt gekürzt, exportieren für vollständigen Inhalt]', - 'section.large_data_warning': '⚠️ Große Datenmenge ({count} Zeichen), kann Leistung beeinträchtigen', - 'section.showing_chars': 'Zeige erste {count} Zeichen', - 'section.basic_info': 'Grundinformationen', - 'section.no_data': 'Keine Daten', + 'monitor.section.request_headers': 'Anfrage-Header', + 'monitor.section.request_body': 'Anfrage-Body', + 'monitor.section.response_headers': 'Antwort-Header', + 'monitor.section.response_body': 'Antwort-Body', + 'monitor.section.no_response': 'Keine Antwort-Body-Daten', + 'monitor.section.response_failed': 'Antwort-Body-Verarbeitung fehlgeschlagen: ', + 'monitor.section.truncated': '[Inhalt gekürzt, exportieren für vollständigen Inhalt]', + 'monitor.section.large_data_warning': '⚠️ Große Datenmenge ({count} Zeichen), kann Leistung beeinträchtigen', + 'monitor.section.showing_chars': 'Zeige erste {count} Zeichen', + 'monitor.section.basic_info': 'Grundinformationen', + 'monitor.section.no_data': 'Keine Daten', // ============ Ratenbegrenzung ============ - 'status.rate_limited': 'Ratenbegrenzt', + 'monitor.status.rate_limited': 'Ratenbegrenzt', // ============ Protokollstufen-Auswahl ============ - 'log_level.all_with_debug': 'Alle Stufen (mit DEBUG)', - 'log_level.error': 'Fehlerprotokolle', - 'log_level.warning': 'Warnungsprotokolle', - 'log_level.info': 'Infoprotokolle', - 'log_level.debug': 'Debugprotokolle', + 'monitor.log_level.all_with_debug': 'Alle Stufen (mit DEBUG)', + 'monitor.log_level.error': 'Fehlerprotokolle', + 'monitor.log_level.warning': 'Warnungsprotokolle', + 'monitor.log_level.info': 'Infoprotokolle', + 'monitor.log_level.debug': 'Debugprotokolle', // ============ DeadLetter ============ - 'dl.reprocess': 'Neu verarbeiten', - 'dl.reprocess_success': 'DeadLetter erfolgreich neu verarbeitet', - 'dl.reprocess_failed': 'DeadLetter Neuverarbeitung fehlgeschlagen', + 'monitor.dl.reprocess': 'Neu verarbeiten', + 'monitor.dl.reprocess_success': 'DeadLetter erfolgreich neu verarbeitet', + 'monitor.dl.reprocess_failed': 'DeadLetter Neuverarbeitung fehlgeschlagen', // ============ Backend-Warnmeldungen-Zuordnung ============ - 'alert.scheduler_not_running': 'Planer läuft nicht', - 'alert.db_connection_failed': 'Datenbankverbindung fehlgeschlagen', - 'alert.redis_connection_failed': 'Redis-Verbindung fehlgeschlagen', - 'alert.event_listener_stopped': 'Ereignis-Listener gestoppt', - 'alert.binlog_listener_stopped': 'Binlog-Listener gestoppt', - 'alert.high_error_rate': 'Hohe Fehlerrate', - 'alert.memory_warning': 'Speichernutzung-Warnung', - 'alert.cpu_warning': 'CPU-Nutzung-Warnung', + 'monitor.alert.scheduler_not_running': 'Planer läuft nicht', + 'monitor.alert.db_connection_failed': 'Datenbankverbindung fehlgeschlagen', + 'monitor.alert.redis_connection_failed': 'Redis-Verbindung fehlgeschlagen', + 'monitor.alert.event_listener_stopped': 'Ereignis-Listener gestoppt', + 'monitor.alert.binlog_listener_stopped': 'Binlog-Listener gestoppt', + 'monitor.alert.high_error_rate': 'Hohe Fehlerrate', + 'monitor.alert.memory_warning': 'Speichernutzung-Warnung', + 'monitor.alert.cpu_warning': 'CPU-Nutzung-Warnung', // ================================================================================ // MDS-Modul (Daten-Bereitstellungssystem) @@ -659,5 +669,12 @@ window.__i18n_de_DE__ = { 'mds.other.tip': 'Hinweis', 'mds.other.warning': 'Warnung', 'mds.other.error': 'Fehler', - 'mds.other.success': 'Erfolg' + 'mds.other.success': 'Erfolg', + + // ============ 补充翻译键 ============ + 'monitor.other.yes': 'Ja', + 'monitor.other.no': 'Nein', + 'monitor.other.data_points': 'Datenpunkte', + 'monitor.col.is_slow': 'Ist langsame Anfrage', + 'monitor.col.is_error': 'Ist Fehler' }; diff --git a/static/lib/i18n/en-US.js b/static/lib/i18n/en-US.js index 6c7124c..4acd29d 100644 --- a/static/lib/i18n/en-US.js +++ b/static/lib/i18n/en-US.js @@ -3,497 +3,507 @@ */ window.__i18n_en_US__ = { // ============ Page Titles ============ - 'page.title': 'MyAPI System Monitor', - 'page.live_logs': 'Live Logs - System Monitor', - 'page.history_logs': 'Log History Query - System Monitor', + 'monitor.page.title': 'MyAPI System Monitor', + 'monitor.page.live_logs': 'Live Logs - System Monitor', + 'monitor.page.history_logs': 'Log History Query - System Monitor', // ============ Navigation ============ - 'nav.overview': '📊 Overview', - 'nav.database': '🗃️ Database', - 'nav.events': '☎️ Events', - 'nav.scheduler': '⏰ Scheduler', - 'nav.http_requests': '📥 HTTP Requests', - 'nav.outbound_requests': '📤 Outbound', - 'nav.logs': '📋 Logs', + 'monitor.nav.overview': '📊 Overview', + 'monitor.nav.database': '🗃️ Database', + 'monitor.nav.events': '☎️ Events', + 'monitor.nav.scheduler': '⏰ Scheduler', + 'monitor.nav.http_requests': '📥 HTTP Requests', + 'monitor.nav.outbound_requests': '📤 Outbound', + 'monitor.nav.logs': '📋 Logs', // ============ Tabs ============ - 'tab.overview': 'Overview', - 'tab.database': 'Database', - 'tab.events': 'Events', - 'tab.scheduler': 'Scheduler', - 'tab.http': 'HTTP Requests', - 'tab.outbound': 'Outbound', - 'tab.logs': 'System Logs', - 'tab.timeline': 'Timeline', - 'tab.chart': 'Charts', + 'monitor.tab.overview': 'Overview', + 'monitor.tab.database': 'Database', + 'monitor.tab.events': 'Events', + 'monitor.tab.scheduler': 'Scheduler', + 'monitor.tab.http': 'HTTP Requests', + 'monitor.tab.outbound': 'Outbound', + 'monitor.tab.logs': 'System Logs', + 'monitor.tab.timeline': 'Timeline', + 'monitor.tab.chart': 'Charts', // ============ Cards ============ - 'card.resource': 'Resource Usage', - 'card.db_status': 'Database Status', - 'card.db_connections': 'Database Connections', - 'card.event_helpers': 'Event Helpers', - 'card.scheduler': 'Job Scheduler', - 'card.api_requests': 'HTTP Requests', - 'card.outbound_requests': 'Outbound Requests', - 'card.redis': 'Redis Status', - 'card.event_listener': 'Event Listener', - 'card.recent_alerts': 'Recent Alerts', - 'card.mysql': 'MySQL', - 'card.http_requests_log': 'HTTP Request Records', - 'card.scheduler_detail': 'Scheduler Details', - 'card.outbound_requests_log': 'Outbound Request Records', - 'card.callback_tracker': 'Callback Tracker', - 'card.event_deduplicator': 'Event Deduplicator', + 'monitor.card.resource': 'Resource Usage', + 'monitor.card.db_status': 'Database Status', + 'monitor.card.db_connections': 'Database Connections', + 'monitor.card.event_helpers': 'Event Helpers', + 'monitor.card.scheduler': 'Job Scheduler', + 'monitor.card.api_requests': 'HTTP Requests', + 'monitor.card.outbound_requests': 'Outbound Requests', + 'monitor.card.redis': 'Redis Status', + 'monitor.card.event_listener': 'Event Listener', + 'monitor.card.recent_alerts': 'Recent Alerts', + 'monitor.card.mysql': 'MySQL', + 'monitor.card.http_requests_log': 'HTTP Request Records', + 'monitor.card.scheduler_detail': 'Scheduler Details', + 'monitor.card.outbound_requests_log': 'Outbound Request Records', + 'monitor.card.callback_tracker': 'Callback Tracker', + 'monitor.card.event_deduplicator': 'Event Deduplicator', // ============ Metrics ============ - 'metric.cpu': 'CPU Usage', - 'metric.memory': 'Memory Usage', - 'metric.threads': 'Threads', - 'metric.uptime': 'Uptime', - 'metric.total_connections': 'Total Connections', - 'metric.healthy': 'Healthy', - 'metric.unhealthy': 'Unhealthy', - 'metric.degraded': 'Degraded', - 'metric.total': 'Total', - 'metric.success': 'Success', - 'metric.failed': 'Failed', - 'metric.pending': 'Pending', - 'metric.active': 'Active', - 'metric.idle': 'Idle', - 'metric.unknown': 'Unknown', - 'metric.warning': 'Warning', - 'metric.events_received': 'Events Received', - 'metric.events_processed': 'Events Processed', - 'metric.events_failed': 'Events Failed', - 'metric.jobs_running': 'Running Jobs', - 'metric.jobs_pending': 'Pending Jobs', - 'metric.requests_total': 'Total Requests', - 'metric.requests_slow': 'Slow Requests', - 'metric.requests_error': 'Error Requests', - 'metric.error_rate': 'Error Rate', - 'metric.avg_time': 'Avg Response', - 'metric.connection_status': 'Connection Status', - 'metric.host': 'Host', - 'metric.port': 'Port', - 'metric.database': 'Database', - 'metric.used_connections': 'Used Connections', - 'metric.max_connections': 'Max Connections', - 'metric.connection_usage': 'Connection Usage', - 'metric.buffer_size': 'Buffer Size', - 'metric.buffer_threshold': 'Buffer Threshold', - 'metric.buffer_usage': 'Buffer Usage', - 'metric.events_interrupted': 'Interrupted', - 'metric.overall_success_rate': 'Overall Success Rate', - 'metric.active_event_types': 'Active Event Types', - 'metric.backpressure_status': 'Backpressure Status', - 'metric.backpressure_pending': 'Pending Events', - 'metric.backpressure_usage': 'Backpressure Usage', - 'metric.event_loop_status': 'Event Loop Status', - 'metric.pending_callbacks': 'Pending Callbacks', - 'metric.max_retries': 'Max Retries', - 'metric.pending_retries': 'Pending Retries', - 'metric.total_entries': 'Total Entries', - 'metric.active_items': 'Active Items', - 'metric.ttl_seconds': 'TTL (seconds)', - 'metric.max_entries': 'Max Entries', - 'metric.dl_total': 'DL Total', - 'metric.recent_dl': 'Recent DL', - 'metric.process_success_rate': 'Process Success Rate', - 'metric.scheduler_status': 'Scheduler Status', - 'metric.job_count': 'Job Count', - 'metric.pending_events': 'Pending Events', - 'metric.total_events': 'Total Events', - 'metric.file_size': 'File Size', - 'metric.running_status': 'Running Status', + 'monitor.metric.cpu': 'CPU Usage', + 'monitor.metric.memory': 'Memory Usage', + 'monitor.metric.threads': 'Threads', + 'monitor.metric.uptime': 'Uptime', + 'monitor.metric.total_connections': 'Total Connections', + 'monitor.metric.healthy': 'Healthy', + 'monitor.metric.unhealthy': 'Unhealthy', + 'monitor.metric.degraded': 'Degraded', + 'monitor.metric.total': 'Total', + 'monitor.metric.success': 'Success', + 'monitor.metric.failed': 'Failed', + 'monitor.metric.pending': 'Pending', + 'monitor.metric.active': 'Active', + 'monitor.metric.idle': 'Idle', + 'monitor.metric.unknown': 'Unknown', + 'monitor.metric.warning': 'Warning', + 'monitor.metric.events_received': 'Events Received', + 'monitor.metric.events_processed': 'Events Processed', + 'monitor.metric.events_failed': 'Events Failed', + 'monitor.metric.jobs_running': 'Running Jobs', + 'monitor.metric.jobs_pending': 'Pending Jobs', + 'monitor.metric.requests_total': 'Total Requests', + 'monitor.metric.requests_slow': 'Slow Requests', + 'monitor.metric.requests_error': 'Error Requests', + 'monitor.metric.error_rate': 'Error Rate', + 'monitor.metric.avg_time': 'Avg Response', + 'monitor.metric.connection_status': 'Connection Status', + 'monitor.metric.host': 'Host', + 'monitor.metric.port': 'Port', + 'monitor.metric.database': 'Database', + 'monitor.metric.used_connections': 'Used Connections', + 'monitor.metric.max_connections': 'Max Connections', + 'monitor.metric.connection_usage': 'Connection Usage', + 'monitor.metric.buffer_size': 'Buffer Size', + 'monitor.metric.buffer_threshold': 'Buffer Threshold', + 'monitor.metric.buffer_usage': 'Buffer Usage', + 'monitor.metric.events_interrupted': 'Interrupted', + 'monitor.metric.overall_success_rate': 'Overall Success Rate', + 'monitor.metric.active_event_types': 'Active Event Types', + 'monitor.metric.backpressure_status': 'Backpressure Status', + 'monitor.metric.backpressure_pending': 'Pending Events', + 'monitor.metric.backpressure_usage': 'Backpressure Usage', + 'monitor.metric.event_loop_status': 'Event Loop Status', + 'monitor.metric.pending_callbacks': 'Pending Callbacks', + 'monitor.metric.max_retries': 'Max Retries', + 'monitor.metric.pending_retries': 'Pending Retries', + 'monitor.metric.total_entries': 'Total Entries', + 'monitor.metric.active_items': 'Active Items', + 'monitor.metric.ttl_seconds': 'TTL (seconds)', + 'monitor.metric.max_entries': 'Max Entries', + 'monitor.metric.dl_total': 'DL Total', + 'monitor.metric.recent_dl': 'Recent DL', + 'monitor.metric.process_success_rate': 'Process Success Rate', + 'monitor.metric.scheduler_status': 'Scheduler Status', + 'monitor.metric.job_count': 'Job Count', + 'monitor.metric.pending_events': 'Pending Events', + 'monitor.metric.total_events': 'Total Events', + 'monitor.metric.file_size': 'File Size', + 'monitor.metric.running_status': 'Running Status', // ============ Status ============ - 'status.healthy': '● System Healthy', - 'status.unhealthy': '● System Unhealthy', - 'status.degraded': '● System Degraded', - 'status.running': 'Running', - 'status.checking': 'Checking', - 'status.stopped': 'Stopped', - 'status.loading': 'Loading...', - 'status.querying': 'Querying...', - 'status.exporting': 'Exporting...', - 'status.no_data': 'No data', - 'status.connected': 'Connected', - 'status.connecting': 'Connecting...', - 'status.disconnected': 'Disconnected', - 'status.reconnecting': 'Reconnecting...', - 'status.paused': 'Paused', - 'status.enabled': 'Enabled', - 'status.disabled': 'Disabled', - 'status.no_db_connections': 'No database connections', - 'status.no_scheduler': 'No scheduled tasks', - 'status.no_http_requests': 'No HTTP requests', - 'status.no_alerts': 'No alerts', - 'status.no_logs': 'No logs', - 'status.no_events': 'No event statistics', - 'status.no_api_requests': 'No API request records', - 'status.no_outbound_requests': 'No outbound request records', - 'status.no_dead_letters': 'No DL', - 'status.partial_warnings': '● Partial Warnings', - 'status.monitoring': 'Monitoring', + 'monitor.status.healthy': '● System Healthy', + 'monitor.status.unhealthy': '● System Unhealthy', + 'monitor.status.degraded': '● System Degraded', + 'monitor.status.running': 'Running', + 'monitor.status.checking': 'Checking', + 'monitor.status.stopped': 'Stopped', + 'monitor.status.loading': 'Loading...', + 'monitor.status.querying': 'Querying...', + 'monitor.status.exporting': 'Exporting...', + 'monitor.status.no_data': 'No data', + 'monitor.status.connected': 'Connected', + 'monitor.status.connecting': 'Connecting...', + 'monitor.status.disconnected': 'Disconnected', + 'monitor.status.reconnecting': 'Reconnecting...', + 'monitor.status.paused': 'Paused', + 'monitor.status.enabled': 'Enabled', + 'monitor.status.disabled': 'Disabled', + 'monitor.status.no_db_connections': 'No database connections', + 'monitor.status.no_scheduler': 'No scheduled tasks', + 'monitor.status.no_http_requests': 'No HTTP requests', + 'monitor.status.no_alerts': 'No alerts', + 'monitor.status.no_logs': 'No logs', + 'monitor.status.no_events': 'No event statistics', + 'monitor.status.no_api_requests': 'No API request records', + 'monitor.status.no_outbound_requests': 'No outbound request records', + 'monitor.status.no_dead_letters': 'No DL', + 'monitor.status.partial_warnings': '● Partial Warnings', + 'monitor.status.monitoring': 'Monitoring', // ============ Buttons ============ - 'btn.query': 'Query', - 'btn.reset': 'Reset', - 'btn.refresh': 'Refresh', - 'btn.export': 'Export', - 'btn.export_csv': 'Export CSV', - 'btn.export_json': 'Export JSON', - 'btn.detail': 'Detail', - 'btn.pause': 'Pause', - 'btn.resume': 'Resume', - 'btn.clear': 'Clear', - 'btn.save': 'Save', - 'btn.delete': 'Delete', - 'btn.close': 'Close', - 'btn.confirm': 'Confirm', - 'btn.cancel': 'Cancel', - 'btn.test': 'Test', - 'btn.apply': 'Apply', - 'btn.filter': 'Filter', - 'btn.clear_all': 'Clear All', - 'btn.realtime_on': 'Realtime: ON', - 'btn.realtime_off': 'Realtime: OFF', - 'btn.precise_locate': '± 60s', - 'btn.precise_cancel': '± 60s - Click to cancel', - 'btn.reset_stats': 'Reset Stats', - 'btn.flush_all': 'Flush All', - 'btn.new_window': 'New Window', - 'btn.auto_scroll': 'Auto Scroll', - 'btn.live_logs': 'Live Logs', - 'btn.history_query': 'History Query', - 'btn.mark_all_read': 'Mark All Read', - 'btn.clear_read_status': 'Clear Read Status', + 'monitor.btn.query': 'Query', + 'monitor.btn.reset': 'Reset', + 'monitor.btn.refresh': 'Refresh', + 'monitor.btn.export': 'Export', + 'monitor.btn.export_csv': 'Export CSV', + 'monitor.btn.export_json': 'Export JSON', + 'monitor.btn.detail': 'Detail', + 'monitor.btn.pause': 'Pause', + 'monitor.btn.resume': 'Resume', + 'monitor.btn.clear': 'Clear', + 'monitor.btn.save': 'Save', + 'monitor.btn.delete': 'Delete', + 'monitor.btn.close': 'Close', + 'monitor.btn.confirm': 'Confirm', + 'monitor.btn.cancel': 'Cancel', + 'monitor.btn.test': 'Test', + 'monitor.btn.apply': 'Apply', + 'monitor.btn.filter': 'Filter', + 'monitor.btn.clear_all': 'Clear All', + 'monitor.btn.realtime_on': 'Realtime: ON', + 'monitor.btn.realtime_off': 'Realtime: OFF', + 'monitor.btn.precise_locate': '± 60s', + 'monitor.btn.precise_cancel': '± 60s - Click to cancel', + 'monitor.btn.reset_stats': 'Reset Stats', + 'monitor.btn.flush_all': 'Flush All', + 'monitor.btn.new_window': 'New Window', + 'monitor.btn.auto_scroll': 'Auto Scroll', + 'monitor.btn.live_logs': 'Live Logs', + 'monitor.btn.history_query': 'History Query', + 'monitor.btn.mark_all_read': 'Mark All Read', + 'monitor.btn.clear_read_status': 'Clear Read Status', // ============ Table Columns ============ - 'col.index': '#', - 'col.time': 'Time', - 'col.level': 'Level', - 'col.module': 'Module', - 'col.message': 'Message', - 'col.method': 'Method', - 'col.path': 'Path', - 'col.url': 'URL', - 'col.status': 'Status', - 'col.duration': 'Duration', - 'col.client_ip': 'Client IP', - 'col.source': 'Source', - 'col.function': 'Function', - 'col.line': 'Line', - 'col.operation': 'Action', - 'col.count': 'Count', - 'col.avg_time': 'Avg Time', - 'col.max_time': 'Max Time', - 'col.db_name': 'DB Name', - 'col.last_check': 'Last Check', - 'col.current_connections': 'Current', - 'col.max_connections': 'Max', - 'col.min_connections': 'Min', - 'col.idle_connections': 'Idle', - 'col.used_connections': 'Used', - 'col.usage': 'Usage', - 'col.processed_records': 'Processed', - 'col.timestamp': 'Timestamp', - 'col.query_params': 'Query Params', - 'col.error_message': 'Error Message', - 'col.url': 'URL', - 'col.is_read': 'Read', - 'col.description': 'Description', - 'col.total_received': 'Total Received', - 'col.pending': 'Pending', - 'col.processed': 'Processed', - 'col.interrupted': 'Interrupted', - 'col.completion_rate': 'Completion Rate', - 'col.avg_latency': 'Avg Latency', - 'col.last_action': 'Last Action', - 'col.id': 'ID', - 'col.event_type': 'Event Type', - 'col.table': 'Table', + 'monitor.col.index': '#', + 'monitor.col.time': 'Time', + 'monitor.col.level': 'Level', + 'monitor.col.module': 'Module', + 'monitor.col.message': 'Message', + 'monitor.col.method': 'Method', + 'monitor.col.path': 'Path', + 'monitor.col.url': 'URL', + 'monitor.col.status': 'Status', + 'monitor.col.duration': 'Duration', + 'monitor.col.client_ip': 'Client IP', + 'monitor.col.source': 'Source', + 'monitor.col.function': 'Function', + 'monitor.col.line': 'Line', + 'monitor.col.operation': 'Action', + 'monitor.col.count': 'Count', + 'monitor.col.avg_time': 'Avg Time', + 'monitor.col.max_time': 'Max Time', + 'monitor.col.db_name': 'DB Name', + 'monitor.col.last_check': 'Last Check', + 'monitor.col.current_connections': 'Current', + 'monitor.col.max_connections': 'Max', + 'monitor.col.min_connections': 'Min', + 'monitor.col.idle_connections': 'Idle', + 'monitor.col.used_connections': 'Used', + 'monitor.col.usage': 'Usage', + 'monitor.col.processed_records': 'Processed', + 'monitor.col.timestamp': 'Timestamp', + 'monitor.col.query_params': 'Query Params', + 'monitor.col.error_message': 'Error Message', + 'monitor.col.url': 'URL', + 'monitor.col.is_read': 'Read', + 'monitor.col.description': 'Description', + 'monitor.col.total_received': 'Total Received', + 'monitor.col.pending': 'Pending', + 'monitor.col.processed': 'Processed', + 'monitor.col.interrupted': 'Interrupted', + 'monitor.col.completion_rate': 'Completion Rate', + 'monitor.col.avg_latency': 'Avg Latency', + 'monitor.col.last_action': 'Last Action', + 'monitor.col.id': 'ID', + 'monitor.col.event_type': 'Event Type', + 'monitor.col.table': 'Table', // ============ Quick Time ============ - 'time.start_time': 'Start Time', - 'time.end_time': 'End Time', - 'time.last_10m': 'Last 10 min', - 'time.last_30m': 'Last 30 min', - 'time.last_1h': 'Last 1 hour', - 'time.last_6h': 'Last 6 hours', - 'time.last_24h': 'Last 24 hours', - 'time.range': 'Time Range', + 'monitor.time.start_time': 'Start Time', + 'monitor.time.end_time': 'End Time', + 'monitor.time.last_10m': 'Last 10 min', + 'monitor.time.last_30m': 'Last 30 min', + 'monitor.time.last_1h': 'Last 1 hour', + 'monitor.time.last_6h': 'Last 6 hours', + 'monitor.time.last_24h': 'Last 24 hours', + 'monitor.time.range': 'Time Range', // ============ Filters ============ - 'filter.level': 'All Levels', - 'filter.type': 'All Types', - 'filter.module': 'Module', - 'filter.keyword': 'Keyword', - 'filter.method': 'Method', - 'filter.client_ip': 'Client IP', - 'filter.status_range': 'Status Range', - 'filter.duration_range': 'Duration Range', - 'filter.advanced': 'Advanced Filters', - 'filter.collapse': 'Collapse', - 'filter.expand': 'Expand', - 'filter.clear': 'Clear', - 'filter.active': 'Active Filters', - 'filter.module_placeholder': 'Enter module name', - 'filter.keyword_placeholder': 'Enter keyword', - 'filter.ip_placeholder': 'Enter client IP', - 'filter.status_placeholder': 'e.g.: 400-499', - 'filter.duration_placeholder': 'e.g.: >1000', - 'filter.all_logs': 'All Logs', + 'monitor.filter.level': 'All Levels', + 'monitor.filter.type': 'All Types', + 'monitor.filter.module': 'Module', + 'monitor.filter.keyword': 'Keyword', + 'monitor.filter.method': 'Method', + 'monitor.filter.client_ip': 'Client IP', + 'monitor.filter.status_range': 'Status Range', + 'monitor.filter.duration_range': 'Duration Range', + 'monitor.filter.advanced': 'Advanced Filters', + 'monitor.filter.collapse': 'Collapse', + 'monitor.filter.expand': 'Expand', + 'monitor.filter.clear': 'Clear', + 'monitor.filter.active': 'Active Filters', + 'monitor.filter.module_placeholder': 'Enter module name', + 'monitor.filter.keyword_placeholder': 'Enter keyword', + 'monitor.filter.ip_placeholder': 'Enter client IP', + 'monitor.filter.status_placeholder': 'e.g.: 400-499', + 'monitor.filter.duration_placeholder': 'e.g.: >1000', + 'monitor.filter.all_logs': 'All Logs', // ============ Charts ============ - 'chart.request_trend': '📊 Request Trend', - 'chart.level_distribution': '📊 Log Level Distribution', - 'chart.status_distribution': '📈 Status Code Distribution', - 'chart.slow_requests': '⏱️ Slow Requests TOP10', - 'chart.total_requests': 'Total Requests', - 'chart.error_count': 'Errors', - 'chart.slow_count': 'Slow Requests', - 'chart.log_count': 'Total Logs', - 'chart.no_slow': '✅ No slow requests', - 'chart.query_required': 'Please execute query first', - 'chart.load_failed': '❌ Chart data load failed, please retry', - 'chart.redis_connections': 'Redis Connection Pool Usage', - 'chart.redis_buffer': 'Redis Buffer Size Changes', - 'chart.cpu': 'CPU', - 'chart.memory': 'Memory', - 'chart.upload': 'Upload', - 'chart.download': 'Download', - 'chart.cpu_memory_axis': 'CPU / Memory (%)', - 'chart.network_axis': 'Network Upload / Download (KB/s)', - 'chart.used_connections': 'Used Connections', - 'chart.buffer_size_mb': 'Buffer Size (MB)', + 'monitor.chart.request_trend': '📊 Request Trend', + 'monitor.chart.level_distribution': '📊 Log Level Distribution', + 'monitor.chart.status_distribution': '📈 Status Code Distribution', + 'monitor.chart.slow_requests': '⏱️ Slow Requests TOP10', + 'monitor.chart.total_requests': 'Total Requests', + 'monitor.chart.error_count': 'Errors', + 'monitor.chart.slow_count': 'Slow Requests', + 'monitor.chart.log_count': 'Total Logs', + 'monitor.chart.no_slow': '✅ No slow requests', + 'monitor.chart.query_required': 'Please execute query first', + 'monitor.chart.load_failed': '❌ Chart data load failed, please retry', + 'monitor.chart.no_data': 'No data', + 'monitor.chart.no_trend': 'No trend data', + 'monitor.chart.redis_connections': 'Redis Connection Pool Usage', + 'monitor.chart.redis_buffer': 'Redis Buffer Size Changes', + 'monitor.chart.cpu': 'CPU', + 'monitor.chart.memory': 'Memory', + 'monitor.chart.upload': 'Upload', + 'monitor.chart.download': 'Download', + 'monitor.chart.cpu_memory_axis': 'CPU / Memory (%)', + 'monitor.chart.network_axis': 'Network Upload / Download (KB/s)', + 'monitor.chart.used_connections': 'Used Connections', + 'monitor.chart.buffer_size_mb': 'Buffer Size (MB)', // ============ Errors ============ - 'error.time_range_invalid': 'Start time cannot be greater than end time', - 'error.time_range_required': 'Please select start time and end time', - 'error.query_failed': 'Query failed, please try again', - 'error.export_failed': 'Export failed, please retry', - 'error.connection_failed': 'Connection failed, please refresh page', - 'error.max_templates': 'Maximum 10 templates allowed, please delete some first', - 'error.auto_pause': 'Realtime tracking auto-paused (over 10 minutes)', - 'error.load_failed': 'Load failed, please retry', - 'error.invalid_params': 'Invalid parameters', - 'error.clear_dl_failed': 'Failed to clear DeadLetter queue', + 'monitor.error.time_range_invalid': 'Start time cannot be greater than end time', + 'monitor.error.time_range_required': 'Please select start time and end time', + 'monitor.error.query_failed': 'Query failed, please try again', + 'monitor.error.export_failed': 'Export failed, please retry', + 'monitor.error.connection_failed': 'Connection failed, please refresh page', + 'monitor.error.max_templates': 'Maximum 10 templates allowed, please delete some first', + 'monitor.error.auto_pause': 'Realtime tracking auto-paused (over 10 minutes)', + 'monitor.error.load_failed': 'Load failed, please retry', + 'monitor.error.invalid_params': 'Invalid parameters', + 'monitor.error.clear_dl_failed': 'Failed to clear DeadLetter queue', // ============ Success ============ - 'success.query_complete': 'Query Complete', - 'success.export_complete': 'Export Complete', - 'success.template_saved': 'Template "{name}" saved', - 'success.logs_cleared': 'Logs cleared', - 'success.operation_success': 'Operation successful', - 'success.dl_cleared': 'DeadLetter queue cleared', + 'monitor.success.query_complete': 'Query Complete', + 'monitor.success.export_complete': 'Export Complete', + 'monitor.success.template_saved': 'Template "{name}" saved', + 'monitor.success.logs_cleared': 'Logs cleared', + 'monitor.success.operation_success': 'Operation successful', + 'monitor.success.dl_cleared': 'DeadLetter queue cleared', // ============ Timeline ============ - 'timeline.title': 'Timeline', - 'timeline.no_data': 'No data, please execute query first', - 'timeline.anomaly_detected': '⚠️ {count} anomalies detected', - 'timeline.error_burst': '{count} consecutive ERROR logs', - 'timeline.slow_anomaly': 'Slow request anomaly ({duration}ms > avg {avg}ms×3)', - 'timeline.duplicate_error': 'Duplicate error "{msg}" appeared {count} times', - 'timeline.http_request': 'HTTP Request', - 'timeline.outbound_request': 'Outbound Request', - 'timeline.system_log': 'System Log', + 'monitor.timeline.title': 'Timeline', + 'monitor.timeline.no_data': 'No data, please execute query first', + 'monitor.timeline.anomaly_detected': '⚠️ {count} anomalies detected', + 'monitor.timeline.error_burst': '{count} consecutive ERROR logs', + 'monitor.timeline.slow_anomaly': 'Slow request anomaly ({duration}ms > avg {avg}ms×3)', + 'monitor.timeline.duplicate_error': 'Duplicate error "{msg}" appeared {count} times', + 'monitor.timeline.http_request': 'HTTP Request', + 'monitor.timeline.outbound_request': 'Outbound Request', + 'monitor.timeline.system_log': 'System Log', + 'monitor.timeline.summary_title': '📊 Timeline Statistics', + 'monitor.timeline.total_events': 'Total Events', + 'monitor.timeline.http_requests': 'HTTP Requests', + 'monitor.timeline.outbound_requests': 'Outbound Requests', + 'monitor.timeline.system_logs': 'System Logs', + 'monitor.timeline.errors': 'Errors', + 'monitor.timeline.warnings': 'Warnings', + 'monitor.timeline.slow_requests': 'Slow Requests', // ============ Pagination ============ - 'pagination.page': 'Page', - 'pagination.of': 'of', - 'pagination.items': 'items', - 'pagination.showing': 'Showing', - 'pagination.per_page': 'Per Page', - 'pagination.first': 'First', - 'pagination.last': 'Last', - 'pagination.prev': 'Previous', - 'pagination.next': 'Next', - 'pagination.go_to': 'Go to', + 'monitor.pagination.page': 'Page', + 'monitor.pagination.of': 'of', + 'monitor.pagination.items': 'items', + 'monitor.pagination.showing': 'Showing', + 'monitor.pagination.per_page': 'Per Page', + 'monitor.pagination.first': 'First', + 'monitor.pagination.last': 'Last', + 'monitor.pagination.prev': 'Previous', + 'monitor.pagination.next': 'Next', + 'monitor.pagination.go_to': 'Go to', // ============ Export ============ - 'export.current_page': 'Export Current Page', - 'export.all_data': 'Export All Data', - 'export.format_csv': 'CSV Format', - 'export.format_json': 'JSON Format', - 'export.select_format': 'Select Format', + 'monitor.export.current_page': 'Export Current Page', + 'monitor.export.all_data': 'Export All Data', + 'monitor.export.format_csv': 'CSV Format', + 'monitor.export.format_json': 'JSON Format', + 'monitor.export.select_format': 'Select Format', // ============ Templates ============ - 'template.saved_queries': 'Saved Queries...', - 'template.save': 'Save Query', - 'template.manage': 'Manage Templates', - 'template.name': 'Template Name', - 'template.description': 'Description', - 'template.delete_confirm': 'Delete this template?', - 'template.empty': 'No saved templates', + 'monitor.template.saved_queries': 'Saved Queries...', + 'monitor.template.save': 'Save Query', + 'monitor.template.manage': 'Manage Templates', + 'monitor.template.name': 'Template Name', + 'monitor.template.description': 'Description', + 'monitor.template.delete_confirm': 'Delete this template?', + 'monitor.template.empty': 'No saved templates', // ============ Statistics ============ - 'stats.time_range': 'Query Time Range', - 'stats.http_requests': 'HTTP Requests', - 'stats.outbound_requests': 'Outbound Requests', - 'stats.system_logs': 'System Logs', - 'stats.level_distribution': 'Level Distribution', - 'stats.all_time': 'All Time', + 'monitor.stats.time_range': 'Query Time Range', + 'monitor.stats.http_requests': 'HTTP Requests', + 'monitor.stats.outbound_requests': 'Outbound Requests', + 'monitor.stats.system_logs': 'System Logs', + 'monitor.stats.level_distribution': 'Level Distribution', + 'monitor.stats.all_time': 'All Time', // ============ Others ============ - 'other.last_update': 'Last Update', - 'other.auto_reconnect': 'reconnect in 5s', - 'other.waiting_logs': 'Waiting for log data...', - 'other.no_matching_logs': 'No matching logs', - 'other.precise_mode': 'Precise Mode', - 'other.saved_queries': 'Saved Queries...', - 'other.all_time': 'All Time', - 'other.linked_query': 'Linked Query', - 'other.seconds': 'seconds', - 'other.minutes': 'minutes', - 'other.hours': 'hours', - 'other.days': 'days', - 'other.ms': 'ms', - 'other.times': 'times', - 'other.view_detail': 'View Detail', - 'other.copy': 'Copy', - 'other.expand': 'Expand', - 'other.collapse': 'Collapse', - 'other.show_internal': 'Show Internal', - 'other.show_read': 'Show Read', + 'monitor.other.last_update': 'Last Update', + 'monitor.other.auto_reconnect': 'reconnect in 5s', + 'monitor.other.waiting_logs': 'Waiting for log data...', + 'monitor.other.no_matching_logs': 'No matching logs', + 'monitor.other.precise_mode': 'Precise Mode', + 'monitor.other.saved_queries': 'Saved Queries...', + 'monitor.other.all_time': 'All Time', + 'monitor.other.linked_query': 'Linked Query', + 'monitor.other.seconds': 'seconds', + 'monitor.other.minutes': 'minutes', + 'monitor.other.hours': 'hours', + 'monitor.other.days': 'days', + 'monitor.other.ms': 'ms', + 'monitor.other.times': 'times', + 'monitor.other.view_detail': 'View Detail', + 'monitor.other.copy': 'Copy', + 'monitor.other.expand': 'Expand', + 'monitor.other.collapse': 'Collapse', + 'monitor.other.show_internal': 'Show Internal', + 'monitor.other.show_read': 'Show Read', // ============ Date ============ - 'date.today': 'Today', - 'date.yesterday': 'Yesterday', + 'monitor.date.today': 'Today', + 'monitor.date.yesterday': 'Yesterday', // ============ Language ============ - 'lang.select': 'Select Language', - 'lang.zh': '中文', - 'lang.en': 'English', - 'lang.de': 'Deutsch', + 'monitor.lang.select': 'Select Language', + 'monitor.lang.zh': '中文', + 'monitor.lang.en': 'English', + 'monitor.lang.de': 'Deutsch', // ============ HTTP Methods ============ - 'method.get': 'GET', - 'method.post': 'POST', - 'method.put': 'PUT', - 'method.delete': 'DELETE', - 'method.patch': 'PATCH', + 'monitor.method.get': 'GET', + 'monitor.method.post': 'POST', + 'monitor.method.put': 'PUT', + 'monitor.method.delete': 'DELETE', + 'monitor.method.patch': 'PATCH', // ============ Log Levels ============ - 'level.debug': 'DEBUG', - 'level.info': 'INFO', - 'level.warning': 'WARNING', - 'level.error': 'ERROR', - 'level.critical': 'CRITICAL', + 'monitor.level.debug': 'DEBUG', + 'monitor.level.info': 'INFO', + 'monitor.level.warning': 'WARNING', + 'monitor.level.error': 'ERROR', + 'monitor.level.critical': 'CRITICAL', // ============ Scheduler ============ - 'scheduler.rule': 'Schedule Rule', - 'scheduler.last_run': 'Last Run', - 'scheduler.max_time': 'Max Time', - 'scheduler.never_run': 'Never Run', - 'scheduler.default': 'Default', - 'scheduler.running': 'Running', - 'scheduler.not_scheduled': 'Not Scheduled', + 'monitor.scheduler.rule': 'Schedule Rule', + 'monitor.scheduler.last_run': 'Last Run', + 'monitor.scheduler.max_time': 'Max Time', + 'monitor.scheduler.never_run': 'Never Run', + 'monitor.scheduler.default': 'Default', + 'monitor.scheduler.running': 'Running', + 'monitor.scheduler.not_scheduled': 'Not Scheduled', // ============ Relative Time ============ - 'time.just_now': 'Just now', - 'time.minutes_ago': '{n} min ago', - 'time.hours_ago': '{n} hours ago', - 'time.days_ago': '{n} days ago', - 'time.day_before_yesterday': 'Day before yesterday', + 'monitor.time.just_now': 'Just now', + 'monitor.time.minutes_ago': '{n} min ago', + 'monitor.time.hours_ago': '{n} hours ago', + 'monitor.time.days_ago': '{n} days ago', + 'monitor.time.day_before_yesterday': 'Day before yesterday', // ============ Alert Types ============ - 'alert.warning': 'Warning', - 'alert.error': 'Error', - 'alert.critical': 'Critical', - 'alert.normal': 'Normal', + 'monitor.alert.warning': 'Warning', + 'monitor.alert.error': 'Error', + 'monitor.alert.critical': 'Critical', + 'monitor.alert.normal': 'Normal', // ============ Connection Status ============ - 'connection.failed': 'Connection Failed', - 'connection.reconnecting': 'Reconnecting', - 'connection.connected': 'Connected', - 'connection.disconnected': 'Disconnected', + 'monitor.connection.failed': 'Connection Failed', + 'monitor.connection.reconnecting': 'Reconnecting', + 'monitor.connection.connected': 'Connected', + 'monitor.connection.disconnected': 'Disconnected', // ============ Monitor Status ============ - 'monitor.paused': '● Monitor paused (inactive)', - 'monitor.panel': 'Monitor Panel', - 'monitor.last_update': 'Last Update', - 'monitor.reset_stats_confirm': 'Reset all event statistics?', + 'monitor.monitor.paused': '● Monitor paused (inactive)', + 'monitor.monitor.panel': 'Monitor Panel', + 'monitor.monitor.last_update': 'Last Update', + 'monitor.monitor.reset_stats_confirm': 'Reset all event statistics?', // ============ Highlight ============ - 'highlight.on': 'Highlighted', - 'highlight.off': 'Highlight', + 'monitor.highlight.on': 'Highlighted', + 'monitor.highlight.off': 'Highlight', // ============ Copy ============ - 'copy.success': 'Copied', - 'copy.failed': 'Copy failed, please copy manually', - 'copy.error': 'Copy failed', + 'monitor.copy.success': 'Copied', + 'monitor.copy.failed': 'Copy failed, please copy manually', + 'monitor.copy.error': 'Copy failed', // ============ Prompts ============ - 'prompt.select_date': 'Please select a date', - 'prompt.fetch_failed': 'Failed to fetch request records, please try again', - 'prompt.fetch_outbound_failed': 'Failed to fetch outbound request records, please try again', - 'prompt.reset_failed': 'Reset failed, please try again', + 'monitor.prompt.select_date': 'Please select a date', + 'monitor.prompt.fetch_failed': 'Failed to fetch request records, please try again', + 'monitor.prompt.fetch_outbound_failed': 'Failed to fetch outbound request records, please try again', + 'monitor.prompt.reset_failed': 'Reset failed, please try again', // ============ Page Titles ============ - 'page.http_requests_log': 'HTTP Request Records', - 'page.outbound_requests_log': 'Outbound Request Records', + 'monitor.page.http_requests_log': 'HTTP Request Records', + 'monitor.page.outbound_requests_log': 'Outbound Request Records', // ============ Time ============ - 'time.tomorrow': 'Tomorrow', - 'time.day_after_tomorrow': 'Day after tomorrow', - 'time.over_24h': 'Over 24 hours', - 'time.expired': 'Expired', - 'time.days_hours_later': '{days}d {hours}h later', - 'time.unknown': 'Unknown', - 'time.month_day': '{month}/{day}', + 'monitor.time.tomorrow': 'Tomorrow', + 'monitor.time.day_after_tomorrow': 'Day after tomorrow', + 'monitor.time.over_24h': 'Over 24 hours', + 'monitor.time.expired': 'Expired', + 'monitor.time.days_hours_later': '{days}d {hours}h later', + 'monitor.time.unknown': 'Unknown', + 'monitor.time.month_day': '{month}/{day}', // ============ Task Types ============ - 'task.system': 'System', - 'task.project': 'Project', - 'task.avg_time': 'Avg Execution Time', + 'monitor.task.system': 'System', + 'monitor.task.project': 'Project', + 'monitor.task.avg_time': 'Avg Execution Time', // ============ Detail Modal ============ - 'modal.outbound_detail': 'Outbound Request Detail', - 'modal.timestamp': 'Timestamp:', - 'modal.method': 'Method:', - 'modal.status_code': 'Status Code:', - 'modal.response_time': 'Response Time:', - 'modal.module': 'Module:', - 'modal.error_msg': 'Error Message:', + 'monitor.modal.outbound_detail': 'Outbound Request Detail', + 'monitor.modal.timestamp': 'Timestamp:', + 'monitor.modal.method': 'Method:', + 'monitor.modal.status_code': 'Status Code:', + 'monitor.modal.response_time': 'Response Time:', + 'monitor.modal.module': 'Module:', + 'monitor.modal.error_msg': 'Error Message:', // ============ Request/Response Sections ============ - 'section.request_headers': 'Request Headers', - 'section.request_body': 'Request Body', - 'section.response_headers': 'Response Headers', - 'section.response_body': 'Response Body', - 'section.no_response': 'No response body data', - 'section.response_failed': 'Response body processing failed: ', - 'section.truncated': '[Content truncated, export to view full content]', - 'section.large_data_warning': '⚠️ Large data ({count} chars), may affect performance', - 'section.showing_chars': 'Showing first {count} chars', - 'section.basic_info': 'Basic Information', - 'section.no_data': 'No data', + 'monitor.section.request_headers': 'Request Headers', + 'monitor.section.request_body': 'Request Body', + 'monitor.section.response_headers': 'Response Headers', + 'monitor.section.response_body': 'Response Body', + 'monitor.section.no_response': 'No response body data', + 'monitor.section.response_failed': 'Response body processing failed: ', + 'monitor.section.truncated': '[Content truncated, export to view full content]', + 'monitor.section.large_data_warning': '⚠️ Large data ({count} chars), may affect performance', + 'monitor.section.showing_chars': 'Showing first {count} chars', + 'monitor.section.basic_info': 'Basic Information', + 'monitor.section.no_data': 'No data', // ============ Rate Limiting ============ - 'status.rate_limited': 'Rate Limited', + 'monitor.status.rate_limited': 'Rate Limited', // ============ Log Level Selection ============ - 'log_level.all_with_debug': 'All Levels (with DEBUG)', - 'log_level.error': 'Error Logs', - 'log_level.warning': 'Warning Logs', - 'log_level.info': 'Info Logs', - 'log_level.debug': 'Debug Logs', + 'monitor.log_level.all_with_debug': 'All Levels (with DEBUG)', + 'monitor.log_level.error': 'Error Logs', + 'monitor.log_level.warning': 'Warning Logs', + 'monitor.log_level.info': 'Info Logs', + 'monitor.log_level.debug': 'Debug Logs', // ============ DeadLetter ============ - 'dl.reprocess': 'Reprocess', - 'dl.reprocess_success': 'DeadLetter reprocessed successfully', - 'dl.reprocess_failed': 'DeadLetter reprocess failed', + 'monitor.dl.reprocess': 'Reprocess', + 'monitor.dl.reprocess_success': 'DeadLetter reprocessed successfully', + 'monitor.dl.reprocess_failed': 'DeadLetter reprocess failed', // ============ Backend Alert Message Mapping ============ - 'alert.scheduler_not_running': 'Scheduler not running', - 'alert.db_connection_failed': 'Database connection failed', - 'alert.redis_connection_failed': 'Redis connection failed', - 'alert.event_listener_stopped': 'Event listener stopped', - 'alert.binlog_listener_stopped': 'Binlog listener stopped', - 'alert.high_error_rate': 'High error rate', - 'alert.memory_warning': 'Memory usage warning', - 'alert.cpu_warning': 'CPU usage warning', + 'monitor.alert.scheduler_not_running': 'Scheduler not running', + 'monitor.alert.db_connection_failed': 'Database connection failed', + 'monitor.alert.redis_connection_failed': 'Redis connection failed', + 'monitor.alert.event_listener_stopped': 'Event listener stopped', + 'monitor.alert.binlog_listener_stopped': 'Binlog listener stopped', + 'monitor.alert.high_error_rate': 'High error rate', + 'monitor.alert.memory_warning': 'Memory usage warning', + 'monitor.alert.cpu_warning': 'CPU usage warning', // ================================================================================ // MDS Module (Data Staging System) @@ -658,5 +668,12 @@ window.__i18n_en_US__ = { 'mds.other.tip': 'Tip', 'mds.other.warning': 'Warning', 'mds.other.error': 'Error', - 'mds.other.success': 'Success' + 'mds.other.success': 'Success', + + // ============ 补充翻译键 ============ + 'monitor.other.yes': 'Yes', + 'monitor.other.no': 'No', + 'monitor.other.data_points': 'data points', + 'monitor.col.is_slow': 'Is Slow Request', + 'monitor.col.is_error': 'Is Error' }; diff --git a/static/lib/i18n/zh-CN.js b/static/lib/i18n/zh-CN.js index 04d684e..5166d48 100644 --- a/static/lib/i18n/zh-CN.js +++ b/static/lib/i18n/zh-CN.js @@ -4,497 +4,507 @@ */ window.__i18n_zh_CN__ = { // ============ 页面标题 ============ - 'page.title': 'MyAPI 系统监控面板', - 'page.live_logs': '实时日志 - 系统监控', - 'page.history_logs': '日志历史查询 - 系统监控', + 'monitor.page.title': 'MyAPI 系统监控面板', + 'monitor.page.live_logs': '实时日志 - 系统监控', + 'monitor.page.history_logs': '日志历史查询 - 系统监控', // ============ 导航菜单 ============ - 'nav.overview': '📊 Overview', - 'nav.database': '🗃️ 数据库', - 'nav.events': '☎️ 事件处理', - 'nav.scheduler': '⏰ 定时任务', - 'nav.http_requests': '📥 接收请求', - 'nav.outbound_requests': '📤 发送请求', - 'nav.logs': '📋 日志', + 'monitor.nav.overview': '📊 Overview', + 'monitor.nav.database': '🗃️ 数据库', + 'monitor.nav.events': '☎️ 事件处理', + 'monitor.nav.scheduler': '⏰ 定时任务', + 'monitor.nav.http_requests': '📥 接收请求', + 'monitor.nav.outbound_requests': '📤 发送请求', + 'monitor.nav.logs': '📋 日志', // ============ 标签页 ============ - 'tab.overview': '概览', - 'tab.database': '数据库', - 'tab.events': '事件处理', - 'tab.scheduler': '定时任务', - 'tab.http': '接收请求', - 'tab.outbound': '发送请求', - 'tab.logs': '系统日志', - 'tab.timeline': '时间线', - 'tab.chart': '图表分析', + 'monitor.tab.overview': '概览', + 'monitor.tab.database': '数据库', + 'monitor.tab.events': '事件处理', + 'monitor.tab.scheduler': '定时任务', + 'monitor.tab.http': '接收请求', + 'monitor.tab.outbound': '发送请求', + 'monitor.tab.logs': '系统日志', + 'monitor.tab.timeline': '时间线', + 'monitor.tab.chart': '图表分析', // ============ 卡片标题 ============ - 'card.resource': '资源使用', - 'card.db_status': '账套状态', - 'card.db_connections': '数据库连接状态', - 'card.event_helpers': '事件辅助模块', - 'card.scheduler': '定时任务调度器', - 'card.api_requests': 'HTTP请求统计', - 'card.outbound_requests': '对外HTTP请求', - 'card.redis': 'Redis状态', - 'card.event_listener': '事件监听', - 'card.recent_alerts': '最近告警', - 'card.mysql': 'MySQL', - 'card.http_requests_log': '接收请求记录', - 'card.scheduler_detail': '定时任务详情', - 'card.outbound_requests_log': '发送请求记录', - 'card.callback_tracker': '回调跟踪器', - 'card.event_deduplicator': '事件去重器', + 'monitor.card.resource': '资源使用', + 'monitor.card.db_status': '账套状态', + 'monitor.card.db_connections': '数据库连接状态', + 'monitor.card.event_helpers': '事件辅助模块', + 'monitor.card.scheduler': '定时任务调度器', + 'monitor.card.api_requests': 'HTTP请求统计', + 'monitor.card.outbound_requests': '对外HTTP请求', + 'monitor.card.redis': 'Redis状态', + 'monitor.card.event_listener': '事件监听', + 'monitor.card.recent_alerts': '最近告警', + 'monitor.card.mysql': 'MySQL', + 'monitor.card.http_requests_log': '接收请求记录', + 'monitor.card.scheduler_detail': '定时任务详情', + 'monitor.card.outbound_requests_log': '发送请求记录', + 'monitor.card.callback_tracker': '回调跟踪器', + 'monitor.card.event_deduplicator': '事件去重器', // ============ 指标标签 ============ - 'metric.cpu': 'CPU 使用率', - 'metric.memory': '内存使用', - 'metric.threads': '线程数', - 'metric.uptime': '运行时间', - 'metric.total_connections': '总连接数', - 'metric.healthy': '健康', - 'metric.unhealthy': '异常', - 'metric.degraded': '降级', - 'metric.total': '总数', - 'metric.success': '成功', - 'metric.failed': '失败', - 'metric.pending': '待处理', - 'metric.active': '活跃', - 'metric.idle': '空闲', - 'metric.unknown': '未知', - 'metric.warning': '警告', - 'metric.events_received': '接收事件', - 'metric.events_processed': '处理事件', - 'metric.events_failed': '失败事件', - 'metric.jobs_running': '运行中任务', - 'metric.jobs_pending': '待执行任务', - 'metric.requests_total': '总请求数', - 'metric.requests_slow': '慢请求', - 'metric.requests_error': '错误请求', - 'metric.error_rate': '错误率', - 'metric.avg_time': '平均响应', - 'metric.connection_status': '连接状态', - 'metric.host': '主机', - 'metric.port': '端口', - 'metric.database': '数据库', - 'metric.used_connections': '使用连接数', - 'metric.max_connections': '最大连接数', - 'metric.connection_usage': '连接使用率', - 'metric.buffer_size': '缓冲大小', - 'metric.buffer_threshold': '缓冲阈值', - 'metric.buffer_usage': '缓冲使用率', - 'metric.events_interrupted': '中断处理', - 'metric.overall_success_rate': '整体成功率', - 'metric.active_event_types': '活跃事件类型', - 'metric.backpressure_status': '背压状态', - 'metric.backpressure_pending': '待处理事件', - 'metric.backpressure_usage': '背压使用率', - 'metric.event_loop_status': '事件循环状态', - 'metric.pending_callbacks': '待处理回调', - 'metric.max_retries': '最大重试次数', - 'metric.pending_retries': '待处理重试', - 'metric.total_entries': '总存储条目', - 'metric.active_items': '活跃项目', - 'metric.ttl_seconds': 'TTL (秒)', - 'metric.max_entries': '最大条目', - 'metric.dl_total': 'DL总数', - 'metric.recent_dl': '最近DL', - 'metric.process_success_rate': '处理成功率', - 'metric.scheduler_status': '调度器状态', - 'metric.job_count': '任务数量', - 'metric.pending_events': '待写入事件', - 'metric.total_events': '总事件数', - 'metric.file_size': '文件大小', - 'metric.running_status': '运行状态', + 'monitor.metric.cpu': 'CPU 使用率', + 'monitor.metric.memory': '内存使用', + 'monitor.metric.threads': '线程数', + 'monitor.metric.uptime': '运行时间', + 'monitor.metric.total_connections': '总连接数', + 'monitor.metric.healthy': '健康', + 'monitor.metric.unhealthy': '异常', + 'monitor.metric.degraded': '降级', + 'monitor.metric.total': '总数', + 'monitor.metric.success': '成功', + 'monitor.metric.failed': '失败', + 'monitor.metric.pending': '待处理', + 'monitor.metric.active': '活跃', + 'monitor.metric.idle': '空闲', + 'monitor.metric.unknown': '未知', + 'monitor.metric.warning': '警告', + 'monitor.metric.events_received': '接收事件', + 'monitor.metric.events_processed': '处理事件', + 'monitor.metric.events_failed': '失败事件', + 'monitor.metric.jobs_running': '运行中任务', + 'monitor.metric.jobs_pending': '待执行任务', + 'monitor.metric.requests_total': '总请求数', + 'monitor.metric.requests_slow': '慢请求', + 'monitor.metric.requests_error': '错误请求', + 'monitor.metric.error_rate': '错误率', + 'monitor.metric.avg_time': '平均响应', + 'monitor.metric.connection_status': '连接状态', + 'monitor.metric.host': '主机', + 'monitor.metric.port': '端口', + 'monitor.metric.database': '数据库', + 'monitor.metric.used_connections': '使用连接数', + 'monitor.metric.max_connections': '最大连接数', + 'monitor.metric.connection_usage': '连接使用率', + 'monitor.metric.buffer_size': '缓冲大小', + 'monitor.metric.buffer_threshold': '缓冲阈值', + 'monitor.metric.buffer_usage': '缓冲使用率', + 'monitor.metric.events_interrupted': '中断处理', + 'monitor.metric.overall_success_rate': '整体成功率', + 'monitor.metric.active_event_types': '活跃事件类型', + 'monitor.metric.backpressure_status': '背压状态', + 'monitor.metric.backpressure_pending': '待处理事件', + 'monitor.metric.backpressure_usage': '背压使用率', + 'monitor.metric.event_loop_status': '事件循环状态', + 'monitor.metric.pending_callbacks': '待处理回调', + 'monitor.metric.max_retries': '最大重试次数', + 'monitor.metric.pending_retries': '待处理重试', + 'monitor.metric.total_entries': '总存储条目', + 'monitor.metric.active_items': '活跃项目', + 'monitor.metric.ttl_seconds': 'TTL (秒)', + 'monitor.metric.max_entries': '最大条目', + 'monitor.metric.dl_total': 'DL总数', + 'monitor.metric.recent_dl': '最近DL', + 'monitor.metric.process_success_rate': '处理成功率', + 'monitor.metric.scheduler_status': '调度器状态', + 'monitor.metric.job_count': '任务数量', + 'monitor.metric.pending_events': '待写入事件', + 'monitor.metric.total_events': '总事件数', + 'monitor.metric.file_size': '文件大小', + 'monitor.metric.running_status': '运行状态', // ============ 状态 ============ - 'status.healthy': '● 系统正常', - 'status.unhealthy': '● 系统异常', - 'status.degraded': '● 系统降级', - 'status.running': '运行中', - 'status.checking': '检查中', - 'status.stopped': '已停止', - 'status.loading': '加载中...', - 'status.querying': '查询中...', - 'status.exporting': '导出中...', - 'status.no_data': '暂无数据', - 'status.connected': '已连接', - 'status.connecting': '连接中...', - 'status.disconnected': '已断开', - 'status.reconnecting': '重连中...', - 'status.paused': '已暂停', - 'status.enabled': '已启用', - 'status.disabled': '已禁用', - 'status.no_db_connections': '暂无数据库连接', - 'status.no_scheduler': '暂无定时任务', - 'status.no_http_requests': '暂无接收请求', - 'status.no_alerts': '暂无告警', - 'status.no_logs': '暂无日志', - 'status.no_events': '暂无事件统计', - 'status.no_api_requests': '暂无 API 请求记录', - 'status.no_outbound_requests': '暂无发送请求记录', - 'status.no_dead_letters': '暂无DL', - 'status.partial_warnings': '● 部分警告', - 'status.monitoring': '监控中', + 'monitor.status.healthy': '● 系统正常', + 'monitor.status.unhealthy': '● 系统异常', + 'monitor.status.degraded': '● 系统降级', + 'monitor.status.running': '运行中', + 'monitor.status.checking': '检查中', + 'monitor.status.stopped': '已停止', + 'monitor.status.loading': '加载中...', + 'monitor.status.querying': '查询中...', + 'monitor.status.exporting': '导出中...', + 'monitor.status.no_data': '暂无数据', + 'monitor.status.connected': '已连接', + 'monitor.status.connecting': '连接中...', + 'monitor.status.disconnected': '已断开', + 'monitor.status.reconnecting': '重连中...', + 'monitor.status.paused': '已暂停', + 'monitor.status.enabled': '已启用', + 'monitor.status.disabled': '已禁用', + 'monitor.status.no_db_connections': '暂无数据库连接', + 'monitor.status.no_scheduler': '暂无定时任务', + 'monitor.status.no_http_requests': '暂无接收请求', + 'monitor.status.no_alerts': '暂无告警', + 'monitor.status.no_logs': '暂无日志', + 'monitor.status.no_events': '暂无事件统计', + 'monitor.status.no_api_requests': '暂无 API 请求记录', + 'monitor.status.no_outbound_requests': '暂无发送请求记录', + 'monitor.status.no_dead_letters': '暂无DL', + 'monitor.status.partial_warnings': '● 部分警告', + 'monitor.status.monitoring': '监控中', // ============ 按钮 ============ - 'btn.query': '查询', - 'btn.reset': '重置', - 'btn.refresh': '刷新', - 'btn.export': '导出', - 'btn.export_csv': '导出 CSV', - 'btn.export_json': '导出 JSON', - 'btn.detail': '详情', - 'btn.pause': '暂停', - 'btn.resume': '继续', - 'btn.clear': '清空', - 'btn.save': '保存', - 'btn.delete': '删除', - 'btn.close': '关闭', - 'btn.confirm': '确认', - 'btn.cancel': '取消', - 'btn.test': '测试', - 'btn.apply': '应用', - 'btn.filter': '过滤', - 'btn.clear_all': '清空全部', - 'btn.realtime_on': '实时追踪: 开', - 'btn.realtime_off': '实时追踪: 关', - 'btn.precise_locate': '± 60s', - 'btn.precise_cancel': '± 60s - 点击取消', - 'btn.reset_stats': '重置统计', - 'btn.flush_all': '立即刷新所有', - 'btn.new_window': '新窗口', - 'btn.auto_scroll': '自动滚动', - 'btn.live_logs': '实时日志', - 'btn.history_query': '历史查询', - 'btn.mark_all_read': '标记全部已读', - 'btn.clear_read_status': '清空已读状态', + 'monitor.btn.query': '查询', + 'monitor.btn.reset': '重置', + 'monitor.btn.refresh': '刷新', + 'monitor.btn.export': '导出', + 'monitor.btn.export_csv': '导出 CSV', + 'monitor.btn.export_json': '导出 JSON', + 'monitor.btn.detail': '详情', + 'monitor.btn.pause': '暂停', + 'monitor.btn.resume': '继续', + 'monitor.btn.clear': '清空', + 'monitor.btn.save': '保存', + 'monitor.btn.delete': '删除', + 'monitor.btn.close': '关闭', + 'monitor.btn.confirm': '确认', + 'monitor.btn.cancel': '取消', + 'monitor.btn.test': '测试', + 'monitor.btn.apply': '应用', + 'monitor.btn.filter': '过滤', + 'monitor.btn.clear_all': '清空全部', + 'monitor.btn.realtime_on': '实时追踪: 开', + 'monitor.btn.realtime_off': '实时追踪: 关', + 'monitor.btn.precise_locate': '± 60s', + 'monitor.btn.precise_cancel': '± 60s - 点击取消', + 'monitor.btn.reset_stats': '重置统计', + 'monitor.btn.flush_all': '立即刷新所有', + 'monitor.btn.new_window': '新窗口', + 'monitor.btn.auto_scroll': '自动滚动', + 'monitor.btn.live_logs': '实时日志', + 'monitor.btn.history_query': '历史查询', + 'monitor.btn.mark_all_read': '标记全部已读', + 'monitor.btn.clear_read_status': '清空已读状态', // ============ 表格列名 ============ - 'col.index': '序号', - 'col.time': '时间', - 'col.level': '级别', - 'col.module': '模块', - 'col.message': '消息', - 'col.method': '方法', - 'col.path': '端点', - 'col.url': 'URL', - 'col.status': '状态码', - 'col.duration': '响应时间', - 'col.client_ip': '客户端IP', - 'col.source': '来源', - 'col.function': '函数', - 'col.line': '行号', - 'col.operation': '操作', - 'col.count': '数量', - 'col.avg_time': '平均时间', - 'col.max_time': '最大时间', - 'col.db_name': '账套名称', - 'col.last_check': '最后检查', - 'col.current_connections': '当前连接', - 'col.max_connections': '最大连接', - 'col.min_connections': '最小连接', - 'col.idle_connections': '空闲连接', - 'col.used_connections': '使用中连接', - 'col.usage': '使用率', - 'col.processed_records': '处理记录', - 'col.timestamp': '时间戳', - 'col.query_params': '查询参数', - 'col.error_message': '错误信息', - 'col.url': 'URL', - 'col.is_read': '已读', - 'col.description': '描述', - 'col.total_received': '总接收', - 'col.pending': '待处理', - 'col.processed': '已处理', - 'col.interrupted': '中断', - 'col.completion_rate': '完成率', - 'col.avg_latency': '平均延迟', - 'col.last_action': '最后动作', - 'col.id': 'ID', - 'col.event_type': '事件类型', - 'col.table': '表', + 'monitor.col.index': '序号', + 'monitor.col.time': '时间', + 'monitor.col.level': '级别', + 'monitor.col.module': '模块', + 'monitor.col.message': '消息', + 'monitor.col.method': '方法', + 'monitor.col.path': '端点', + 'monitor.col.url': 'URL', + 'monitor.col.status': '状态码', + 'monitor.col.duration': '响应时间', + 'monitor.col.client_ip': '客户端IP', + 'monitor.col.source': '来源', + 'monitor.col.function': '函数', + 'monitor.col.line': '行号', + 'monitor.col.operation': '操作', + 'monitor.col.count': '数量', + 'monitor.col.avg_time': '平均时间', + 'monitor.col.max_time': '最大时间', + 'monitor.col.db_name': '账套名称', + 'monitor.col.last_check': '最后检查', + 'monitor.col.current_connections': '当前连接', + 'monitor.col.max_connections': '最大连接', + 'monitor.col.min_connections': '最小连接', + 'monitor.col.idle_connections': '空闲连接', + 'monitor.col.used_connections': '使用中连接', + 'monitor.col.usage': '使用率', + 'monitor.col.processed_records': '处理记录', + 'monitor.col.timestamp': '时间戳', + 'monitor.col.query_params': '查询参数', + 'monitor.col.error_message': '错误信息', + 'monitor.col.url': 'URL', + 'monitor.col.is_read': '已读', + 'monitor.col.description': '描述', + 'monitor.col.total_received': '总接收', + 'monitor.col.pending': '待处理', + 'monitor.col.processed': '已处理', + 'monitor.col.interrupted': '中断', + 'monitor.col.completion_rate': '完成率', + 'monitor.col.avg_latency': '平均延迟', + 'monitor.col.last_action': '最后动作', + 'monitor.col.id': 'ID', + 'monitor.col.event_type': '事件类型', + 'monitor.col.table': '表', // ============ 快捷时间 ============ - 'time.start_time': '开始时间', - 'time.end_time': '结束时间', - 'time.last_10m': '最近10分钟', - 'time.last_30m': '最近30分钟', - 'time.last_1h': '最近1小时', - 'time.last_6h': '最近6小时', - 'time.last_24h': '最近24小时', - 'time.range': '时间范围', + 'monitor.time.start_time': '开始时间', + 'monitor.time.end_time': '结束时间', + 'monitor.time.last_10m': '最近10分钟', + 'monitor.time.last_30m': '最近30分钟', + 'monitor.time.last_1h': '最近1小时', + 'monitor.time.last_6h': '最近6小时', + 'monitor.time.last_24h': '最近24小时', + 'monitor.time.range': '时间范围', // ============ 过滤条件 ============ - 'filter.level': '全部级别', - 'filter.type': '全部数据', - 'filter.module': '模块', - 'filter.keyword': '关键词', - 'filter.method': '请求方法', - 'filter.client_ip': '客户端IP', - 'filter.status_range': '状态码范围', - 'filter.duration_range': '响应时间范围', - 'filter.advanced': '高级过滤', - 'filter.collapse': '收起', - 'filter.expand': '展开', - 'filter.clear': '清空', - 'filter.active': '已激活过滤条件', - 'filter.module_placeholder': '输入模块名', - 'filter.keyword_placeholder': '输入关键词搜索', - 'filter.ip_placeholder': '输入客户端IP', - 'filter.status_placeholder': '如: 400-499', - 'filter.duration_placeholder': '如: >1000', - 'filter.all_logs': '全部日志', + 'monitor.filter.level': '全部级别', + 'monitor.filter.type': '全部数据', + 'monitor.filter.module': '模块', + 'monitor.filter.keyword': '关键词', + 'monitor.filter.method': '请求方法', + 'monitor.filter.client_ip': '客户端IP', + 'monitor.filter.status_range': '状态码范围', + 'monitor.filter.duration_range': '响应时间范围', + 'monitor.filter.advanced': '高级过滤', + 'monitor.filter.collapse': '收起', + 'monitor.filter.expand': '展开', + 'monitor.filter.clear': '清空', + 'monitor.filter.active': '已激活过滤条件', + 'monitor.filter.module_placeholder': '输入模块名', + 'monitor.filter.keyword_placeholder': '输入关键词搜索', + 'monitor.filter.ip_placeholder': '输入客户端IP', + 'monitor.filter.status_placeholder': '如: 400-499', + 'monitor.filter.duration_placeholder': '如: >1000', + 'monitor.filter.all_logs': '全部日志', // ============ 图表 ============ - 'chart.request_trend': '📊 请求量趋势', - 'chart.level_distribution': '📊 日志级别分布', - 'chart.status_distribution': '📈 状态码分布', - 'chart.slow_requests': '⏱️ 慢请求TOP10', - 'chart.total_requests': '总请求', - 'chart.error_count': '错误', - 'chart.slow_count': '慢请求', - 'chart.log_count': '日志总数', - 'chart.no_slow': '✅ 无慢请求', - 'chart.query_required': '请先执行查询', - 'chart.load_failed': '❌ 图表数据加载失败,请重试', - 'chart.redis_connections': 'Redis 连接池使用情况', - 'chart.redis_buffer': 'Redis 缓冲大小变化', - 'chart.cpu': 'CPU', - 'chart.memory': '内存', - 'chart.upload': '上传', - 'chart.download': '下载', - 'chart.cpu_memory_axis': 'CPU / 内存 (%)', - 'chart.network_axis': '网络上传 / 下载 (KB/s)', - 'chart.used_connections': '使用连接数', - 'chart.buffer_size_mb': '缓冲大小 (MB)', + 'monitor.chart.request_trend': '📊 请求量趋势', + 'monitor.chart.level_distribution': '📊 日志级别分布', + 'monitor.chart.status_distribution': '📈 状态码分布', + 'monitor.chart.slow_requests': '⏱️ 慢请求TOP10', + 'monitor.chart.total_requests': '总请求', + 'monitor.chart.error_count': '错误', + 'monitor.chart.slow_count': '慢请求', + 'monitor.chart.log_count': '日志总数', + 'monitor.chart.no_slow': '✅ 无慢请求', + 'monitor.chart.query_required': '请先执行查询', + 'monitor.chart.load_failed': '❌ 图表数据加载失败,请重试', + 'monitor.chart.no_data': '无数据', + 'monitor.chart.no_trend': '无趋势数据', + 'monitor.chart.redis_connections': 'Redis 连接池使用情况', + 'monitor.chart.redis_buffer': 'Redis 缓冲大小变化', + 'monitor.chart.cpu': 'CPU', + 'monitor.chart.memory': '内存', + 'monitor.chart.upload': '上传', + 'monitor.chart.download': '下载', + 'monitor.chart.cpu_memory_axis': 'CPU / 内存 (%)', + 'monitor.chart.network_axis': '网络上传 / 下载 (KB/s)', + 'monitor.chart.used_connections': '使用连接数', + 'monitor.chart.buffer_size_mb': '缓冲大小 (MB)', // ============ 错误提示 ============ - 'error.time_range_invalid': '开始时间不能大于结束时间', - 'error.time_range_required': '请选择开始时间和结束时间', - 'error.query_failed': '查询失败,请稍后重试', - 'error.export_failed': '导出失败,请重试', - 'error.connection_failed': '连接失败,请刷新页面', - 'error.max_templates': '最多保存10个模板,请先删除部分模板', - 'error.auto_pause': '实时追踪已自动暂停(超过10分钟)', - 'error.load_failed': '加载失败,请重试', - 'error.invalid_params': '参数错误', - 'error.clear_dl_failed': '清空DeadLetter队列失败', + 'monitor.error.time_range_invalid': '开始时间不能大于结束时间', + 'monitor.error.time_range_required': '请选择开始时间和结束时间', + 'monitor.error.query_failed': '查询失败,请稍后重试', + 'monitor.error.export_failed': '导出失败,请重试', + 'monitor.error.connection_failed': '连接失败,请刷新页面', + 'monitor.error.max_templates': '最多保存10个模板,请先删除部分模板', + 'monitor.error.auto_pause': '实时追踪已自动暂停(超过10分钟)', + 'monitor.error.load_failed': '加载失败,请重试', + 'monitor.error.invalid_params': '参数错误', + 'monitor.error.clear_dl_failed': '清空DeadLetter队列失败', // ============ 成功提示 ============ - 'success.query_complete': '查询完成', - 'success.export_complete': '导出完成', - 'success.template_saved': '模板"{name}"已保存', - 'success.logs_cleared': '日志已清空', - 'success.operation_success': '操作成功', - 'success.dl_cleared': 'DeadLetter队列已清空', + 'monitor.success.query_complete': '查询完成', + 'monitor.success.export_complete': '导出完成', + 'monitor.success.template_saved': '模板"{name}"已保存', + 'monitor.success.logs_cleared': '日志已清空', + 'monitor.success.operation_success': '操作成功', + 'monitor.success.dl_cleared': 'DeadLetter队列已清空', // ============ 时间线 ============ - 'timeline.title': '时间线', - 'timeline.no_data': '暂无数据,请先执行查询', - 'timeline.anomaly_detected': '⚠️ 发现 {count} 处异常', - 'timeline.error_burst': '连续{count}条ERROR日志', - 'timeline.slow_anomaly': '异常慢请求({duration}ms > 平均{avg}ms×3)', - 'timeline.duplicate_error': '重复错误"{msg}"出现{count}次', - 'timeline.http_request': 'HTTP请求', - 'timeline.outbound_request': '发送请求', - 'timeline.system_log': '系统日志', + 'monitor.timeline.title': '时间线', + 'monitor.timeline.no_data': '暂无数据,请先执行查询', + 'monitor.timeline.anomaly_detected': '⚠️ 发现 {count} 处异常', + 'monitor.timeline.error_burst': '连续{count}条ERROR日志', + 'monitor.timeline.slow_anomaly': '异常慢请求({duration}ms > 平均{avg}ms×3)', + 'monitor.timeline.duplicate_error': '重复错误"{msg}"出现{count}次', + 'monitor.timeline.http_request': 'HTTP请求', + 'monitor.timeline.outbound_request': '发送请求', + 'monitor.timeline.system_log': '系统日志', + 'monitor.timeline.summary_title': '📊 时间线统计', + 'monitor.timeline.total_events': '总事件', + 'monitor.timeline.http_requests': 'HTTP请求', + 'monitor.timeline.outbound_requests': '发送请求', + 'monitor.timeline.system_logs': '系统日志', + 'monitor.timeline.errors': '错误', + 'monitor.timeline.warnings': '警告', + 'monitor.timeline.slow_requests': '慢请求', // ============ 分页 ============ - 'pagination.page': '页', - 'pagination.of': '共', - 'pagination.items': '条', - 'pagination.showing': '显示', - 'pagination.per_page': '每页', - 'pagination.first': '首页', - 'pagination.last': '末页', - 'pagination.prev': '上一页', - 'pagination.next': '下一页', - 'pagination.go_to': '跳转', + 'monitor.pagination.page': '页', + 'monitor.pagination.of': '共', + 'monitor.pagination.items': '条', + 'monitor.pagination.showing': '显示', + 'monitor.pagination.per_page': '每页', + 'monitor.pagination.first': '首页', + 'monitor.pagination.last': '末页', + 'monitor.pagination.prev': '上一页', + 'monitor.pagination.next': '下一页', + 'monitor.pagination.go_to': '跳转', // ============ 导出 ============ - 'export.current_page': '导出当前页', - 'export.all_data': '导出全部数据', - 'export.format_csv': 'CSV格式', - 'export.format_json': 'JSON格式', - 'export.select_format': '选择导出格式', + 'monitor.export.current_page': '导出当前页', + 'monitor.export.all_data': '导出全部数据', + 'monitor.export.format_csv': 'CSV格式', + 'monitor.export.format_json': 'JSON格式', + 'monitor.export.select_format': '选择导出格式', // ============ 查询模板 ============ - 'template.saved_queries': '已保存查询...', - 'template.save': '保存查询条件', - 'template.manage': '管理模板', - 'template.name': '模板名称', - 'template.description': '描述', - 'template.delete_confirm': '确定删除该模板?', - 'template.empty': '暂无保存的模板', + 'monitor.template.saved_queries': '已保存查询...', + 'monitor.template.save': '保存查询条件', + 'monitor.template.manage': '管理模板', + 'monitor.template.name': '模板名称', + 'monitor.template.description': '描述', + 'monitor.template.delete_confirm': '确定删除该模板?', + 'monitor.template.empty': '暂无保存的模板', // ============ 统计信息 ============ - 'stats.time_range': '查询时间范围', - 'stats.http_requests': '接收请求', - 'stats.outbound_requests': '发送请求', - 'stats.system_logs': '系统日志', - 'stats.level_distribution': '级别分布', - 'stats.all_time': '全部时间', + 'monitor.stats.time_range': '查询时间范围', + 'monitor.stats.http_requests': '接收请求', + 'monitor.stats.outbound_requests': '发送请求', + 'monitor.stats.system_logs': '系统日志', + 'monitor.stats.level_distribution': '级别分布', + 'monitor.stats.all_time': '全部时间', // ============ 其他 ============ - 'other.last_update': '最后更新', - 'other.auto_reconnect': '5秒后重连', - 'other.waiting_logs': '正在等待日志数据...', - 'other.no_matching_logs': '没有匹配的日志', - 'other.precise_mode': '精确定位', - 'other.saved_queries': '已保存查询...', - 'other.all_time': '全部时间', - 'other.linked_query': '联动查询', - 'other.seconds': '秒', - 'other.minutes': '分钟', - 'other.hours': '小时', - 'other.days': '天', - 'other.ms': '毫秒', - 'other.times': '次', - 'other.view_detail': '查看详情', - 'other.copy': '复制', - 'other.expand': '展开', - 'other.collapse': '收起', - 'other.show_internal': '显示内部请求', - 'other.show_read': '显示已读', + 'monitor.other.last_update': '最后更新', + 'monitor.other.auto_reconnect': '5秒后重连', + 'monitor.other.waiting_logs': '正在等待日志数据...', + 'monitor.other.no_matching_logs': '没有匹配的日志', + 'monitor.other.precise_mode': '精确定位', + 'monitor.other.saved_queries': '已保存查询...', + 'monitor.other.all_time': '全部时间', + 'monitor.other.linked_query': '联动查询', + 'monitor.other.seconds': '秒', + 'monitor.other.minutes': '分钟', + 'monitor.other.hours': '小时', + 'monitor.other.days': '天', + 'monitor.other.ms': '毫秒', + 'monitor.other.times': '次', + 'monitor.other.view_detail': '查看详情', + 'monitor.other.copy': '复制', + 'monitor.other.expand': '展开', + 'monitor.other.collapse': '收起', + 'monitor.other.show_internal': '显示内部请求', + 'monitor.other.show_read': '显示已读', // ============ 日期 ============ - 'date.today': '今天', - 'date.yesterday': '昨天', + 'monitor.date.today': '今天', + 'monitor.date.yesterday': '昨天', // ============ 语言选择 ============ - 'lang.select': '选择语言', - 'lang.zh': '中文', - 'lang.en': 'English', - 'lang.de': 'Deutsch', + 'monitor.lang.select': '选择语言', + 'monitor.lang.zh': '中文', + 'monitor.lang.en': 'English', + 'monitor.lang.de': 'Deutsch', // ============ HTTP方法 ============ - 'method.get': 'GET', - 'method.post': 'POST', - 'method.put': 'PUT', - 'method.delete': 'DELETE', - 'method.patch': 'PATCH', + 'monitor.method.get': 'GET', + 'monitor.method.post': 'POST', + 'monitor.method.put': 'PUT', + 'monitor.method.delete': 'DELETE', + 'monitor.method.patch': 'PATCH', // ============ 日志级别 ============ - 'level.debug': 'DEBUG', - 'level.info': 'INFO', - 'level.warning': 'WARNING', - 'level.error': 'ERROR', - 'level.critical': 'CRITICAL', + 'monitor.level.debug': 'DEBUG', + 'monitor.level.info': 'INFO', + 'monitor.level.warning': 'WARNING', + 'monitor.level.error': 'ERROR', + 'monitor.level.critical': 'CRITICAL', // ============ 定时任务 ============ - 'scheduler.rule': '定时规则', - 'scheduler.last_run': '最近执行', - 'scheduler.max_time': '最大执行时间', - 'scheduler.never_run': '从未执行', - 'scheduler.default': '默认', - 'scheduler.running': '执行中', - 'scheduler.not_scheduled': '未计划', + 'monitor.scheduler.rule': '定时规则', + 'monitor.scheduler.last_run': '最近执行', + 'monitor.scheduler.max_time': '最大执行时间', + 'monitor.scheduler.never_run': '从未执行', + 'monitor.scheduler.default': '默认', + 'monitor.scheduler.running': '执行中', + 'monitor.scheduler.not_scheduled': '未计划', // ============ 相对时间 ============ - 'time.just_now': '刚刚', - 'time.minutes_ago': '{n}分钟前', - 'time.hours_ago': '{n}小时前', - 'time.days_ago': '{n}天前', - 'time.day_before_yesterday': '前天', + 'monitor.time.just_now': '刚刚', + 'monitor.time.minutes_ago': '{n}分钟前', + 'monitor.time.hours_ago': '{n}小时前', + 'monitor.time.days_ago': '{n}天前', + 'monitor.time.day_before_yesterday': '前天', // ============ 告警类型 ============ - 'alert.warning': '警告', - 'alert.error': '错误', - 'alert.critical': '严重', - 'alert.normal': '正常', + 'monitor.alert.warning': '警告', + 'monitor.alert.error': '错误', + 'monitor.alert.critical': '严重', + 'monitor.alert.normal': '正常', // ============ 连接状态 ============ - 'connection.failed': '连接失败', - 'connection.reconnecting': '重新连接', - 'connection.connected': '已连接', - 'connection.disconnected': '断开', + 'monitor.connection.failed': '连接失败', + 'monitor.connection.reconnecting': '重新连接', + 'monitor.connection.connected': '已连接', + 'monitor.connection.disconnected': '断开', // ============ 监控状态 ============ - 'monitor.paused': '● 监控已暂停(长时间未活动)', - 'monitor.panel': '监控面板', - 'monitor.last_update': '最后更新', - 'monitor.reset_stats_confirm': '确定要重置所有事件统计吗?', + 'monitor.monitor.paused': '● 监控已暂停(长时间未活动)', + 'monitor.monitor.panel': '监控面板', + 'monitor.monitor.last_update': '最后更新', + 'monitor.monitor.reset_stats_confirm': '确定要重置所有事件统计吗?', // ============ 高亮操作 ============ - 'highlight.on': '已高亮', - 'highlight.off': '高亮', + 'monitor.highlight.on': '已高亮', + 'monitor.highlight.off': '高亮', // ============ 复制操作 ============ - 'copy.success': '已复制', - 'copy.failed': '复制失败,请手动复制', - 'copy.error': '复制失败', + 'monitor.copy.success': '已复制', + 'monitor.copy.failed': '复制失败,请手动复制', + 'monitor.copy.error': '复制失败', // ============ 选择提示 ============ - 'prompt.select_date': '请选择日期', - 'prompt.fetch_failed': '获取请求记录失败,请稍后重试', - 'prompt.fetch_outbound_failed': '获取对外请求记录失败,请稍后重试', - 'prompt.reset_failed': '重置失败,请重试', + 'monitor.prompt.select_date': '请选择日期', + 'monitor.prompt.fetch_failed': '获取请求记录失败,请稍后重试', + 'monitor.prompt.fetch_outbound_failed': '获取对外请求记录失败,请稍后重试', + 'monitor.prompt.reset_failed': '重置失败,请重试', // ============ 页面标题 ============ - 'page.http_requests_log': '接收请求记录', - 'page.outbound_requests_log': '发送请求记录', + 'monitor.page.http_requests_log': '接收请求记录', + 'monitor.page.outbound_requests_log': '发送请求记录', // ============ 时间相关 ============ - 'time.tomorrow': '明天', - 'time.day_after_tomorrow': '后天', - 'time.over_24h': '超过24小时', - 'time.expired': '已过期', - 'time.days_hours_later': '{days}天{hours}小时后', - 'time.unknown': '未知', - 'time.month_day': '{month}月{day}日', + 'monitor.time.tomorrow': '明天', + 'monitor.time.day_after_tomorrow': '后天', + 'monitor.time.over_24h': '超过24小时', + 'monitor.time.expired': '已过期', + 'monitor.time.days_hours_later': '{days}天{hours}小时后', + 'monitor.time.unknown': '未知', + 'monitor.time.month_day': '{month}月{day}日', // ============ 任务类型 ============ - 'task.system': '系统', - 'task.project': '项目', - 'task.avg_time': '平均执行时间', + 'monitor.task.system': '系统', + 'monitor.task.project': '项目', + 'monitor.task.avg_time': '平均执行时间', // ============ 详情模态框 ============ - 'modal.outbound_detail': '发送请求详情', - 'modal.timestamp': '时间戳:', - 'modal.method': '方法:', - 'modal.status_code': '状态码:', - 'modal.response_time': '响应时间:', - 'modal.module': '模块:', - 'modal.error_msg': '错误信息:', + 'monitor.modal.outbound_detail': '发送请求详情', + 'monitor.modal.timestamp': '时间戳:', + 'monitor.modal.method': '方法:', + 'monitor.modal.status_code': '状态码:', + 'monitor.modal.response_time': '响应时间:', + 'monitor.modal.module': '模块:', + 'monitor.modal.error_msg': '错误信息:', // ============ 请求/响应部分 ============ - 'section.request_headers': '请求头', - 'section.request_body': '请求体', - 'section.response_headers': '响应头', - 'section.response_body': '响应体', - 'section.no_response': '无响应体数据', - 'section.response_failed': '响应体处理失败: ', - 'section.truncated': '[内容已截断,完整内容请导出查看]', - 'section.large_data_warning': '⚠️ 数据量较大({count}字符),可能影响显示性能', - 'section.showing_chars': '仅显示前{count}字符', - 'section.basic_info': '基本信息', - 'section.no_data': '无数据', + 'monitor.section.request_headers': '请求头', + 'monitor.section.request_body': '请求体', + 'monitor.section.response_headers': '响应头', + 'monitor.section.response_body': '响应体', + 'monitor.section.no_response': '无响应体数据', + 'monitor.section.response_failed': '响应体处理失败: ', + 'monitor.section.truncated': '[内容已截断,完整内容请导出查看]', + 'monitor.section.large_data_warning': '⚠️ 数据量较大({count}字符),可能影响显示性能', + 'monitor.section.showing_chars': '仅显示前{count}字符', + 'monitor.section.basic_info': '基本信息', + 'monitor.section.no_data': '无数据', // ============ 限流状态 ============ - 'status.rate_limited': '限流', + 'monitor.status.rate_limited': '限流', // ============ 日志级别选择 ============ - 'log_level.all_with_debug': '全部级别 (含DEBUG)', - 'log_level.error': '错误日志', - 'log_level.warning': '警告日志', - 'log_level.info': '信息日志', - 'log_level.debug': '调试日志', + 'monitor.log_level.all_with_debug': '全部级别 (含DEBUG)', + 'monitor.log_level.error': '错误日志', + 'monitor.log_level.warning': '警告日志', + 'monitor.log_level.info': '信息日志', + 'monitor.log_level.debug': '调试日志', // ============ DeadLetter ============ - 'dl.reprocess': '重新处理', - 'dl.reprocess_success': 'DeadLetter重新处理成功', - 'dl.reprocess_failed': 'DeadLetter重新处理失败', + 'monitor.dl.reprocess': '重新处理', + 'monitor.dl.reprocess_success': 'DeadLetter重新处理成功', + 'monitor.dl.reprocess_failed': 'DeadLetter重新处理失败', // ============ 后端告警消息映射 ============ - 'alert.scheduler_not_running': '调度器未运行', - 'alert.db_connection_failed': '数据库连接失败', - 'alert.redis_connection_failed': 'Redis连接失败', - 'alert.event_listener_stopped': '事件监听器已停止', - 'alert.binlog_listener_stopped': 'Binlog监听器已停止', - 'alert.high_error_rate': '错误率过高', - 'alert.memory_warning': '内存使用警告', - 'alert.cpu_warning': 'CPU使用警告', + 'monitor.alert.scheduler_not_running': '调度器未运行', + 'monitor.alert.db_connection_failed': '数据库连接失败', + 'monitor.alert.redis_connection_failed': 'Redis连接失败', + 'monitor.alert.event_listener_stopped': '事件监听器已停止', + 'monitor.alert.binlog_listener_stopped': 'Binlog监听器已停止', + 'monitor.alert.high_error_rate': '错误率过高', + 'monitor.alert.memory_warning': '内存使用警告', + 'monitor.alert.cpu_warning': 'CPU使用警告', // ================================================================================ // MDS模块 (数据清洗管理系统) @@ -659,5 +669,12 @@ window.__i18n_zh_CN__ = { 'mds.other.tip': '提示', 'mds.other.warning': '警告', 'mds.other.error': '错误', - 'mds.other.success': '成功' + 'mds.other.success': '成功', + + // ============ 补充翻译键 ============ + 'monitor.other.yes': '是', + 'monitor.other.no': '否', + 'monitor.other.data_points': '个时间点', + 'monitor.col.is_slow': '是否慢请求', + 'monitor.col.is_error': '是否错误' }; diff --git a/static/monitor/history-logs.html b/static/monitor/history-logs.html index d1475a9..8151646 100644 --- a/static/monitor/history-logs.html +++ b/static/monitor/history-logs.html @@ -842,8 +842,8 @@
-

📊 日志历史查询

- 联动查询 +

📊 日志历史查询

+ 联动查询
- + @@ -866,19 +866,19 @@
- - - - - - - + + + + + + +
@@ -887,36 +887,36 @@