3

VUE+.NET应用系统的国际化-多语言词条服务 - Eric zhou

 1 year ago
source link: https://www.cnblogs.com/tianqing/p/17205495.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

上篇文章我们介绍了

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

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

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

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

一、多语言词条设计

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

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

23525-20230311111259801-1338365984.png

 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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK