# 数据国际化

# 1 数据国际化真实效果

以SeeyonA8+集团版为例,先用系统管理员账号登录系统,在系统设置-系统模块管理-模块启停用-国际化-数字国际化中打开数字国际化开关,如图所示:

1714302789747.png

再重启OA系统,登录集团管理员账号,在基础功能设置-枚举管理中查看相应枚举,点击修改按钮,点击枚举名称右边的小地球图标可进行国际化资源管理:

1714302800330.png

以公共枚举时区为例,管理人员可人工修改其对应的英文和繁体中文,以对接不同企业的需求。

1714302811860.png

数据国际化同样适用于枚举值的显示,如公共枚举处理结果的枚举值“同意”,企业管理人员也可以对其进行国际化管理。

1714302827561.png

# 2 开发步骤

# 2.1 单字段设置国际化组件

数据国际化组件基于jQuery,并按照ctp标准comp组件规范实现,如果需要使用,需要按照平台【JSP开发规范】 (opens new window)引入相关文件。

# 2.1.1 页面DOM初始化

<input type="text" id="dataI18nID" name="dataI18nName"  value="8578565212478542153" class="comp"
comp="type:'dataI18n',i18nSwitch:'off',mode:1,category:'enum.name',categoryName:'枚举名称'"
validate="notNullWithoutTrim:true,notNull:true,maxLength:85"/>

# 2.1.2 jQuery插件初始化

// 应用场景二:业务js中动态拼接生成国际化input组件,在业务js中主动调用$.('#eleId').dataI18n({...})方法,即可渲染生成组件。
$.('#dataI18nID').dataI18n({
  type:'dataI18n',
  mode:1,
  category:'enum.name',
  i18nSwitch:'off',
  categoryName:'枚举名称'
}); // eleId为国际化组件id

# 2.1.3 标准comp方式渲染

var $i18nDom = $.('#dataI18nID');
$i18nDom.addClass("comp");
$i18nDom.value("8578565212478542153")
$i18nDom.attr("comp","type:'dataI18n',i18nSwitch:'off',mode:1,category:'enum.name',categoryName:'枚举名称'");
$i18nDom.attr("validate","notNullWithoutTrim:true,notNull:true,maxLength:85");
$i18nDom.compThis();

# 2.1.4 更新国际化key

// 业务代码可通过如下方法回填组件值。
$("#dataI18nID").setI18nVal("-3449671849168386491");// 传国际化表中的id
$("#dataI18nID").setI18nVal("国际化组件");// 传未国际化的值

说明 :组件生效,需要在 系统模块管理-->模块启停 功能中开启“数据国际化”开关,此开关默认为关。

# 2.2 自定义国际化事件监听

由于组件内部会将原来DOM进行替换,所以不能使用jQuery的on/bind,事件绑定使用jquery的delegate(代理)方式绑定。

__queryData__作为数据存放的对象,有i18nTitle和title两种属性,queryData.i18nTitle用来存放应用中的国际化数据,queryData.title用来存放应用中的原始数据。相应事件触发的传值在如下代码中反映:

# 2.2.1 dataChange事件

dataChange事件用于组件内部通知应用数据已经改变,方便应用做数据处理。**若使用了国际化,则触发dataChange事件,将相应数据的国际化值(i18nValue)传入相应变量的国际化属性(i18nTitle)中;若未使用国际化,则没有i18nValue这一属性,i18nTitle和title都是原始值。 **注意如果你通过JQuery中的validate插件进行校验,但规则校验不通过,组件不会保存数据同样也不会触发dataChnage事件。

$("国际化dom父元素的选择器").delegate("#i18n_dmo","dataChange", function(event,data){
 if(data.isI18n){//使用了国际化
  __queryData__.i18nTitle = data.i18nValue;
  __queryData__.title = data.value;
 }else{//未使用国际化
  __queryData__.i18nTitle = data.value;
  __queryData__.title = data.value;
 }
})

返回数据说明:

//返回数据说明
{
  "domId": "scheduledstats_title",//dom的id
  "isI18n": true,// 是否使用国际化,不使用返回false,且没有i18nValue、allLanguageValue、currentLanguage属性
  "value": "3321074866139252525",//input的值,如果使用国际化则是国际化的id,否者是input的数据
  "i18nValue": "静态报表",// 使用国际化则返回当前语种国际化的文字
  "allLanguageValue": {//全部语言的数据
    "en": "English-静态报表",
    "zh_CN": "静态报表",
    "zh_TW": "繁體中文-静态报表"
  },
  "currentLanguage": "zh_CN"//当前语种的local
}

