通过数据库加载实现动态管理,用户可以自己修改界面显示的文本,满足国际化需求
如图所示,前端使用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/Login
public 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';
后台接口数据示例