FForm Platform
enzh-CN

国际化

通过稳定消息 key、本地化 metadata 和支持替换表达式的运行时文本建立双语或多语 FormPlatform 界面。

国际化(i18n)

FormPlatform 客户端的系统文字使用稳定 key,而不是把某种语言直接写在 Vue 模板或系统表单定义中。客户端加载当前 locale 的消息字典,`t(key)` 返回翻译;找不到翻译时保留可诊断的 key 或约定的 fallback,而不是静默替换成错误语言。

新增系统文字

1. 选择领域化 key,例如 `cms.media.upload`、`survey.dashboard.status.completed`,不要使用含糊的 `save2`。

2. 在 `ClientApp/src/i18n.js` 的英文和中文消息中同时添加值。

3. Vue/SFC 使用 `t('key')`;表单 schema 的 Label、Header、Menu Title 等使用 `@key`。

4. 服务端返回 `messageKey`、可选 parameters 和英文 fallback;客户端统一翻译,不应由服务端根据浏览器语言拼接业务句子。

5. 为扩展模块调用 `api.registerMessages(namespace, { en: {...}, 'zh-CN': {...} })`,并让所有模块消息处于自己的 namespace。

表单显示名和描述

表单自己的 `displayName`、`description` 可以直接在 **表单设置 / Action Code**

中维护各语言译文。基础文字仍在顶层,语言覆盖保存在同一表单定义的

`translations` 中:

{
  "name": "Acme_Customer",
  "displayName": "Customer registration",
  "description": "Register a customer",
  "translations": {
    "zh-CN": {
      "displayName": "客户登记",
      "description": "登记客户资料"
    }
  }
}

语言覆盖是作者文字,不需要也不应增加 `@`;即使译文写成 `@common.save`,也会

原样显示。当前语言缺少某个字段时,按字段回退到顶层基础文字。表单列表、Form

Center、Submission Center、问卷卡片和管理选择器都会读取这些覆盖;技术表单名

`name` 仍是不可翻译的稳定标识。关系存储把覆盖保存在

`form_definitions.translations_json`,文件/内存存储把它保存在同一个定义对象中,

因此删除表单会同时删除这些译文,不会在运行时目录中留下孤儿。

共享的平台或模块固定词条仍可在顶层基础文字中使用显式 `@key`,例如

`"displayName": "@form.SystemHeader.displayName"`。未加 `@` 的基础文字始终作为

字面量且不查询目录;系统不兼容未加 `@` 的 `form.*` 值。已经手工放入

`FormPlatform.I18n` 的表单专属旧 key 不会自动迁移或删除,因为平台无法判断该 key

是否还被其他表单复用;复制到表单定义并验证后,应由目录管理员明确清理。

动态内容

CMS 的中英文页面不是同一个字符串的机器翻译:它们是独立内容记录,以相同 Translation key 关联。因此 slug、SEO、正文、导航和图片替代文字均可按语言优化。普通用户数据不应被自动翻译;其显示语言由业务数据模型和表单设计决定。

业务表单控件翻译

问卷和其他业务表单的原始文字仍保存在控件的普通属性中。控件属性弹窗提供 **翻译(Translations)** 页签:选择目标语言(例如 `zh-CN`)后,可直接编辑 Label、Placeholder、普通文字、标题、按钮文字、Tooltip 标题和内容、必填及自定义校验消息,以及静态选项、菜单项、分页/标签页和表格列等 schema 集合中的显示文字。

保存控件和表单时,设计器会自动把翻译写入 `component.translations[locale]`。某个翻译输入框留空时,不保存该项覆盖,运行时自动回退到控件原文。“清除此语言”只删除当前控件所选语言的覆盖,不会修改原文或其他语言。

翻译页签只允许编辑展示文字。选项值、ID、Property Name、代码、URL、数据映射和静态业务数据行不会显示在该页签,也不会被翻译覆盖。例如静态选项会把稳定的 `value` 作为匹配标识:

{
  "props": {
    "options": [
      { "text": "Active", "value": "active" }
    ]
  },
  "translations": {
    "zh-CN": {
      "props": {
        "options": [
          { "value": "active", "text": "启用" }
        ]
      }
    }
  }
}

运行时按 `id`、`value`、`field` 等稳定标识把集合译文合并到原集合。只有每个原始成员都有非空稳定标识时才采用标识合并;否则设计器生成位置数组。稳定标识在同一原集合中应保持唯一。集合的成员和顺序仍由原控件定义决定,提交值不会改变。为兼容已有手写 schema,不含稳定标识的旧式翻译数组仍按位置合并。

业务表单控件的翻译不需要在 `ClientApp/src/i18n.js` 中新增系统词条,也不需要重新编译主应用;修改表单定义并保存即可生效。平台自身的固定 UI 文案仍应使用稳定 i18n key。

属性面板界面文字

Designer 属性面板中的字段名、分组标题、选项显示名、帮助文字、无障碍标题和自然语言占位符属于平台固定界面,不属于表单内容。它们必须调用 `t(...)`,并在 `ClientApp/src/i18n.js` 中同时提供 `en` 和 `zh-CN` 词条。该规则覆盖 General 页签的全部区域,包括搜索框、按钮、菜单、表格、DataGrid、图片及布局容器的细致外观设置。动态选项继续保存稳定的 schema 值,只翻译用户看到的选项名。

CSS 声明、Tailwind 类、日期格式 token、URL、JSON、表达式、组件 ID 和 Data Model 名称等可执行或结构化示例不得翻译。新增 General 页签设置时,只有在中英文目录都加入其界面文字后才算完成;表单作者输入的控件文字应写入 `component.translations`,不能混入平台固定目录。

Events 页签遵守相同规则。说明文字、参数编辑器、目标控件、按钮、占位符和内置事件显示名使用 `events.*` 固定目录;显示名旁边的事件技术名称(例如 `onChange`)以及 Action 函数名或 Action 链标识永不翻译。第三方事件会自动查找 `events.<事件名称>`,找不到时回退到事件注册时提供的 label,因此扩展可以通过自己的运行时消息目录翻译显示名,而不改变事件协议。

验证

切换语言后应检查菜单、系统表单名称/描述、toast、DataGrid、组件属性、服务端错误、客户端扩展消息及公开 CMS 页面。新增公共 API 错误时,确保返回 `PlatformErrorResponse` 和稳定 `messageKey`。

English edition: INTERNATIONALIZATION.md.