Files
CyberStrikeAI/docs/frontend-i18n.md
2026-03-09 02:06:39 +08:00

10 KiB
Raw Permalink Blame History

CyberStrikeAI 前端国际化方案

本文档说明 CyberStrikeAI Web 前端(web/templates/index.html + web/static/js/*.js)的国际化设计与开发规范,确保在不引入打包工具和不改动后端路由的前提下,实现可扩展、低返工的多语言支持。

当前目标:

  • 支持中英文切换zh-CN / en-US
  • 后续可方便扩展更多语言(如 ja-JP、ko-KR 等)

一、总体设计原则

  • 前端主导的客户端国际化:所有 UI 文案在浏览器端根据当前语言动态渲染,后端 Go 仅负责结构和数据,不参与语言分发。
  • 单一 HTML 模板:继续使用一份 index.html 模板,不为不同语言复制模板文件。
  • 文案与逻辑分离:所有可见文本通过「键值表」管理(多语言 JSONHTML / JS 只写 key不直接写中文/英文常量。
  • 渐进式改造:先覆盖 header / 登录 / 侧边栏 / 系统设置等关键区域,其他页面按模块逐步迁移,避免一次性大改动。
  • 可回退默认语言:即使目标语言未完全翻译,也能回退到默认中文,不出现原始 key。

二、技术选型与目录结构

2.1 技术选型

  • i18n 引擎:使用 i18next 的浏览器 UMD 版本(通过 CDN 引入),无需打包器。
  • 资源格式:每种语言一份 JSON 文件,采用「域 + 语义」的层级 key 方案,例如:
    • common.ok
    • nav.dashboard
    • header.apiDocs
    • settings.robot.wecom.token

2.2 目录结构

  • web/templates/index.html
    • 页面骨架 + 所有静态文案位置,将逐步改为 data-i18n 标记。
  • web/static/js/i18n.js
    • 前端 i18n 初始化与 DOM 应用逻辑(本方案新增)。
  • web/static/i18n/(新增目录)
    • zh-CN.json:中文文案(默认语言)
    • en-US.json:英文文案
    • 未来可新增:ja-JP.jsonko-KR.json 等。

三、文案组织规范

3.1 Key 命名约定

  • 采用「模块.语义」形式,最多 23 级,确保可读性:
    • 导航:nav.dashboardnav.chatnav.settings
    • 头部:header.titleheader.apiDocsheader.logout
    • 登录:login.titlelogin.subtitlelogin.passwordLabellogin.submit
    • 仪表盘:dashboard.titledashboard.refreshdashboard.runningTasks
    • 系统设置:settings.titlesettings.nav.basicsettings.nav.robotsettings.apply
    • 机器人配置:settings.robot.wecom.enabledsettings.robot.wecom.token 等。
  • 尽量按「界面区域」而不是「文件名」划分域,便于非开发人员理解。

3.2 JSON 示例

web/static/i18n/zh-CN.json 示例:

{
  "common": {
    "ok": "确定",
    "cancel": "取消"
  },
  "nav": {
    "dashboard": "仪表盘",
    "chat": "对话",
    "infoCollect": "信息收集",
    "tasks": "任务管理",
    "vulnerabilities": "漏洞管理",
    "settings": "系统设置"
  },
  "header": {
    "title": "CyberStrikeAI",
    "apiDocs": "API 文档",
    "logout": "退出登录",
    "language": "界面语言"
  },
  "login": {
    "title": "登录 CyberStrikeAI",
    "subtitle": "请输入配置中的访问密码",
    "passwordLabel": "密码",
    "passwordPlaceholder": "输入登录密码",
    "submit": "登录"
  }
}

英文文件 en-US.json 保持相同 key不同 value

{
  "common": {
    "ok": "OK",
    "cancel": "Cancel"
  },
  "nav": {
    "dashboard": "Dashboard",
    "chat": "Chat",
    "infoCollect": "Recon",
    "tasks": "Tasks",
    "vulnerabilities": "Vulnerabilities",
    "settings": "Settings"
  },
  "header": {
    "title": "CyberStrikeAI",
    "apiDocs": "API Docs",
    "logout": "Sign out",
    "language": "Interface language"
  },
  "login": {
    "title": "Sign in to CyberStrikeAI",
    "subtitle": "Enter the access password from config",
    "passwordLabel": "Password",
    "passwordPlaceholder": "Enter password",
    "submit": "Sign in"
  }
}

约定:新增界面时,必须先定义 i18n key再在 HTML/JS 中使用 key,禁止直接写死中文/英文。


四、HTML 标记规范data-i18n

4.1 基本规则

  • 使用 data-i18n 将元素文本与某个 key 绑定:
<span data-i18n="nav.dashboard">仪表盘</span>
  • 默认行为:脚本会替换元素的 textContent
  • 同时翻译属性时,额外使用 data-i18n-attr,逗号分隔多个属性名:
<button
  class="openapi-doc-btn"
  onclick="window.open('/api-docs', '_blank')"
  data-i18n="header.apiDocs"
  data-i18n-attr="title"
  title="API 文档">
  <span data-i18n="header.apiDocs">API 文档</span>
</button>

4.2 默认文本的作用

  • HTML 内的中文默认值作为「无 JS / 初始化前」的占位内容:
    • 页面在 JS 尚未加载完成时不会出现空白或 key。
    • JS 初始化后会用当前语言覆盖这些文本。

五、JavaScript 中的文案规范

5.1 全局翻译函数 t()

i18n.js 暴露以下全局函数:

  • window.t(key: string): string
    • 返回当前语言下的翻译文本,若缺失则回退到默认语言,再不行则返回 key 本身。
  • window.changeLanguage(lang: string): Promise<void>
    • 切换语言并刷新页面文案(不会刷新整页)。

示例(以 web/static/js/settings.js 为例):

// 之前
alert('加载配置失败: ' + error.message);

// 之后
alert(t('settings.loadConfigFailed') + ': ' + error.message);

规范:JS 内所有面向用户的提示、按钮文字、对话框标题都应通过 t() 获取,不直接写死中文/英文。

5.2 渐进迁移建议

  • 优先改造:
    • 频繁弹出的错误提示 / 成功提示;
    • 登录相关、系统设置相关文案。
  • 低优先级:
    • 仅面向运维人员的调试提示,可以暂时保留英文/中文常量。

六、i18n 初始化与语言切换实现

6.1 语言选择策略

  • 默认语言:zh-CN
  • 优先级(从高到低):
    1. localStorage 中的用户选择keycsai_lang)。
    2. 浏览器 navigator.languagezh 开头 → zh-CN,否则 en-US)。
    3. 默认 zh-CN

6.2 初始化流程(i18n.js

  1. 读取初始语言。
  2. 初始化 i18next
    • lng 为当前语言;
    • fallbackLngzh-CN
    • 资源先留空,采用按需加载。
  3. 通过 fetch 拉取 /static/i18n/{lng}.jsoni18next.addResources
  4. 更新:
    • <html lang="..."> 属性;
    • 所有带 data-i18n / data-i18n-attr 的元素。
  5. 暴露 window.twindow.changeLanguage

6.3 DOM 应用逻辑

伪代码:

function applyTranslations(root = document) {
  const elements = root.querySelectorAll('[data-i18n]');
  elements.forEach(el => {
    const key = el.getAttribute('data-i18n');
    if (!key) return;
    const text = i18next.t(key);
    if (text) {
      el.textContent = text;
    }

    const attrList = el.getAttribute('data-i18n-attr');
    if (attrList) {
      attrList.split(',').map(s => s.trim()).forEach(attr => {
        if (!attr) return;
        const val = i18next.t(key);
        if (val) el.setAttribute(attr, val);
      });
    }
  });
}

对于由 JS 动态插入的元素,需要在插入后再次调用 applyTranslations(新容器)


七、语言切换 UI 规范

7.1 位置与形态

  • 位置:index.html header 右侧 API 文档 按钮附近(靠近用户头像)。
  • 交互形式:
    • 一个紧凑的语言切换组件,例如:
      • 🌐 图标 + 当前语言文本(中文 / English)的下拉按钮;
      • 下拉内容列出所有可用语言。

7.2 示例结构

<div class="lang-switcher">
  <button class="btn-secondary lang-switcher-btn" onclick="toggleLangDropdown()" data-i18n="header.language">
    <span class="lang-switcher-icon">🌐</span>
    <span id="current-lang-label">中文</span>
  </button>
  <div id="lang-dropdown" class="lang-dropdown" style="display: none;">
    <div class="lang-option" data-lang="zh-CN" onclick="onLanguageSelect('zh-CN')">中文</div>
    <div class="lang-option" data-lang="en-US" onclick="onLanguageSelect('en-US')">English</div>
  </div>
</div>

对应 JSi18n.js 中):

function onLanguageSelect(lang) {
  changeLanguage(lang).then(updateLangLabel).catch(console.error);
  closeLangDropdown();
}

function updateLangLabel() {
  const labelEl = document.getElementById('current-lang-label');
  if (!labelEl) return;
  const lang = i18next.language || 'zh-CN';
  labelEl.textContent = lang.startsWith('zh') ? '中文' : 'English';
}

规范:语言切换只更新文案,不刷新整页,也不修改 URL hash


八、开发流程建议

8.1 新增 / 修改界面的流程

  1. 设计界面时,先列出所有文案。
  2. 在对应语言 JSON 中补充/修改 key 与翻译。
  3. 在 HTML 中使用 data-i18n,在 JS 中使用 t('...')
  4. 在浏览器中切换中英文,确认两种语言显示都正确。

8.2 渐进式改造顺序(推荐)

  1. 阶段 1已规划
    • 引入 i18next 与 i18n.js
    • 新建 zh-CN.json / en-US.json(先覆盖 header / 登录 / 左侧导航)。
    • 实现 header 区域语言切换组件。
  2. 阶段 2(已完成)
    • 系统设置页面(包括机器人配置页面)全部文案 i18n 化。
    • settings.js 中的提示与错误信息改用 t()
  3. 阶段 3(进行中)
    • 仪表盘、任务管理、漏洞管理、MCP、Skills、Roles 等页面按模块逐步迁移。
  4. 阶段 4
    • 清理 JS / HTML 中残留的硬编码中文,统一通过 i18n。

九、后续扩展新语言

当需要新增语言时:

  1. web/static/i18n/ 中新增 {lang}.json,复制现有英文/中文文件结构,补充对应翻译。
  2. 在语言切换下拉中添加对应选项,例如:
    • data-lang="ja-JP" / 文本 日本語
  3. 无需修改 i18n.js 或现有 HTML/JS 逻辑,即可支持新语言。

十、注意事项与坑点

  • 不要复制多份 HTML 模板 来做多语言,那样维护成本极高,本方案统一由前端 i18n 控制。
  • 避免 key 直接用中文/英文句子,统一采用「模块.语义」短 key便于 diff 与搜索。
  • 避免在 CSS 中写死文本(如 content: "xxx"),如确有需要,应通过 JS 设置并走 i18n。
  • 对于后端返回的可本地化错误文本(未来可能支持),优先由后端根据 Accept-Language 返回对应语言,前端只负责展示。