# 2.2.2 dataBackfill事件

dataBackfill事件用于组件内部通知应用数据已经完成国际数据的化的回填并初始化,方便应用做数据处理。事件触发传值方式和上述dataChange事件相同。

$("国际化dom父元素的选择器").delegate("#indexName","dataBackfill", function(event,data){
 if(data.isI18n){//使用了国际化
  __queryData__.i18nTitle = data.i18nValue;
  __queryData__.title = data.value;
 }else{//未使用国际化
  __queryData__.i18nTitle = data.value;
  __queryData__.title = data.value;
 }
})

返回数据说明:

//返回数据说明
{
  "domId": "scheduledstats_title",//dom的id
  "isI18n": true,// 是否使用国际化,不使用返回false,且没有i18nValue、allLanguageValue、currentLanguage属性
  "value": "3321074866139252525",//input的值,如果使用国际化则是国际化的id,否者是input的数据
  "i18nValue": "静态报表",// 使用国际化则返回当前语种国际化的文字
  "allLanguageValue": {//全部语言的数据
    "en": "English-静态报表",
    "zh_CN": "静态报表",
    "zh_TW": "繁體中文-静态报表"
  },
  "currentLanguage": "zh_CN"//当前语种的local
}

# 2.3 批量设置国际化组件

上面我们讲了单字段国际化组件的设置和开发,这里通过jsonData来批量设置国际化组件,jsonData的属性说明见下表。

通过onOk方法来处理返回数据,onOk方法的相应属性见下文中的表格。

组件调用示例:

var jsonData = '['+
  '{\"name\":\"field0001\",\"text\":\"姓名\",\"maxLength\":80,\"category\":\"cap4.formmain_0025.field0001\"},'+
  '{\"name\":\"field00011\",\"text\":\"姓名\",\"title\":\"曾用名\",\"maxLength\":80,\"category\":\"cap4.formmain_0025.field00011\"},'+
  '{\"name\":\"field0002\",\"text\":\"性别\",\"maxLength\":10,\"category\":\"cap4.formmain_0025.field0002\"},'+
  '{\"name\":\"field0003\",\"text\":\"学历\",\"category\":\"cap4.formmain_0025.field0003\"},'+
  '{\"key\":\"-477759458923426020\",\"name\":\"field0004\",\"text\":\"籍贯\",\"maxLength\":50,\"category\":\"cap4.formmain_0025.field0004\"}'+
  ']';

  $.showDataI18nDialog({'jsonData':jsonData,'onOk':onOk,fieldName:"字段名称",titleName:"标题名称",showFieldColumn:true,showTitleColumn:false,callbackCheckMethod:checkI18nData});

  function onOk(data){
   console.log(data);
   /*
      *   处理返回数据
   */
  }

# 3 数据国际化属性说明

# 3.1 input属性说明

