上篇文章我们介绍了

VUE+.NET应用系统的国际化-整体设计思路

系统国际化改造整体设计思路如下:

  1. 提供一个工具,识别前后端代码中的中文,形成多语言词条,按语言、界面、模块统一管理多有的多语言词条
  2. 提供一个翻译服务,批量翻译多语言词条
  3. 提供一个词条服务,支持后端代码在运行时根据用户登录的语言,动态获取对应的多语言文本
  4. 提供前端多语言JS生成服务,按界面动态生成对应的多语言JS文件,方便前端VUE文件使用。
  5. 提供代码替换工具,将VUE前端代码中的中文替换为$t("词条ID"),后端代码中的中文替换为TermService.Current.GetText("词条ID")

今天,我们继续介绍多语言词条服务的设计和实现。

一、多语言词条设计

什么是多语言词条,即代码中需要支持多语言的文本。例如后台提示、前端界面的各类显示元素(Label、Button文字、Tooltips、标题、列表标题等等)。这些内容统一抽象为多语言词条。

多语言词条是产品多语言包的组成部分。支持在不同的语言下,显示对应的文本。

上图中:

I18NTerm代表多语言词条对象,主要描述了多语言词条的各个属性,主要的几个属性有:

        /// <summary>
/// 词条的key
/// </summary>
public string Code { get; set; } /// <summary>
/// 词条的名称
/// </summary>
public string Name { get; set; } /// <summary>
/// 原始文本
/// </summary>
public string OriginalText { get; set; } /// <summary>
/// 多语言词条子项
/// </summary>
public List<I18NTermItem> TranslateItems { get; set; } = new List<I18NTermItem>(); /// <summary>
/// 隶属的产品
/// </summary>
public string Product { get; set; } /// <summary>
/// 隶属的关键应用/系统
/// </summary>
/// <remarks>
/// 用于批量打包国际化JS文件
/// </remarks>
public string SubSystem { get; set; } /// <summary>
/// 隶属的关键应用/系统编号
/// </summary>
/// <remarks>
/// 用于批量打包国际化JS文件
/// </remarks>
public string SubSystemCode { get; set; }

一条词条,包含多个词条子项I18NTermItem,每一个词条子项,都代表了一种语言的翻译结果

 public class I18NTermItem : CacheElement
{
/// <summary>
/// 词条ID
/// </summary>
public string TermID { get; set; } /// <summary>
/// 语言
/// </summary>
public string Language { get; set; } /// <summary>
/// 翻译的文本
/// </summary>
public string TranslateText { get; set; } /// <summary>
/// 用户自定义文本
/// </summary>
public string CustomText { get; set; } public string GetText()
{
if (string.IsNullOrEmpty(CustomText))
{
return TranslateText;
} return CustomText;
}
}

 二、多语言词条管理服务

有了多语言词条对象后,需要增加其对应的多语言词条管理服务,用于对词条的增删查改

先定义一个多语言词条管理的接口II18NTermManageService

public interface II18NTermManageService
{
void Add(I18NTerm term); void Remove(string termId); void AddTerms(List<I18NTerm> terms); void RemoveTerms(List<string> terms); void Update(I18NTerm term); I18NTerm GetTerm(string termId); List<I18NTerm> GetTerms(); List<I18NTerm> GetTerms(string sourceId); List<I18NTerm> GetTermsByApplication(string applicationId); List<I18NTerm> GetTermByConditions(string applicationId, string sourceId = null, string sourceLocation = null, string Dimension1 = null, string Dimension2 = null, string Dimension3 = null); }

这个接口对应的实现中,可以采用EF完成词条数据的持久化操作,在这里不再详细展示了,大家根据需求自行实现即可。

三、多语言词条查询服务

系统在运行时,需要调用词条服务查询各类词条的翻译文本。因此,抽象一个多语言词条查询服务接口II18NTermService

    /// <summary>
/// 词条查询服务接口
/// </summary>
public interface II18NTermService
{
/// <summary>
/// 根据词条编号获取对应的词条翻译
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <returns></returns>
string GetText(string termCode, string defaultText); /// <summary>
/// 根据词条编号获取对应的词条翻译并格式化输出
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <param name="args">包含零个或多个要格式化的对象的对象数组</param>
/// <returns></returns>
string GetTextFormatted(string termCode, string defaultText, params object[] args); /// <summary>
/// 根据词条编号获取对应的词条翻译
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="language">语言标识</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <returns></returns>
string GetTextWithlanguage(string termCode,string language, string defaultText); /// <summary>
/// 根据词条编号获取对应的词条翻译并格式化输出
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="language">语言标识</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <param name="args">包含零个或多个要格式化的对象的对象数组</param>
/// <returns></returns>
string GetTextFormattedWithlanguage(string termCode, string language, string defaultText, params object[] args); /// <summary>
/// 批量获取词条,注意:此接口不能在特来电生产环境使用。
/// </summary>
/// <param name="termCodes"></param>
/// <returns></returns>
Dictionary<string,string> BatchGetText(List<string> termCodes);
}

这个接口的具体实现中,可以增加词条的Redis缓存和内存缓存,调用II18NTermManageService的实现逻辑,从数据库中查询持久化的词条数据。缓存到内存和Redis中,  以提升查询性能。

例如:

 /// <summary>
