电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

多语言开发规范

来源:金蝶云社区作者:金蝶2024-09-2325

 多语言开发规范

1 总体规范

1. 【强制】为了可以利用翻译平台支持程序提示语的翻译,切忌在一个工程中包含多个苍穹应用的提示语,不同苍穹应用的提示语应该放在不同的工程中。


2. 【强制】为了正常使用多语言产品,在提交中文元数据文件时,禁止提交非中文的元数据文件



3. 【推荐】图片的多语言:原则上图片和文字需要做分离,这样在实现多语言时只要把文字抽取出来翻译。如果文字嵌入图片中则需要整个图片重新设计多语言。


多语言字段

2.1 单据设计文本类型处理

1.【强制】多语言环境下,单据设计时注意事项:文本类型的字段,有需要显示不同国家语言文字的,则应选择多语言文本控件。


2.【推荐】多语言字段勾选“通用语言“属性,可解决的问题:即使在其他语言下没有维护该语言的译文,以该语言登录云苍穹后,此字段显示为中文而不是空:

 

2.2 多语言字段设计规范

【推荐】多语言表的字段长度设置:字段长度根据业务实际情况设置,一般设置为500。

【强制如果启用了通用语言的选项,对应的物理表中会增加一个字段,此字段的类型与多语言表中的字段保持一致

【强制】多语言表主键的字段类型为VARCHAR


2.3通用多语言自定义SQL

【推荐】代码使用orm查询会自动处理通用语言字段,对于直接用sql查询多语言字段值,需要判断该字段是否开启了通用语言,然后若当前语言环境对应的值为NULL则取通用字段上的值。

 


3 预插数据

3.1 预插数据规范

【强制】预插数据中不能填写分号,如果填写了分号,在制作多语言包时,分号会被识别为两个语句而截断,导致生成的语句在执行时报错。


【强制】在使用标准产品补丁进行多语言表的数据操作时,仅限于对简体中文数据进行新增、更新或删除操作,非简体中文数据由多语言产品补丁进行处理。


程序提示语

4.1中文词条与KEY写法规范

1. 【强制】程序提示语中的中文词条写法注意。

(1)中文词条要纯正,不要汉语然后夹杂着英文符号。

(2)词条的开头和结尾除非特殊原因最好不要留空格。


2. 【强制】中文词条中不要包含\n、\r这样的转义字符,也不要包含html标签

比如,下面的中文词条:"保存成功。\n请检查这条记录。"其中包含了\n转义字符,在中文场景下加载正常,前端显示的时候会换行,然而,在其他语种下,会直接在界面上显示\n而不是换行,这是因为多语言处理的时候经过了很多步骤,包括抽取、加载、工具转换、记录进入数据库、加载记录等过程,最后加载出来的转义字符会有多余的\。如果确实需要这样的换行效果,可以使用占位符。也就是把转义字符与其他中文拆开后再连接起来。另外,html包含了<>这样的特殊字符,在后续处理的过程中会报错,所以也需要把html标签与其它中文拆开后再连接起来,改造方法与转义字符的相同。

3.【推荐】代码中只包含需要翻译的中文内容。不要包含任何的格式、转移字符、特殊符号等。有可能导致译文显示错乱。

4.【强制】资源文件中的KEY唯一(不区分大小写)
*
有些数据库对大小写不敏感,会导致潜在问题。

反例:



4.2词条拼接处理规范

1. 【强制】提示语必须是完整的句子,句子中的变量需要使用占位符替换。

通常遇到的使用场景如下:


场景1:当代码中的提示语中只包含一个需要替换的变量时,可以使用%s进行替换。


正例:

中文示例:第5条行程。

代码示例:ResManager.loadKDString("第%s条行程。", "CslScheme_6", "fi-bcm-formplugin", count)


说明:中文内容中的“5”是代码根据实际情况动态变化的,并且在这条语句中只存在一个变量需要动态替换。因此可以使用%s进行替换。


