Files
webman-buildadmin/app/common/middleware/LoadLangPack.php
zhenhui 932a433613 1.优化下注接口/api/game/betPlace
2.优化后台/admin/config/gameConfig中新增压注筹码配置
2026-05-14 10:37:21 +08:00

173 lines
6.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Request;
use Webman\Http\Response;
/**
* 加载控制器语言包中间件Webman 迁移版,等价 ThinkPHP LoadLangPack
* 根据当前路由加载对应控制器的语言包到 Translator
*/
class LoadLangPack implements MiddlewareInterface
{
public function process(Request $request, callable $handler): Response
{
$path = trim($request->path(), '/');
if (str_starts_with($path, 'api/') || str_starts_with($path, 'admin/')) {
$this->loadLang($request);
}
return $handler($request);
}
/**
* 解析当前请求语言。
* - 后台 admin优先请求头 think-langzh-cn / en其次 lang 头,再次查询/表单参数 lang支持 zh→zh-cn
* - 对外 api优先查询/表单参数 langzh / zh-cn / en其次 lang 头,再次 think-lang仅当解析结果为允许列表中的 zh-cn 或 en 时生效,否则固定 zh-cn不使用 Accept-Language。仅 lang=en规范化后返回英文文案。
*/
protected function resolveLangSet(Request $request): string
{
$path = trim($request->path(), '/');
$parts = explode('/', $path);
$app = $parts[0] ?? 'api';
$queryRaw = $request->get('lang');
if ($queryRaw === null || $queryRaw === '') {
$queryRaw = $request->post('lang');
}
$queryLang = '';
if (is_string($queryRaw)) {
$queryLang = $queryRaw;
} elseif (is_scalar($queryRaw)) {
$queryLang = trim('' . $queryRaw);
}
$thinkRaw = $request->header('think-lang', '');
$thinkLang = '';
if (is_string($thinkRaw)) {
$thinkLang = $thinkRaw;
} elseif (is_array($thinkRaw) && isset($thinkRaw[0]) && is_string($thinkRaw[0])) {
$thinkLang = $thinkRaw[0];
}
$headerLangRaw = $request->header('lang', '');
$headerLang = '';
if (is_string($headerLangRaw)) {
$headerLang = $headerLangRaw;
} elseif (is_array($headerLangRaw) && isset($headerLangRaw[0]) && is_string($headerLangRaw[0])) {
$headerLang = $headerLangRaw[0];
}
$normalize = static function (string $raw): string {
$s = str_replace('_', '-', strtolower(trim($raw)));
if ($s === 'zh') {
return 'zh-cn';
}
return $s;
};
$allowLangList = config('lang.allow_lang_list', ['zh-cn', 'en']);
$candidates = [];
if ($app === 'admin') {
if ($thinkLang !== '') {
$candidates[] = $normalize($thinkLang);
}
if ($headerLang !== '') {
$candidates[] = $normalize($headerLang);
}
if ($queryLang !== '') {
$candidates[] = $normalize($queryLang);
}
} else {
if ($queryLang !== '') {
$candidates[] = $normalize($queryLang);
}
if ($headerLang !== '') {
$candidates[] = $normalize($headerLang);
}
if ($thinkLang !== '') {
$candidates[] = $normalize($thinkLang);
}
}
foreach ($candidates as $code) {
if ($code !== '' && in_array($code, $allowLangList, true)) {
return $code;
}
}
// 对外 api无显式 lang / think-lang 时默认中文,避免浏览器 Accept-Language: en 覆盖产品默认
if ($app === 'api') {
return 'zh-cn';
}
$acceptRaw = $request->header('accept-language');
$acceptLang = is_string($acceptRaw) ? $acceptRaw : '';
if (preg_match('/^zh[-_]?cn|^zh/i', $acceptLang)) {
return 'zh-cn';
}
if (preg_match('/^en/i', $acceptLang)) {
return 'en';
}
$defaultRaw = config('lang.default_lang', config('translation.locale', 'zh-cn'));
$default = is_string($defaultRaw) ? $defaultRaw : 'zh-cn';
return str_replace('_', '-', strtolower($default));
}
protected function loadLang(Request $request): void
{
$langSet = $this->resolveLangSet($request);
// 设置当前请求的翻译语言,使 __() 和 trans() 使用正确的语言
if (function_exists('locale')) {
locale($langSet);
}
$path = trim($request->path(), '/');
$parts = explode('/', $path);
$app = $parts[0] ?? 'api';
$appLangDir = base_path() . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . $app . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR;
if (!class_exists(\support\Translation::class)) {
return;
}
$translator = \support\Translation::instance();
// 1. 加载根级语言包zh-cn.php / en.php供 common 翻译使用
$rootLangFile = $appLangDir . $langSet . '.php';
if (is_file($rootLangFile)) {
$translator->addResource('phpfile', $rootLangFile, $langSet, 'messages');
}
// 1.5 公共语言包app/common/lang/{locale}/*.php供 common 服务层与多应用共用
$commonLangPattern = base_path() . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $langSet . DIRECTORY_SEPARATOR . '*.php';
foreach (glob($commonLangPattern) ?: [] as $commonLangFile) {
$translator->addResource('phpfile', $commonLangFile, $langSet, 'messages');
}
// 2. 加载控制器专用语言包(如 zh-cn/auth/group.php供 get_route_remark 等使用
// 同时加载到 messages 域,使 __() 能正确翻译控制器内的文案(如安装页错误提示)
$controllerPath = get_controller_path($request);
if ($controllerPath) {
$controllerPathForFile = str_replace('.', '/', $controllerPath);
$controllerPathForFile = implode('/', array_map(function ($p) {
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $p));
}, explode('/', $controllerPathForFile)));
$controllerLangFile = $appLangDir . $langSet . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $controllerPathForFile) . '.php';
if (is_file($controllerLangFile)) {
$translator->addResource('phpfile', $controllerLangFile, $langSet, $controllerPath);
$translator->addResource('phpfile', $controllerLangFile, $langSet, 'messages');
}
}
}
}