属性 必填 说明
id 自定义 不写会自动生成
name 自定义 不写会自动生成
value 编辑或初始化场景下使用。直接把应用字段的原始值赋给value即可。
readonly input的readonly值决定组件是否可用
disable input的disable值决定组件是否可用
class comp 固定值
comp 详见comp属性说明
validate 规则原组件规范一致。此validate值会影响业务表单与国际化弹出框中表单的校验。 业务表单校验说明:完全依赖业务代码。 国际化弹出框表单校验说明:1、是否进行表单校验,受comp属性中validateSwitch开关控制;2、表单校验依据此validate,空校验除外;3、组件会忽略业务中设置的空校验规则;组件自身重置空校验规则,默认语言与当前语言不能为空,其它语言可为空。
onblur 不建议使用,建议使用dataChange事件,blur事件存在调用先后顺序问题,组件内部无法确认组件优先被调用1.直接在input元素上添加事件 onblur="javascript:console.log('失去焦点!');" 2.js绑定时建议使用on绑定事件,可以让多次绑定的函数都执行$("#dataI18nID").on('blur',function () {// 业务代码})
onclick等事件 可自定义各类事件
data-i18n 该值由组件回填(true/false) 标识此字段的值是否进行了国际化。组件渲染完或国际化弹出框点击确定按钮后更新此属性的值
data-allLanguageValue 该值由组件回填 所有语言的值,json格式的字符串,例:{"en":"english Value","zh_CN":"中文","zh_TW":"繁體"}

# 3.2 comp属性说明

属性 必填 说明
type dataI18n 固定值
model 1 暂时未用到,建议先设置为1。1表示使用弹出对话框单一录入模式
category 标识应用分类,命名规范为应用分类+模块标识+Input的名称,至少三级,以点分隔,不允许重复。如枚举管理-枚举名称,category为global.enum.name。(category为以后清理无引用数据的重要依据,请务必填写)
categoryName 编辑的字段名称,国际化页面提示使用。
i18nSwitch on/off 是否国际化。暂时使用,是否保留待定。
validateSwitch on/off 国际化弹出框中是否做校验。
checkI18nData 0/1 是否进行业务逻辑校验. 如果设置了需要进行校验(checkI18nData:1),需要同时在页面上定义js方法:function callBackCheckI18nData(i18nData,callback,param)来进行业务逻辑校验,同时在校验成功后调用回调函数保存国际化数据。

checkI18nData国际化数据校验示例:

/**
*1.i18nData:设置的国际化数据,json格式,如 {"zh_CN":"1","en":"1","zh_TW":"","validate":true,"id":"8444155350495150826","category":"organization.account.name","currentLocale":"zh_CN"}
*2.callback:保存国际化数据的回调函数。
*3.param:保存国际化数据的回调函数参数。
*/
function callBackCheckI18nData(i18nData,callback,param){
    var id = $("#id").val();
    var action = id === '-1' ? 'add' : 'update';
    // 业务数据逻辑校验
    oManager.checkNameI18nData(i18nData,action, id,null,{
        success: function(msg) { 
     if(msg != ''){
  $.alert(msg);
     }else{
         // 逻辑校验成功,必须手动调用回调函数保存国际化数据
  callback(param);
     }
        }
      });
}

# 3.3 jsonData属性说明

属性 必填 说明
name 页面字段的唯一标识(表单控件的名称或者input框的id,自行设置)
text 字段名称
title 字段标题(text相同的情况下用于区分字段,缺省值为text。)
categoryName 类别(规则:应用组名称.业务名称.字段名称。(规则按具体要求处理,保证分类唯一,易懂)key:对应存储的国际化id。新增时为空,更新时必填。)
maxLength 字段最大长度(缺省为数据库最大长度500)
key 对应存储的国际化id,新增时为空,更新时必填。

# 3.4 非必要设置属性说明

属性 必填 说明
fieldName 自定义的字段名称
titleName 自定义的标题名称
showFieldColumn true/false 是否显示列(缺省显示)
showTitleColumn true/false 是否显示列(缺省显示)
callbackCheckMethod 保存数据前的回调校验函数

callbackCheckMethod 国际化数据校验示例

/**
*1.content:校验数据
*2.callbackSaveMethod:回调函数
*/
function checkI18nData(content,callbackSaveMethod){
    // 业务数据逻辑校验
    oManager.checkNameI18nData(content,{
        success: function(msg) { 
     if(msg != ''){
  $.alert(msg);
     }else{
         // 逻辑校验成功,必须手动调用回调函数保存国际化数据
  callbackSaveMethod();
     }
        }
      });
}

# 3.5 onOk方法说明

数据保存成功后的回调函数。 data数据格式:

[
{"name":"field0001,"text":"姓名","key":"8475457947599485074"},
{"name":"field0002,"text":"籍贯","key":"-790375975930503570"}
]
属性 说明
name 和传入的name一致,(表单控件的名称或者input框的id)。
text 返回编辑过的当前语种的名称。
key 国际化的id。

# 数据国际化(后端)

# 背景&需求

需要对系统某个地方的展示适配国际化,涉及到的后端开发

# 操作步骤&解决方案

下面以用户名称的国际化作为示例

前端已经实现了国际化的配置 1719990961002.png

1719990984152.png

# 第一步:

配置态适配:

1、后端需要在数据库表新增字段

1719991175478.png

2、并给对象新增字段i18nNameId

1719991108133.png

3、修改保存数据接口

在保存的时候,前端会传一个long类型的i18nNameId过来,入库存入数据库

4、修改查询接口,新增i18nNameId字段查询返回,方便前端根据id回填已配置的国际化值

# 第二步:

运行态适配:

1、修改展示接口,对从数据库的查询接口进行特殊处理,对原来的name字段进行单独重新赋值

1719991406843.png

重新设置,通过以下代码取国际化值

ResourceUtil.getString(i18nNameId);

1719991462041.png

返回的值会自动根据当前环境语言,来返回对应的值,适配完成

编撰人:het、zhangzuh、admin