From eef91a6c83206e10f0ab45ba4445b6522e6a88f9 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 25 Feb 2026 18:21:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=89=8D=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=A4=9A=E8=AF=AD=E8=A8=80=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前端: - 在 API 请求中添加 Accept-Language 头,传递当前语言设置 后端: - 创建 LanguageMiddleware 中间件,自动检测并设置语言 - 为所有 API 路由添加语言中间件 Co-Authored-By: Claude Opus 4.6 --- backend/app/middleware/LanguageMiddleware.php | 31 +++++++++++++++++++ backend/config/route.php | 12 ++++--- frontend/src/services/api.ts | 5 ++- 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 backend/app/middleware/LanguageMiddleware.php diff --git a/backend/app/middleware/LanguageMiddleware.php b/backend/app/middleware/LanguageMiddleware.php new file mode 100644 index 0000000..104b1c3 --- /dev/null +++ b/backend/app/middleware/LanguageMiddleware.php @@ -0,0 +1,31 @@ +header('Accept-Language'); + + if ($acceptLanguage) { + // 取前两个字符作为语言代码 + $locale = substr($acceptLanguage, 0, 2); + + // 支持的语言列表 + $supportedLocales = ['zh', 'en', 'ru', 'es', 'fr']; + + if (in_array($locale, $supportedLocales)) { + Translation::setLocale($locale); + } + } + + return $next($request); + } +} diff --git a/backend/config/route.php b/backend/config/route.php index ce2959c..8cb6c5a 100644 --- a/backend/config/route.php +++ b/backend/config/route.php @@ -2,11 +2,15 @@ use Webman\Route; +// 全局 API 中间件(语言设置) +$apiMiddleware = [app\middleware\LanguageMiddleware::class]; +$authMiddleware = array_merge($apiMiddleware, [app\middleware\AuthMiddleware::class]); + // 认证路由(不需要认证) Route::group('/api/v1', function () { Route::post('/auth/login', [app\controller\AuthController::class, 'login']); Route::post('/auth/feishu-login', [app\controller\AuthController::class, 'feishuLogin']); -}); +})->middleware($apiMiddleware); // 用户路由(需要认证) Route::group('/api/v1/user', function () { @@ -15,7 +19,7 @@ Route::group('/api/v1/user', function () { Route::get('/companies', [app\controller\UserController::class, 'companies']); Route::get('/list', [app\controller\UserController::class, 'list']); Route::post('/switch-company', [app\controller\UserController::class, 'switchCompany']); -})->middleware([\app\middleware\AuthMiddleware::class]); +})->middleware($authMiddleware); // 审批路由(需要认证) Route::group('/api/v1/approval', function () { @@ -24,7 +28,7 @@ Route::group('/api/v1/approval', function () { Route::post('/approve/{id}', [app\controller\ApprovalController::class, 'approve']); Route::post('/reject/{id}', [app\controller\ApprovalController::class, 'reject']); Route::post('/cancel/{id}', [app\controller\ApprovalController::class, 'cancel']); -})->middleware([\app\middleware\AuthMiddleware::class]); +})->middleware($authMiddleware); // 出差审批路由(需要认证) Route::group('/api/v1/business-trip', function () { @@ -36,7 +40,7 @@ Route::group('/api/v1/business-trip', function () { Route::post('/cancel/{id}', [app\controller\BusinessTripController::class, 'cancel']); Route::delete('/{id}', [app\controller\BusinessTripController::class, 'deleteDraft']); Route::post('/approve/{id}', [app\controller\BusinessTripController::class, 'approve']); -})->middleware([\app\middleware\AuthMiddleware::class]); +})->middleware($authMiddleware); // 默认路由 Route::fallback(function () { diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index cad932e..529445c 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -11,13 +11,16 @@ const api = axios.create({ }, }) -// 请求拦截器:添加 token +// 请求拦截器:添加 token 和语言 api.interceptors.request.use( (config) => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } + // 添加语言头 + const lang = localStorage.getItem('i18nextLng') || 'zh' + config.headers['Accept-Language'] = lang return config }, (error) => {