国际化开发及配置

平台支持国际化(多语言),对于平台提供的应用,分别提供了中文简体、中文繁体和英文等三种语言。

中文简体界面

中文繁体界面

英文界面

开发多语言应用

开发多语言应用的步骤如下

  1. 正常开发应用
  2. 修改js文件,将中文替换为多语言函数
  3. 使用系统工具
    1. 检测并替换多语言表达式
    2. 扫描生成资源文件
    3. 填入语言资源
    4. 开启多语言

开启多语言

开启多语言,参考《开启多语言、设置当前语言》一节。开启多语言后,门户右上角会显示语言切换图标,系统默认显示三种语言,如需添加其它语言,在开启多语言配置中添加。用户登录后默认使用设置的语言,也可以通过门户右上角的语言切换图标切换语言。

一些常用内容,系统已经翻译,在语言资源文件中无需再翻译

在 JS 文件中使用多语言函数

JS 文件中使用的多语言函数是:this.i18n("中文内容",import.meta.url),替换的作用有两个

  1. 系统扫描 JS 文件时,会将多语言函数中的中文内容生成到资源文件中
  2. 运行时,将中文内容替换为资源文件中的语言内容

例如将“提示”替换为多语言函数,代码如下

    title: '提示'

改为

    title: this.i18n('提示',import.meta.url)

JS文件中通过请求获取多语言信息,平台请求request已集成语言设置,可直接使用。

let onButton2Click = async(event) => {
    /**
     * 特别注意:这里一定要使用平台自带的请求方法request。如果你用其他的请求方式,例如fetch,axios等,需要在请求头中新增accept-language用来定义请求语言
     */
    let {data}=await $page.request({url:"$serviceName/main/i18n/getlanguageinfo"});  
    message.info(JSON.stringify(data));
}

图 6

如果要使用第三方请求方法,例如fetch,axios等,需要在请求头中新增“accept-language”来定义请求语言,以fetch为例

/**
 * 使用第三方请求,获取多语言资源
 * @param {*} event 
 * @returns 
 */
let onThirdBtnClick = async(event) => {
    const pageData=$page.comp("pageData")
    let currentData=pageData.getCurrentRow();
    if(!currentData.key||!currentData.language){
        message.error("语言及语言key不能为空");
        return;
    }
    const response=await fetch(`/main/i18n/test?key=${currentData.key}`,{headers:{"accept-language":currentData.language}}); 
    let data=await response.text();
    pageData.setValue("txt",data);
}

在 Java 文件中使用多语言函数

Java 后端资源文件需要按需新建(系统不会自动生成),统一放在到 "$$model/service/service-meta-info/src/main/resources/i18n" 目录下,语言资源路径规范:$model/service/service-meta-info/src/main/resources/i18n/语言/resource.json

图 7

在后端使用多语言需要引用 I18nResourceLoader 类,通过使用 i18n 方法进行内容翻译

图 3

I18nResourceLoader类常用方法

public String i18n(String key) throws ExecutionException
public String i18n(String key, String languageId) throws ExecutionException
描述:通过指定语言获取key对应的语言资源
参数:
    key         语言请求内容
    languageId  语言(zh-CN/en-US等),默认从请求(accept-language)中获取
返回:
    指定语言对应的资源

后端获取语言相关信息,可以在 controller 上新增 Locale 参数,然后在具体服务中使用,也可以在服务类下直接使用 SpringWebUtil.getRequest().getLocale() 获取

public String getLanguageInfo(Locale locale) throws Exception {
    JSONObject obj=new JSONObject();
    obj.put("displayLanguage", locale.getDisplayLanguage());
    obj.put("language", locale.getLanguage());
    obj.put("displayCountry", locale.getDisplayCountry());

    //从当前请求中获取Locale
    Locale localeReq=SpringWebUtil.getRequest().getLocale();

    //从当前请求中获取语言id
    obj.put("languageId", SpringWebUtil.getRequest().getLocale().toLanguageTag());
    return obj.toJSONString();
}

图 4

图 5

模型的多语言配置

在 IDE 中,点击右上角的齿轮图标,弹出下拉菜单。点击多语言配置菜单,打开多语言配置对话框。

系统默认三种语言,点击语言选项按钮,修改语言选项。

前端多语言配置

