外观
国际化
字数
3304 字
预计阅读
13 分钟
国际化(常写作 i18n)就是让同一套系统能用不同的语言显示。项目内置简体中文(zh-CN)和 English(en-US)两种语言,随时可以切换。
切换的不只是按钮和菜单:后端返回的错误信息、表单校验提示、字典、内置数据的名称、消息通知、导出的 Excel,都会跟着语言走。
这是从第一行代码起就遵守的规则:代码里不直接写中文,每一段给用户看的文字都对应一个翻译键(一个固定的名字,比如 crud.action.save),中文和英文分别写在各自的翻译文件里。自动检查会保证两种语言一条不缺。
覆盖范围
| 内容 | 切换语言后 |
|---|---|
| 界面文字 | 菜单、按钮、表格列名、提示框全部切换 |
| 后端返回的错误信息 | 服务端按请求的语言翻译好再返回,比如"数据已存在,不能重复" |
| 表单校验提示 | 浏览器里的提示和服务端返回的提示是同一套文字,提示里的字段名也会翻译 |
| 菜单名称 | 内置菜单跟着切换;管理员新建的菜单可以分别填写中文名称和英文名称 |
| 字典、参数名称 | 每个字典项、每个参数都可以分别填写各语言的文字 |
| 内置数据的名称 | 内置的角色、部门、岗位、审批流程、消息模板、定时任务等,名称跟着切换 |
| 消息通知 | 同一个模板按语言分别保存,按收件人的语言发送 |
| 登录日志 | "提示"一栏按查看人的语言显示 |
| Excel 导入导出 | 表头、字典值按当前语言输出;导入时中文表头和英文表头都能识别 |
| 第三方组件 | Element Plus 组件、日期、图表、富文本编辑器、Cron 编辑器、验证码、表单设计器的界面文字一起切换 |
| 移动端 | 同样支持中英文,在登录页和"我的"页面切换 |
哪些内容不会翻译
- 用户自己录入的内容只保存录入的那一种文字:管理员新建的角色、部门、岗位,自己设计的审批流程和节点,业务数据等,切换语言时保持原样。表单字段标题例外:在表单设计器的「国际化配置」里新增词条,分别填写中文和英文,再把字段标题绑定到这个词条,切换语言时标题就会跟着变。内置流程模板的表单就是这样做的;
- 通知公告是作者写给读者的文章,作者按读者的语言撰写,系统不做多语言;
- 定时任务执行失败时记录的错误信息,是程序的原始报错,不翻译;
- 表单设计器里"地区选择"的地区名称只有中文。
切换语言
有三个地方可以切换:
- 页头右上角的语言图标("切换语言");
- 登录、注册、找回密码、修改密码、锁屏这几个页面右上角的语言菜单;
- 个人中心的"偏好设置"里的"界面语言"。
切换后立即生效,不需要刷新页面:表单里已经填的内容不会丢,已经显示的校验提示会换成新的语言,浏览器标签上的页面标题也会跟着变。
- 浏览器会记住你的选择。第一次打开时按浏览器的语言决定:英文浏览器显示 English,其他情况显示简体中文;
- 登录后切换,会同时保存到账号里。之后系统发给你的站内信、邮件和短信通知,都使用这种语言(短信验证码除外,它跟获取验证码时页面的语言走)。在登录页上切换的语言只记在当前浏览器里;
- 用户在注册页自己注册时,注册页的语言会保存为账号的语言;
- 账号里没有保存语言的用户(比如管理员新建、之后也没切换过语言的),通知按简体中文发送。
服务端怎么判断语言
每个请求按下面的顺序决定用哪种语言,找到第一个支持的就停下:
| 顺序 | 来源 | 说明 |
|---|---|---|
| 1 | 地址里的 lang 参数 | 比如 ?lang=en-US |
| 2 | 请求头 Accept-Language | 页面发出的每个请求都会自动带上当前界面语言 |
| 3 | 账号里保存的语言 | 已登录时才有 |
| 4 | 简体中文 | 默认 |
判断时只看语言部分:英式英语 en-GB 按 English 处理,繁体中文 zh-TW 按简体中文处理。
时区
时间的显示也会照顾到用户所在的地方:
- 导出 Excel 时,时间按浏览器所在的时区输出;
- 通知里的时间按收件人的时区显示,也就是他最近一次登录时浏览器的时区;
- 都不知道时,使用参数
core.default_timezone(默认时区,默认值Asia/Shanghai),可以在 系统管理 → 参数设置 中修改。
数据库内容的多语言
数据库里的内容分两种情况处理。
菜单
- 内置菜单的名称会跟着语言切换;
- 在 系统管理 → 菜单管理 新增菜单时,"菜单名称"必填,下面还有"中文名称"和"英文名称"两栏。
显示时按这个顺序取名称:当前语言的名称 → "菜单名称"(填的是翻译键时,比如 menu.iam.user,显示它的翻译)→ "菜单名称"原样显示。所以只想要一种语言时,只填"菜单名称"就够了。
字典和参数
- 系统管理 → 字典管理:字典有"多语言名称",字典数据有"多语言标签",每种语言一个输入框;
- 系统管理 → 参数设置:参数有"多语言名称"。
字典项显示当前语言的标签;这种语言的输入框留空时,显示"字典标签"。数据里的值在字典中找不到时,直接显示这个值。参数名称也是一样:先用当前语言的名称,没填就用"参数名称"。
内置数据的名称
项目初始化时写入的角色、部门、岗位、审批流程、消息模板、定时任务、存储配置等,名称都会跟着语言切换。管理员自己新建的数据是普通文字,原样显示。
- 编辑时:打开内置数据的编辑表单,看到的是当前语言的名称。名称没改就保存,它仍然跟着语言切换;改了名称,就变成普通文字,以后不再随语言变化;
- 搜索时:按名称查询这些列表,输入中文或英文都能找到内置数据。比如在 系统管理 → 岗位管理 里搜"engineer",也能找到"开发工程师"。
消息模板
在 系统管理 → 消息中心 的"站内信模板"、"邮件模板"、"短信模板"里,每个模板都有"语言"一项:同一个模板编码,每种语言各存一个(同一编码、同一语言只能有一个)。
- 在站内信模板列表中,点某一行的 更多 → 添加翻译,会打开新增表单:编码、名称和内容从这一行复制过来,语言换成另一种,把内容翻译后保存即可;
- 发送时,按收件人账号里的语言选模板;没有这种语言的模板时用简体中文的,再没有就用任意一个启用的;
- 短信验证码(短信登录、找回密码、个人中心更换手机号)不按账号里保存的语言,而按获取验证码那次请求的语言选模板(见上面服务端怎么判断语言,一般就是当前页面的语言);
- 模板里的流程名称、节点名称、字典值等参数,也按收件人的语言显示。
Excel
- 导出:表头、字典列、内置数据的名称按当前界面语言输出,时间按浏览器的时区输出;
- 导入模板:用当前语言生成表头和字典下拉框;
- 导入:表头填中文或英文都能识别;字典列填任一语言的标签或者字典值都可以;
- 导入失败时生成的错误报告,"行号"、"错误信息"两列也按当前语言输出。
自动检查
pnpm verify 里包含一项国际化检查(pnpm i18n:check),提交代码前必须通过:
| 检查 | 说明 |
|---|---|
| 两种语言一一对应 | 每个翻译文件在另一种语言里都有一份,键完全相同;同一个键不能在两个文件里重复定义 |
| 用到的键都存在 | 前端、后端、共享包和移动端代码里写出的翻译键,两种语言都要有 |
| 代码里没有中文 | .ts 和 .vue 文件中(注释除外)不能出现中文和全角标点。翻译文件、种子数据、数据库迁移和测试不受限制 |
| 种子数据完整 | 种子里引用的菜单名、内置名称的翻译键必须存在;字典标签、参数名称必须中英文都填;每个消息模板两种语言的内容都不能为空(站内信的标题和正文、邮件的主题和正文、短信的正文) |
| 待翻译 | 英文还没翻译、暂时留空的键,会被统计为"待翻译",只提示不报错。设置环境变量 I18N_TODO_STRICT=1 后会报错 |
另外有一个测试检查:每一个错误码都有中文和英文的错误信息。
增加一种语言
目前内置中英文两种。增加第三种(比如日文 ja-JP)需要改代码,不能在后台直接添加。大致步骤:
- 在语言列表里加上新语言的代码;
- 把前端、后端、共享包和移动端的英文翻译文件各复制一份,翻译成新语言;
- 给 Element Plus、日期、图表等第三方组件配上新语言的语言包,在语言菜单里加上它的名称;
- 有几处写死了中英文两种语言,需要一起改:菜单表单的"中文名称/英文名称"、多语言输入框的校验规则、自动检查脚本等;
- 在 系统管理 → 字典管理 的"语言"字典(
core.locale)里加一项;种子里的字典标签、参数名称、消息模板补上新语言; - 运行
pnpm verify,按提示补齐缺少的翻译。
每一步要改哪些文件,见在代码中使用国际化 · 增加一种语言。
开发指南
- 在代码中使用国际化:翻译文件放在哪里、后端怎么翻译、数据库内容、自动检查和增加语言的具体做法
- 权限与翻译:在前端页面里使用翻译
- 参数校验:校验提示和字段名的翻译
- 异常处理:给新的错误码写中英文信息
- 字典、参数设置、种子与菜单:用种子预置多语言的数据
- 消息通知:按收件人的语言发送通知
- Excel 导入导出:表头和字典列的翻译
- 代码生成器:生成的模块自带中英文翻译文件