/// 获取词条翻译
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="defaultText">默认值,当找不到对应的词条时将返回默认值</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public string GetText(string termCode, string defaultText)
{
if (string.IsNullOrWhiteSpace(termCode))
throw new ArgumentNullException($"Term Code is null, {termCode}");
if (Teld.Core.Session.Service.AppContext.Current.Language == null)
{
return defaultText;
}
string language = T.Core.Session.Service.AppContext.Current.Language.DisplayCode; string key = termCode + "&" + language; if (cache.TryGetValue(key, out var val))
{
return val;
} var termItem = termManageService.GetTermItem(termCode, language); if (termItem == null)
{
TermMonitor.NotFound(termCode, language);
return defaultText;
}
else
{
string text = termItem.GetText();
cache[key] = text;
return text;
}
}

以上是多语言词条服务的设计和实现。

分享给大家

周国庆

2023/3/11

VUE+.NET应用系统的国际化-多语言词条服务的更多相关文章

  1. WPF 实际国际化多语言界面

    前段时候写了一个WPF多语言界面处理,个人感觉还行,分享给大家.使用合并字典,静态绑定,动态绑定.样式等东西 效果图 定义一个实体类LanguageModel,实际INotifyPropertyCha ...

  2. yii2 api接口 实现国际化多语言设置

    1) 在 /config/main.php 下添加如下代码: 'components' => [ 'language' => 'zh-CN', 'i18n' => [ 'transl ...

  3. Linux下获得系统时间的C语言实现

    Linux下获得系统时间的C语言的实现方法 #include<time.h> //C语言的头文件#include<stdio.h> //C语言的I/O   int main() ...

  4. iOS 国际化多语言设置 xcode7

    iOS 国际化多语言设置 方式一: 1. 在storyboard中创建好UI,然后在 project 里面  Localizables 栏目里面,添加你需要的语言:默认是Englist; 比如这里我添 ...

  5. Form_Form Builder国际化多语言开发(案例)

    2014-05-06 Created By BaoXinjian

  6. 基于Vue实现后台系统权限控制

    原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通 ...

  7. 更好用的excel国际化多语言导出

    不知道大家在开发中有没有遇到过『excel导出』的需求,反正我最近写了不少这种功能,刚开始利用poi,一行行的手动塞数据,生成excel,而且还有国际化需求,比如:标题栏有一列,用户切换成" ...

  8. [Spring]Spring Mvc实现国际化/多语言

    1.添加多语言文件*.properties F64_en_EN.properties详情如下: F60_G00_M100=Please select data. F60_G00_M101=Are yo ...

  9. iOS 学习笔记六 【APP中的文字和APP名字的国际化多语言处理】

    今天为新手解决下APP中的文字和APP名字的国际化多语言处理, 不多说了,直接上步骤: 1.打开你的项目,单机project名字,选中project,直接看图吧: 2.创建Localizable.st ...

  10. php gettext方式实现UTF-8国际化多语言(i18n)

    php gettext方式实现UTF-8国际化多语言(i18n) 一.总结 一句话总结: 二.php gettext方式实现UTF-8国际化多语言(i18n) 近 来随着i18n(国际化)的逐渐标准化 ...

随机推荐

  1. leecode编写记录

    记录leecode刷题思路 39.组合总数 39. 组合总和 - 力扣(LeetCode) 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candida ...

  2. MySQL经典45题

    一.数据库字段说明 1.学生表 Student(SId,Sname,Sage,Ssex)SId :学生编号Sname:学生姓名Sage :出生年月Ssex:学生性别 2.课程表 Course(CId, ...

  3. 简单的理解synchronized锁升级

    前言 今天碰到一个synchronized锁升级的问题, 查了查, 发现一个帖子举例说明比较贴切, 特此转发, 如有问题, 欢迎讨论说明 转自: 木叶盒子 https://www.bilibili.c ...

  4. mumu模拟器pin码忘记,如何找回

    1.进入mumu安装目录:D:\Program Files (x86)\MuMu\emulator\nemu\vmonitor\bin 2.通过cmd进入mumu的bin目录,输入命令:adb_ser ...

  5. [转]NET实现RSA AES DES 字符串 加密解密以及SHA1 MD5加密

    表明来源 https://www.cnblogs.com/shanranlei/p/3630944.html#!comments 本文列举了    数据加密算法(Data Encryption Alg ...

  6. 运行代码后出现Process finished with exit code 0

    pycharm_运行不出结果,也不报错_Process finished with exit code 0用pycharm运行程序的时候,运行不出结果 ,也不报错,且正常退出解决1:将 run → e ...

  7. Oracle存储过程 Call使用

    在 Oracle 中,可以将存储过程(PROCEDURE)定义在一个包(PACKAGE)中. 要调用包中的存储过程,需要使用包名和存储过程名来引用它们.以下是一个示例: 假设我们有一个名为 my_pa ...

  8. loadrunner 11

    1  环境windows server 2012  2019 的.net 时, 服务器管理器--仪表板--勾选.net后报错? 其中一个办法就是将服务器临时联网,就能安装成功. 2   联机时 提示如 ...

  9. 【APT】Patchwork APT组织针对巴基斯坦国防官员攻击活动分析

    前言 Patchwork(白象.摩诃草.APT-C-09.Dropping Elephant)是一个疑似具有印度国家背景的APT组织,该组织长期针对中国.巴基斯坦等南亚地区国家进行网络攻击窃密活动.本 ...

  10. Java Fastjson Unserialize WriteUp

    Java Fastjson Unserialize 题目地址: https://ctf.bugku.com/challenges/detail/id/339.html 1. 查看网页源代码 <s ...