选择桌面端,依次点击检测并替换多语言表达式、扫描生成资源文件、开启多语言等三个按钮。系统自动扫描桌面端(UI2/pcx 目录)下的 w 和 js 文件,将其中的中文内容生成到资源文件中。

  • 系统检查 w 文件时,对其中可作为语言资源的内容,增加多语言函数,例如 text="操作"被替换为 text="{$page.i18n('操作')}"
  • 系统扫描 w 和 js 文件时,将其中多语言函数的第一个参数生成到语言资源文件中

生成后,展开左侧的资源树,可以看到系统扫描出的 w 和 js 文件,点击某个文件,切换语言,右侧表格中显示出该语言的语言资源。在“值”列中输入该语言资源,

可以通过点击新建键值按钮,添加新的键值。例如数据集的必填提示和约束提示,就需要手工添加相应的语言资源。

每个端每种语言对应一个资源文件,桌面端生成的语言资源文件为 UI2/pcx/i18n/语言/resource.json

后端多语言配置

选择后端,点击扫描生成资源文件按钮。系统自动扫描后端(service/main 目录)下的 data.m 文件,将其中的中文内容生成到资源文件中。

生成后,展开左侧的资源树,可以看到系统扫描出的数据集,点击某个数据集,切换语言,右侧表格中显示出该语言的语言资源。在“值”列中输入该语言资源,

每个端每种语言对应一个资源文件,后端生成的语言资源文件为 service/service-meta-info/src/main/resources/i18n/语言/resource.json

系统翻译规则

运行时语言资源经过一些处理,会合并为一个 JSON 对象,在浏览器的控制台中,输入 getCurrentReactPage().getCurrentLanguage() 即可看到

  • 数据集(data.m)的资源会生成到服务名下
  • 前端多语言函数 i18n 的查找顺序是,先通过精确路径查找,如果没找到,再找服务名下的资源,如果还没找到,直接找根下的资源
  • 精确路径规则为:/服务名+/所在页面端访问路径+文件详细路径(支持.w 及.js 文件)

例如:控制台中的“租户管理”页面地址为:/pcx/tenants/adminTenants.w,对应的精确路径为:/consoleui/pcxapp/pcx/tenants/adminTenants.w,统一通用配置中的多语言配置如下:

{  
    "/consoleui": {
        "/pcxapp": {
            "/pcx": {
                "/tenants": {
                    "/adminTenants.w": {
                        "添加租户": "添加空间",   
                        "租户设置": "空间设置"
                    }  
                }
            }
        }
    }
}

所在页面端访问路径可以在云 IDE 下高级,多模块多端配置下找到,pcx 端的访问路径是 pcxapp

图 0

  • 后端服务只支持精确路径查找,路径规则:/服务名+/service+请求地址+":"+请求类型(默认类型为get)

例如:企业门户中的菜单请求服务 url 为:/manager/authorized/menus,对应的后端服务精确路径为:/entry/service/manager/authorized/menus:GET,统一通用配置中的多语言配置如下:

{  
    "/entry": {
        "/service": {
            "/manager": {
                "/authorized": {
                    "/menus:GET": {
                        "title": {
                            "租户管理": "空间管理",
                            "租户统计": "空间统计",
                            "我的租户": "我的空间",
                            "租户申请": "空间申请",
                            "租户变更申请": "空间变更申请"
                        }
                    }
                }
            }
        }
    }
}
  • 数据集(data.m)的资源建议定义在后端资源文件中,在所有使用到该数据集的 w 文件中都不用再定义
  • 运行时,会将“键”里面的内容替换为“值”里面的内容进行显示。当“值”为空时,会显示“键”里面的内容
  • 数据集的必填提示和约束提示,需要手工添加相应的语言资源
  • 资源内容中不是静态的,需要显示上下文中的变量,做法如下

  • 在资源内容中使用 {} 表示参数,例如下面的代码中使用了两个参数:{begin}和{end}

      "确认将{begin}至{end} 期间已结束的任务归档?": "Confirm to archive the completed tasks from {begin} to {end}?",
  1. 在 js 文件中,先进行资源替换,再给参数赋值,代码如下
      tipsTxt = this.i18n("确认将{begin}至{end}期间已结束的任务归档?",import.meta.url);
      tipsTxt = wx.String.stringFormatByKey(tipsTxt, {"begin":begin,"end":end});
  • 当资源内容中包括 > 和 : 等特殊字符,系统不能找到对应的语言资源时,需要对语言内容执行 md5(32位 小写),作为键的值。例如中文内容为:以 fn: 开头定义 js,语言资源应写成
   "718e5376e126f3ebece6a3c083490da8": "Define JavaScript starting with fn:",

