net9 abp vnext 多语言通过数据库动态管理

通过数据库加载实现动态管理,用户可以自己修改界面显示的文本,满足国际化需求

如图所示,前端使用tdesign vnext

新建表TSYS_Localization与TSYS_LocalizationDetail

国旗图标下载网址flag-icons: Free Country Flags in SVG

在Shared下创建下图3个文件

 [Table("TSYS_LocalizationDetail")]public class LocalizedResource{public long Id { get; set; }public long CultureId { get; set; }        [FreeSql.DataAnnotations.Navigate(nameof(CultureId))]public virtual LocalizedCulture? Culture { get; set; }public string Type { get; set; }public string Key { get; set; }public string Value { get; set; }public string Enable { get; set; }public DateTime CreationTime { get; set; }[FreeSql.DataAnnotations.JsonMap]public ExtraPropertyDictionary ExtraProperties { get; set; } = new ExtraPropertyDictionary();//public string LocalizedCultureName { get; set; }public LocalizedString GetLocalizedString(string cultureName){return new LocalizedString(Key, Value);}}[Table("TSYS_Localization")]public class LocalizedCulture{private string isDefault;public long Id { get; set; }        public string Culture { get; set; }public string CultureName { get; set; }public string Icon { get; set; }public bool IsDefault { get => isDefault == "Y" ? true : false; set => isDefault = value ? "Y" : "N"; }}
public static class DatabaseLocalizationExtensions
{public static LocalizationResourceBase AddDatabase([NotNull] this LocalizationResourceBase localizationResource, string resourceName){Check.NotNull(localizationResource, nameof(localizationResource));localizationResource.Contributors.Add(new DatabaseLocalizationResourceContributor(resourceName));return localizationResource;}
}
 public class DatabaseLocalizationResourceContributor : ILocalizationResourceContributor{private IFreeSql _freeSql;private readonly string _resourceName = null;public bool IsDynamic => false;private Dictionary<string, Dictionary<string, LocalizedString>> _resources = new Dictionary<string, Dictionary<string, LocalizedString>>();public DatabaseLocalizationResourceContributor(string resourceName = null){_resourceName = resourceName;}public void Initialize(LocalizationResourceInitializationContext context){_freeSql = context.ServiceProvider.GetRequiredService<IFreeSql>();var cultureName= CultureInfo.CurrentCulture.Name;if (cultureName!=null){var dic = _freeSql.Select<LocalizedResource>().Include(t => t.Culture).Where(t => t.Culture.Culture == cultureName).ToDictionary(t => string.IsNullOrEmpty(t.Type) ? t.Key : $"{t.Type}.{t.Key}", t => new LocalizedString(t.Key, t.Value));if (dic.Count>0){_resources.Add(cultureName, dic);}}            }public LocalizedString GetOrNull(string cultureName, string name){if (!_resources.ContainsKey(cultureName)){var dic = _freeSql.Select<LocalizedResource>().Include(t => t.Culture).Where(t => t.Culture.Culture == cultureName).ToDictionary(t => string.IsNullOrEmpty(t.Type) ? t.Key : $"{t.Type}.{t.Key}", t => new LocalizedString(t.Key, t.Value));if (dic.Count > 0 && !_resources.ContainsKey(cultureName)){_resources.Add(cultureName, dic);}}if (_resources.ContainsKey(cultureName) && _resources[cultureName].ContainsKey(name)){return _resources[cultureName][name];}else{if (!_freeSql.Select<LocalizedResource>().Any(t => t.Key == name)){var localization = _freeSql.Queryable<LocalizedCulture>().ToList();List<LocalizedResource> localizedResources = new List<LocalizedResource>();foreach (var item in localization){LocalizedResource localizedResource = new LocalizedResource();localizedResource.Id = YitIdHelper.NextId();localizedResource.Key = name;localizedResource.CultureId = item.Id;localizedResource.Value = name;localizedResource.Type = "";localizedResource.CreationTime = DateTime.Now;localizedResource.Enable = "Y";localizedResources.Add(localizedResource);}_freeSql.Insert<LocalizedResource>(localizedResources).ExecuteAffrows();}                if (cultureName.StartsWith("zh")){                 return new LocalizedString(name, name);}else{return new LocalizedString(name, name);}}}public void Fill(string cultureName, Dictionary<string, LocalizedString> dictionary){if (!_resources.ContainsKey(cultureName)){_resources.Add(cultureName, dictionary);}else{foreach (var item in dictionary){if (_resources[cultureName].ContainsKey(item.Key)){_resources[cultureName][item.Key] = item.Value;}else{_resources[cultureName].Add(item.Key, item.Value);}}}}//调用登录时接口时触发https://localhost:44356/Account/Loginpublic async Task FillAsync(string cultureName, Dictionary<string, LocalizedString> dictionary){if (!_resources.ContainsKey(cultureName)){_resources.Add(cultureName, dictionary);}else{foreach (var item in dictionary){if (_resources[cultureName].ContainsKey(item.Key)){_resources[cultureName][item.Key] = item.Value; }else{_resources[cultureName].Add(item.Key, item.Value);}}}}public Task<IEnumerable<string>> GetSupportedCulturesAsync(){var cultures=_freeSql.Select<LocalizedCulture>().ToList(t => t.Culture).AsEnumerable<string>();return Task.FromResult(cultures);}}

前端更改语言时调用后端加载多语言json

合并json使用lodash库

import merge from 'lodash/merge';

后台接口数据示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/480697.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ceph的用户管理和cephx认证

用户权限概述 用户格式 参考链接&#xff1a; 权限&#xff1a;https://docs.ceph.com/en/latest/rados/operations/user-management/#authorization-capabilities 用户&#xff1a;https://docs.ceph.com/en/reef/rados/operations/user-management/ ceph的用户格式TYPEID…

springboot340“共享书角”图书借还管理系统(论文+源码)_kaic

摘 要 随着社会的发展&#xff0c;图书借还的管理形势越来越严峻。越来越多的借阅者利用互联网获得信息&#xff0c;但图书借还信息量大。为了方便借阅者更好的获得本图书借还信息&#xff0c;因此&#xff0c;设计一种安全高效的“共享书角”图书借还管理系统极为重要。 为…

爬虫笔记24——纷玩岛自动抢票脚本笔记

纷玩岛自动抢票&#xff0c;协议抢票思路实现 一、获取Authorization凭证二、几个关键的参数三、几个关键的接口获取参数v&#xff0c;这个参数其实可以写死&#xff0c;可忽略通过价位获取演出的参数信息获取观演人信息&#xff0c;账号提前录入即可提交订单接口 先看实现图&a…

配置泛微e9后端开发环境

配置泛微e9的后端开发环境 1.安装jdk1.8&#xff08;请自行安装并设置环境变量&#xff09; 2.将服务器上的WEARVER文件夹拷贝到开发环境下(其中要包含ecology和Resin目录) 3.通过idea创建一个基础Java项目,将jdk设置为1.8 4.添加依赖,需要将3个文件夹的所有jar包添加到项目中…

52-基于单片机的超声波、温湿度、光照检测分阶段报警

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 1.通过DHT11模块读取环境温度和湿度: 2.将湿度、障碍物距显示在lcd1602上面&#xff0c;第一行显示温度和湿度,格式为:xxCyy%&#xff0c;第二行显示超声波传感器测得的距离&#xff0c;格式为:Di…

C++类的自动转换和强制类型转换

目录 一、类型转换 二、转换函数 一、类型转换 C⽀持内置类型隐式类型转换为类类型对象&#xff0c;需要有相关内置类型为参数的构造函数 简单说就是可以将内置类型转化为自定义类型 示例&#xff1a; class Test { public:Test(int n1 0):num1(n1){}void pr…

w~视觉~合集26

我自己的原文哦~ https://blog.51cto.com/whaosoft/12663170 #InternVL 本文设计了一个大规模的视觉-语言基础模型&#xff08;InternVL&#xff09;&#xff0c;将视觉基础模型的参数扩展到60亿&#xff0c;并逐步与LLM对齐&#xff0c;利用来自不同来源的网络规模的图像-文…

C++优选算法十六 BFS解决最短路问题

1.BFS解决最短路问题的优势与局限 BFS是一种有效的解决最短路问题的算法&#xff0c;特别适用于无权图或边权相等的图。 优势&#xff1a; BFS能够逐层遍历图中的所有节点&#xff0c;直到找到目标节点或遍历完所有可达节点。对于无权图&#xff08;即边权为1的图&#xff0…

服务器创建容器时报错: no main manifest attribute

1.出现问题的原因 springboot项目快速搭建完成以后&#xff0c;打包 > 制作容器 > 启动 在创建完成docker容器以后,启动时出现以下问题 查询了一下百度,说的是没有main文件信息, 2.解决方法 在pom文件里面加入以下代码即可 <plugins><plugin><groupI…

【小白学机器学习34】基础统计2种方法:用numpy的方法np().mean()等进行统计,pd.DataFrame.groupby() 分组统计

目录 1 用 numpy 快速求数组的各种统计量&#xff1a;mean, var, std 1.1 数据准备 1.2 直接用np的公式求解 1.3 注意问题 1.4 用print() 输出内容&#xff0c;显示效果 2 为了验证公式的背后的理解&#xff0c;下面是详细的展开公式的求法 2.1 均值mean的详细 2.2 方差…

无需插件,如何以二维码网址直抵3D互动新世界?

随着Web技术的飞速发展&#xff0c;一个无需额外插件&#xff0c;仅凭二维码或网址即可直接访问的三维互动时代已经悄然来临。这一变革&#xff0c;得益于WebGL技术与先进web3D引擎的完美融合&#xff0c;它们共同构建了51建模网这样一个既便捷又高效的在线三维互动平台&#x…

【前端】跨域问题与缓存

报错如下&#xff1a; 原因&#xff1a; 浏览器 缓存跨域&#xff0c;顾名思义是由于浏览器的缓存机制导致的一种跨域情况。这种跨域一般会出现在浏览器通过一些无视跨域的标签和css(如img、background-image)缓存了一些图片资源之后&#xff0c;当再次发起图片请求时&#xff…

怎么样才算得上熟悉高并发编程?

提到并发编程很多人就会头疼了&#xff1b;首先就是一些基础概念&#xff1a;并发&#xff0c;并行&#xff0c;同步&#xff0c;异步&#xff0c;临界区&#xff0c;阻塞&#xff0c;非阻塞还有各种锁全都砸你脸上&#xff0c;随之而来的就是要保证程序运行时关键数据在多线程…

大数据新视界 -- 大数据大厂之 Hive 数据质量保障:数据清洗与验证的策略(上)(17/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

MySQL5.6升级MySQL5.7

升级方式介绍 08 数据库服务版本升级方法 5.6 – 5.7 – 8.0 数据库版本升级方法&#xff1a; Inplace-本地升级 步骤一&#xff1a;在同一台服务器中&#xff0c;需要部署高版本数据库服务实例步骤二&#xff1a;低版本数据库中的数据进行备份迁移&#xff0c;迁移到高版本…

添加字符(暴力模拟)

添加字符 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);char[] A in.next().toCharArray();char[] B in.next().toCharArray();int …

关注度上升,交易量直线上涨,Base Season 即将到来?

撰文&#xff1a;Zeneca 编译&#xff1a;Yangz&#xff0c;Techub News 译者按&#xff1a;凭借 AI 发币平台 Clanker 及 Virtuals 的爆火&#xff0c;行业对 Base 生态的关注出现「暴涨」。当地时间 11 月 26 日&#xff0c;Base 上的交易量直线拉升&#xff0c;达到约 1136…

安能物流 All in TiDB 背后的故事与成果

导读 在数字化转型的浪潮中&#xff0c;安能物流通过技术创新不断提升物流效率&#xff0c;迈出了全链路 All in TiDB 的重要一步。本文将深入探讨安能物流如何选择 TiDB 作为核心数据库&#xff0c;以应对高并发、数据处理能力和系统可扩展性等挑战。通过 TiDB 的弹性扩展能力…

《深入理解经典广度优先遍历算法》

广度优先遍历:宽度优先遍历&#xff08;Breadth-First Search, BFS&#xff09;, 图论和树论中基本的查找搜索算法&#xff0c; 是广大图算法的基础.。 前置知识和介绍 数据结构: 队列&#xff0c; 双端队列。 二叉树:经典bfs,按层bfs&#xff08;即树的层序遍历&#xff09;。…

FPGA工具链及功能介绍

一、处理流程 把verilog等源码&#xff0c;变为FPGA中可执行的比特流文件&#xff0c;主要包含这些步骤&#xff1a; 步骤功能转译将verilog代码转化为更详细的语法&#xff0c;增加更多细节内容技术映射将每个vrilog用到的模块&#xff0c;对应到FPGA的物理器件上优化优化冗余…