09d4cb8054
- 修复选择审批人后再选择抄送人导致状态丢失的问题 - 使用独立的 sessionStorage key (selectedApprovers, selectedCc) - 组件每次挂载时从 sessionStorage 恢复状态 - 只在提交/保存成功后清除 sessionStorage - 优化人员选择页面布局和样式 - 更新 CLAUDE.md 文档记录问题和解决方案 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
171 lines
4.3 KiB
PHP
171 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Util;
|
|
|
|
/**
|
|
* 多语言翻译类
|
|
* 支持:中文(zh)、英文(en)、俄语(ru)、西语(es)、法语(fr)
|
|
*/
|
|
class Lang
|
|
{
|
|
private static ?array $translations = null;
|
|
private static string $locale = 'zh';
|
|
private static string $fallbackLocale = 'zh';
|
|
|
|
/**
|
|
* 支持的语言列表
|
|
*/
|
|
public const SUPPORTED_LOCALES = ['zh', 'en', 'ru', 'es', 'fr'];
|
|
|
|
/**
|
|
* 语言名称映射
|
|
*/
|
|
public const LOCALE_NAMES = [
|
|
'zh' => '简体中文',
|
|
'en' => 'English',
|
|
'ru' => 'Русский',
|
|
'es' => 'Español',
|
|
'fr' => 'Français',
|
|
];
|
|
|
|
/**
|
|
* 初始化翻译
|
|
*/
|
|
private static function loadTranslations(): void
|
|
{
|
|
if (self::$translations !== null) {
|
|
return;
|
|
}
|
|
|
|
self::$translations = [];
|
|
foreach (self::SUPPORTED_LOCALES as $locale) {
|
|
$file = base_path() . "/lang/{$locale}.php";
|
|
if (file_exists($file)) {
|
|
self::$translations[$locale] = require $file;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置当前语言
|
|
*/
|
|
public static function setLocale(string $locale): void
|
|
{
|
|
if (in_array($locale, self::SUPPORTED_LOCALES)) {
|
|
self::$locale = $locale;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取当前语言
|
|
*/
|
|
public static function getLocale(): string
|
|
{
|
|
return self::$locale;
|
|
}
|
|
|
|
/**
|
|
* 从请求中获取语言
|
|
*/
|
|
public static function detectFromRequest(): string
|
|
{
|
|
// 从请求头获取语言
|
|
$request = \request();
|
|
$acceptLanguage = $request->header('Accept-Language');
|
|
|
|
if ($acceptLanguage) {
|
|
// 解析 Accept-Language 头
|
|
$locales = explode(',', $acceptLanguage);
|
|
foreach ($locales as $locale) {
|
|
$locale = trim(strstr($locale, ';', true));
|
|
$locale = substr($locale, 0, 2);
|
|
if (in_array($locale, self::SUPPORTED_LOCALES)) {
|
|
return $locale;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 从查询参数获取
|
|
$lang = $request->input('lang');
|
|
if ($lang && in_array($lang, self::SUPPORTED_LOCALES)) {
|
|
return $lang;
|
|
}
|
|
|
|
return self::$fallbackLocale;
|
|
}
|
|
|
|
/**
|
|
* 翻译文本
|
|
*
|
|
* @param string $key 翻译键,使用点号分隔,如 'common.confirm'
|
|
* @param array $params 替换参数
|
|
* @param string|null $locale 指定语言,null 则使用当前语言
|
|
* @return string 翻译后的文本
|
|
*/
|
|
public static function get(string $key, array $params = [], ?string $locale = null): string
|
|
{
|
|
self::loadTranslations();
|
|
|
|
$locale = $locale ?? self::$locale;
|
|
|
|
// 获取翻译值
|
|
$value = self::getTranslationValue($key, $locale);
|
|
|
|
// 替换参数
|
|
if (!empty($params)) {
|
|
foreach ($params as $search => $replace) {
|
|
$value = str_replace(':' . $search, $replace, $value);
|
|
$value = str_replace('{' . $search . '}', $replace, $value);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* 获取翻译值
|
|
*/
|
|
private static function getTranslationValue(string $key, string $locale): string
|
|
{
|
|
$keys = explode('.', $key);
|
|
$value = self::$translations[$locale] ?? [];
|
|
|
|
foreach ($keys as $k) {
|
|
if (isset($value[$k])) {
|
|
$value = $value[$k];
|
|
} else {
|
|
// 尝试使用回退语言
|
|
if ($locale !== self::$fallbackLocale) {
|
|
return self::getTranslationValue($key, self::$fallbackLocale);
|
|
}
|
|
return $key;
|
|
}
|
|
}
|
|
|
|
return is_string($value) ? $value : $key;
|
|
}
|
|
|
|
/**
|
|
* 判断翻译是否存在
|
|
*/
|
|
public static function has(string $key, ?string $locale = null): bool
|
|
{
|
|
self::loadTranslations();
|
|
|
|
$locale = $locale ?? self::$locale;
|
|
|
|
$keys = explode('.', $key);
|
|
$value = self::$translations[$locale] ?? [];
|
|
|
|
foreach ($keys as $k) {
|
|
if (isset($value[$k])) {
|
|
$value = $value[$k];
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|