其中 718e5376e126f3ebece6a3c083490da8 为“以fn:开头定义js”md5 后的值

  • 数据集组件提供了加载数据前事件,事件参数 event.data 是要加载的数据,此时可修改 event.data,最终数据集会将 event.data 加载到数据集中。可以使用此特性对一些需要翻译的数据进行翻译。步骤如下:

静态数据集 channelData 中 name 列里面的中文需要翻译

<wx:tableData id="channelData" idColumn="id" type="custom" >
    <column id="default66" label="id" name="id" type="String"/>
    <column id="default67" label="name" name="name" type="String"/>
    <data id="default68" >[![CDATA[[{"id":"portal","name":"门户"},{"id":"email","name":"邮件"},{"id":"dingtalk","name":"钉钉"},{"id":"wx","name":"企业微信"},{"id":"sms","name":"短信"}]]]](!%5BCDATA%5B%5B%7B%22id%22:%22portal%22,%22name%22:%22%E9%97%A8%E6%88%B7%22%7D,%7B%22id%22:%22email%22,%22name%22:%22%E9%82%AE%E4%BB%B6%22%7D,%7B%22id%22:%22dingtalk%22,%22name%22:%22%E9%92%89%E9%92%89%22%7D,%7B%22id%22:%22wx%22,%22name%22:%22%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%22%7D,%7B%22id%22:%22sms%22,%22name%22:%22%E7%9F%AD%E4%BF%A1%22%7D%5D%5D%5D)</data>
(/wx:tableData)

在 channelData 的加载数据前事件中,调用 jsonI18n 方法翻译要加载的数据。注意为了使用当前 js 的语言资源,i18n 方法必须使用当前 js 里面的。js 代码如下

onChannelDataBeforeLoad = (event) => {
    this.i18nFn = (key) => {
        return this.i18n(key, import.meta.url);
    }
    wx.String.jsonI18n(event.data, ["name"], this.i18nFn);
}

如果页面上有多个数据集需要翻译,可以将 this.i18nFn 定义到 constructor 方法中,代码如下

constructor(props, context) {
    super(props, context);
    this.i18nFn = (key) => {
        return this.i18n(key, import.meta.url);
    }
}

服务的多语言配置

系统提供对服务返回结果和报错信息的翻译能力,例如门户功能树就是对服务返回结果的翻译。

翻译服务返回结果

  • 定义一个服务,GET 请求,在服务中返回 JSON 字符串数据
public String returnInfo() throws Exception {
  JSONObject ret = new JSONObject();
  ret.put("message", "这是服务返回信息");
  return ret.toJSONString();
}
  • 在 js 中调用这个服务,获取服务返回的 JSON 数据
try{
  let ret = await this.request({
    url:"$serviceName/main/fuwu/returninfo"
  })
  message.info(ret.data.message);
}catch(e){
  message.error(e.data.message);
}
  • 在后端的语言资源文件中添加服务返回结果的语言资源
{
  "$service": {
    "/main": {
      "/fuwu": {
        "/returninfo:GET":{
          "message":{
            "这是服务返回信息": "This is service return info"
          }
        }
      }
    }
  }
}
  • 运行效果

翻译服务报错信息

  • 定义一个服务,在服务中返回404
public String returnError() throws Exception {
  throw new BaseRuntimeException(HttpStatus.NOT_FOUND.value(),"这是服务报错信息");
}
  • 在 js 中调用这个服务,获取异常信息
try{
  let ret = await this.request({
    url:"$serviceName/main/fuwu/returnerror"
  })
  message.info(ret.data.message);
}catch(e){
  message.error(e.data.message);
}
  • 在后端的语言资源文件中添加服务报错信息的语言资源
{
  "$service": {
    "@error": {
      "message": {
        "这是服务报错信息": "This is service error info"
      }
    }
  }
}
  • 运行效果

功能树的多语言配置

上面配置的内容都是页面内的语言资源,对于显示到门户功能树上的菜单的语言资源,需要在统一通用配置中的多语言配置中配置,如下图所示。

其中/entry/manager/authorized/menus:GET 是获取菜单的请求

    {
        "/entry": {
            "/service": {
                "/manager": {
                    "/authorized": {
                        "/menus:GET": {
                            "title": {
                                "订单(多语言)": "Order(International)"
                            }
                        }
                    }
                }
            }
        }
    }

运行效果

开启多语言配置

系统默认不开启多语言,在企业门户中开启多语言。访问企业门户,打开统一通用配置,有三个多语言相关配置,分别是:开启多语言、当前语言、多语言配置。

开启多语言