场景2:当在提示语中需要按照顺序位置替换多个参数内容时,可以使用%1$s,%2$s按顺序使用。


正例:

中文示例:第2行“价格”不能为空。


代码示例:

ResManager.loadKDString("第%1$s行“%2$s”不能为空。", "SrcPurListMustInput_1", "scm-src-common",i+1,displayName))


说明:要使用%1$s,%2$s,%3$s等这种带参数位置的占位符,而不要使用%s,因为中文的语序跟其他语种的语序可能不同,这会导致翻译不准确或者翻译错误。在这个中文示例中,“2”和“价格”会随着录入人员实际录入的情况不同而发生变化。因此需要使用2个参数来进行变量替换。这时就需要使用%1$s和%2$s来进行替换。在代码示例中i+1用来替换行数,displayName用来替换具体字段内容。


场景3:当进行页面提示时,如果使用到了表单中某一字段控件的名称时,建议通过元数据来获取该名称,并通过占位符的方式进行页面提示。这样可以保证提示语内容与字段描述一致,同时字段描述修改时,不会影响代码中提示语内容,代码无需修改。

正例:

MainEntityType dataEntityType = EntityMetadataCache.getDataEntityType("页面编码");
Map<String, IDataEntityProperty> fields = dataEntityType.getAllEntities().get("页面编码").getFields();
String username = fields.get("字段标识").getDisplayName().toString()getView().showTipNotification(ResManager.loadKDString("%s已绑定环境,不允许新增环境。","Test_0","工程标识",username);


说明:%s代替字段控件的名称



2. 【推荐】使用带参数位置的格式化形式,ResManager.loadKDString就可以满足格式化转换其他语言的需要。


正例:

代码示例:

ResManager.loadKDString("第%1$s行%2$s不能为空。", "SrcPurListMustInput_1", "scm-src-common", i,  displayName);

反例:

代码示例:

ResManager.loadKDString(String.format("第%1$s行%2$s不能为空。", i,  displayName), "SrcPurListMustInput_1", "scm-src-common");

可以使用String.format,但必须位于ResManager.loadKDString外层。


3. 更多拼接问题示例

(1)不成对双引号或单引号(含全角和半角)

反例:

ResManager.loadKDString("and函数的最终结果必须是“通过“或”不通过”。", "AndCompareCalculate_1", SYSTEM_TYPE)));


正例:

ResManager.loadKDString("and函数的最终结果必须是“通过”或“不通过”。", "AndCompareCalculate_1", SYSTEM_TYPE)));



(2)句首为冒号、顿号、逗号、全角句号、右方括号、右圆括号(含全角和半角)

反例:

errorMsg.append(number).append(ResManager.loadKDString(":存在下级资料,不允许个性化。", "BaseDataIndividualizer_6", SYSTEM_TYPE));


正例:

errorMsg.append(ResManager.loadKDString("%s:存在下级资料,不允许个性化。", "BaseDataIndividualize_6", SYSTEM_TYPE,number));



(3)句末为左圆括号、左方括号(含全角和半角)

反例:

String logStr = ResManager.loadKDString("初始化共享中心:", "WorkDateUtil_0", "ssc-task-formplugin") + centerId + ResManager.loadKDString("的工作日历(", "WorkDateUtil_1", "ssc-task-formplugin") + startDateCopy + ", " + endDateCopy + ResManager.loadKDString("),上午工作数量:", "WorkDateUtil_2", "ssc-task-formplugin")
                    + morning_workDateList.size() + ResManager.loadKDString(",下午工作数量:", "WorkDateUtil_3", "ssc-task-formplugin") + afternoon_workDateList.size() + ResManager.loadKDString(",工作日历分录dateentry:", "WorkDateUtil_4", "ssc-task-formplugin") + days;


正例:

String logStr = ResManager.loadKDString("初始化共享中心:%1$s的工作日历(%2$s,%3$s),上午工作数量:%4$s,下午工作数量:%5$s,工作日历分录dateentry:%6$s", "BaseContent_1",SYSTEM_TYPE,centerId ,startDateCopy ,endDateCopy,morning_workDateList.size() , afternoon_workDateList.size(),days);



(4)句子末尾为"从"、"但是"、"或者是、"第"

反例:

errorMsg.append(ResManager.loadKDString("优先级和时效分录第", "TaskRuleChildSave_4", "ssc-task-opplugin")).append(listSeq)
         .append(ResManager.loadKDString("行:优先级越高,设置的时效应该越小", "TaskRuleChildSave_5", SYSTEM_TYPE));

     
正例:

errorMsg.append(ResManager.loadKDString("优先级和时效分录第%s行:优先级越高,设置的时效应该越小。", "TaskRuleChildSave_4", SYSTEM_TYPE,listSeq));


4.3静态常量处理规范

1.【强制】程序提示语静态常量写法。

kd.bos.permission.formplugin.AdministratorEditPlugin


以上JAVA类的中文静态常量:

private static final String MSG_CANCEL_EDITNEWADMIN = "新增管理员未保存,是否放弃保存?";
private static final String MSG_CURADMIN_SAVEORNOT  = "当前管理员未保存,是否放弃保存?";


用转换工具处理后变成:

private static final String MSG_CANCEL_EDITNEWADMIN = ResManager.loadKDString("新增管理员未保存,是否放弃保存?", "AdministratorEditPlugin_0", "bos-permission-formplugin");
private static final String MSG_CURADMIN_SAVEORNOT  = ResManager.loadKDString("当前管理员未保存,是否放弃保存?", "AdministratorEditPlugin_1", "bos-permission-formplugin");


这样的处理,在运行时不会根据不同的登录语言返回相应的译文。

this.getView().showConfirm(MSG_CANCEL_EDITNEWADMIN, MessageBoxOptions.OKCancel,new ConfirmCallBackListener(eventInfo, this));


解决方案:增加一个获取提示语的方法:

private String getMsgCancleEditNewAdmin(){
return "新增管理员未保存,是否放弃保存?";
}


原来使用静态常量的地方修改为调用获取提示语的方法

this.getView().showConfirm(getMsgCancleEditNewAdmin(), MessageBoxOptions.OKCancel,
              new ConfirmCallBackListener(eventInfo, this));


程序提示语转换工具加工后的代码为

private String getMsgCancleEditNewAdmin(){ return ResManager.loadKDString("新增管理员未保存,是否放弃保存?", "AdministratorEditPlugin_0", "bos-permission-formplugin");
 
}


2. 【推荐】不能使用static来修饰中文静态常量,要按照推荐的方式对代码进行修改。开发完成后,可以使用多语言检查工具来进行硬编码代码检查。保证代码不存在中文硬编码问题。



4.4枚举类型处理规范

1. 【推荐】枚举类也存在与静态变量类似的问题,建议改动办法如下:

比如有这样的一个枚举类:

public enum StateEnum {
    PASS("1", "通过"),
    NOT_PASS("2", "不通过");

    private String code;
    private String name;

    StateEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}


用转换工具处理后,变成:

public enum StateEnum {
    PASS("1",ResManager.loadKDString("通过", "StateEnum_0", "helloworld")),
    NOT_PASS("2",ResManager.loadKDString("不通过", "StateEnum_1", "helloworld"));

    private String code;
    private String name;

    StateEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}


但枚举类按照Java规范也只会初始化加载一次。如果切换语言,则不会根据当前登录或显示语言加载相应的译文。

改动办法:新增一个类(类名请命名为:MultiLan

多语言开发规范

1 总体规范1. 【强制】为了可以利用翻译平台支持程序提示语的翻译,切忌在一个工程中包含多个苍穹应用的提示语,不同苍穹应用的提示语应...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信