• .NET应用系统的国际化-多语言词条服务


    上篇文章我们介绍了

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

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

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

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

    一、多语言词条设计

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

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

     上图中:

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

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

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

    复制代码
     public class I18NTermItem : CacheElement
        {
            /// 
            /// 词条ID
            /// 
            public string TermID { get; set; }
    
            /// 
            /// 语言
            /// 
            public string Language { get; set; }
    
            /// 
            /// 翻译的文本
            /// 
            public string TranslateText { get; set; }
    
            /// 
            /// 用户自定义文本
            /// 
            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 terms);
    
            void RemoveTerms(List<string> terms);
    
            void Update(I18NTerm term);
    
            I18NTerm GetTerm(string termId);
    
            List GetTerms();
    
            List GetTerms(string sourceId);
    
            List GetTermsByApplication(string applicationId);
    
            List GetTermByConditions(string applicationId, string sourceId = null, string sourceLocation = null, string Dimension1 = null, string Dimension2 = null, string Dimension3 = null);
    
        }
    复制代码

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

    三、多语言词条查询服务

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

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

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

    例如:

    复制代码
     /// 
            /// 获取词条翻译
            /// 
            /// 词条编号
            /// 默认值,当找不到对应的词条时将返回默认值
            /// 
            /// 
            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

     

  • 相关阅读:
    图详解第六篇:多源最短路径--Floyd-Warshall算法(完结篇)
    21年-外包-面试题
    字节跳动数据中台的 Data Catalog 系统搜索实践
    Bigemap 在土地图利用环境生态行业中的应用
    hbuilderx ios自定义基座真机测试
    python+opencv读取rtsp流
    DP/typec转VGA(国产化,工业级)
    Request failed with status code 422
    突破瓶颈,火力全开!揭秘六西格玛管理培训公司如何助你一臂之力
    K8S部署时IP问题
  • 原文地址:https://www.cnblogs.com/tianqing/p/17205495.html