开启多语言:在这里开启多语言和设置系统支持的语言

设置当前语言

当前语言:打开统一按组织配置,可以按组织设置当前语言

系统标题的多语言配置

打开统一通用配置,先设置系统名称和登录页标题,再设置语言资源。

  • 在门户配置中设置系统名称

  • 在登录配置中设置登录页标题

  • 在移动端登录配置中设置登录页标题

  • 在多语言配置中,配置某种语言的语言资源,一种语言对应一个配置项

其中 /entry/config/config/getconfig:GET 是获取统一通用配置的请求

    {
        "/entry": {
            "/service": {
                "/config": {
                    "/config": {
                        "/getconfig:GET":{
                            "loginTitle":{
                                "登录": "Login",
                                "欢迎": "Welcome"
                            },
                            "sysName":{
                                "系统": "System"
                            }
                        }
                    }
                }
            }
        }
    }

运行效果

页面文字的多语言配置

找出页面的路径

在浏览器中打开页面,地址栏里面会显示页面路径。例如打开组织管理页面后,地址栏里面的地址为

http://域名/entry/pcxapp/#/entry/pcxapp/pcx/index#/entry/opm-mobileapp/opm-mobile/org

第二个#后面的路径即为页面的路径:/entry/opm-mobileapp/opm-mobile/org 是桌面端页面,实际路径是:/entry/opm-pcxapp/opm-pcx/org.w 属于企业门户应用 entry,IDE 中的路径是:/UI2/opm-pcx/org.w

找到资源文件

打开企业门户应用的 IDE,找到 /UI2/opm-pcx/i18n 目录,这个目录下一般包括3个语言目录,中文简体:zh-CN、中文繁体:zh-TW、英语:en-US。在语言目录下是资源文件 resource.json。在资源文件中找到页面中资源的定义,如下图所示

1719831379717

添加多语言配置

在多语言配置中,逐级写出页面路径,在页面下写出语言资源,如下图所示

图 9

配置完成后,刷新页面查看配置效果,如下图所示

图 7

定义公共语言资源

如果多个页面,需要设置统一的语言资源,可以将语言资源直接定义到根下。下面以控制台门户将“租户”替换为“空间”为例说明

在多语言配置中,页面上统一使用的语言资源直接写在根下,后端服务的语言资源还是写到精确位置下,如下图所示

{
    "租户名称或编码": "空间名称或编码",
    "租户": "空间",
    "租户名称": "空间名称",
    "租户编码": "空间编码",
    "租户编辑": "空间编辑",
    "租户账号": "空间账号",
    "查看租户账号": "查看空间账号",
    "添加租户": "添加空间",
    "租户设置": "空间设置",
    "租户组织": "空间组织",
    "/entry": {
        "/service": {
            "/manager": {
                "/authorized": {
                    "/menus:GET": {
                        "title": {
                            "租户管理": "空间管理",
                            "租户统计": "空间统计",
                            "我的租户": "我的空间",
                            "租户申请": "空间申请",
                            "租户变更申请": "空间变更申请"
                        }
                    }
                }
            }
        }
    }
}

配置完成后,刷新页面查看配置效果,如下图所示

图 10

特别说明

  • 前端多语言配置支持根节点及精确路径定义
  • 后端服务只支持精确路径定义

总结,根据需要,页面的语言资源,即可以定义在页面的精确路径下,也可以定义在根下;后端请求的语言资源,必须定义在请求的精确路径下。示例代码如下

{
    "租户名称或编码": "空间名称或编码",
    "租户": "空间",
    "租户名称": "空间名称",
    "租户编码": "空间编码",
    "租户编辑": "空间编辑",
    "租户账号": "空间账号",
    "查看租户账号": "查看空间账号",
    "/consoleui": {
        "/pcxapp": {
            "/pcx": {
                "/tenants": {
                    "/adminTenants.w": {
                        "添加租户": "添加空间",   
                        "租户设置": "空间设置"
                    }  
                }
            }
        }
    },
    "/entry": {
        "/service": {
            "/manager": {
                "/authorized": {
                    "/menus:GET": {
                        "title": {
                            "租户管理": "空间管理",
                            "租户统计": "空间统计",
                            "我的租户": "我的空间",
                            "租户申请": "空间申请",
                            "租户变更申请": "空间变更申请"
                        }
                    }
                }
            }
        },
        "/pcxapp": {
            "/pcx": {
                "/index.HeaderAvatar.js": {
                    "租户组织": "空间组织"
                }
            }
        }
    }
}

results matching ""

    No results matching ""