using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Globalization;
namespace Atomx.Admin.Client.Services
{
///
/// 语言提供者服务
///
public class LanguageProvider
{
private readonly IJSRuntime _jsRuntime;
private readonly NavigationManager _navigationManager;
private string _currentLanguage = "zh-Hans";
public event Action? OnLanguageChanged;
public LanguageProvider(IJSRuntime jsRuntime, NavigationManager navigationManager)
{
_jsRuntime = jsRuntime;
_navigationManager = navigationManager;
}
public string CurrentLanguage
{
get => _currentLanguage;
private set
{
if (_currentLanguage != value)
{
_currentLanguage = value;
// 设置全局线程文化,确保 IStringLocalizer 等在随后的渲染中读取到新文化
try
{
var ci = new CultureInfo(value);
CultureInfo.DefaultThreadCurrentCulture = ci;
CultureInfo.DefaultThreadCurrentUICulture = ci;
}
catch
{
// 忽略无效 culture 字符串
}
OnLanguageChanged?.Invoke();
}
}
}
public List SupportedLanguages { get; } = new()
{
"zh-Hans", // 简体中文
"en-US" // 英文(美国)
};
///
/// 初始化语言
///
public async Task InitializeAsync()
{
// 尝试从本地存储获取保存的语言
try
{
var savedLanguage = await _jsRuntime.InvokeAsync("localStorage.getItem", "preferred-language");
if (!string.IsNullOrEmpty(savedLanguage) && SupportedLanguages.Contains(savedLanguage))
{
CurrentLanguage = savedLanguage;
}
else
{
// 从浏览器获取语言
var browserLanguage = await _jsRuntime.InvokeAsync("getBrowserLanguage");
CurrentLanguage = GetSupportedLanguage(browserLanguage);
}
}
catch
{
// JS互操作可能不可用(在预渲染时)
CurrentLanguage = "zh-Hans";
}
}
///
/// 切换语言
///
public async Task ChangeLanguageAsync(string languageCode)
{
if (SupportedLanguages.Contains(languageCode) && CurrentLanguage != languageCode)
{
CurrentLanguage = languageCode;
// 保存到本地存储
try
{
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "preferred-language", languageCode);
}
catch
{
// 忽略错误
}
// setter 已触发 OnLanguageChanged
}
}
///
/// 获取支持的语言
///
private string GetSupportedLanguage(string browserLanguage)
{
if (string.IsNullOrEmpty(browserLanguage))
return "zh-Hans";
// 检查完全匹配
if (SupportedLanguages.Contains(browserLanguage))
return browserLanguage;
// 检查中性语言匹配
var neutralLanguage = browserLanguage.Split('-')[0];
foreach (var supported in SupportedLanguages)
{
if (supported.StartsWith(neutralLanguage))
return supported;
}
return "zh-Hans"; // 默认语言
}
}
}