feat: 添加前后端多语言支持
前端: - 在 API 请求中添加 Accept-Language 头,传递当前语言设置 后端: - 创建 LanguageMiddleware 中间件,自动检测并设置语言 - 为所有 API 路由添加语言中间件 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\middleware;
|
||||||
|
|
||||||
|
use support\Translation;
|
||||||
|
use Webman\Http\Request;
|
||||||
|
use Webman\Http\Response;
|
||||||
|
use Webman\MiddlewareInterface;
|
||||||
|
|
||||||
|
class LanguageMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
public function process(Request $request, callable $next): Response
|
||||||
|
{
|
||||||
|
// 从请求头获取语言
|
||||||
|
$acceptLanguage = $request->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
use Webman\Route;
|
use Webman\Route;
|
||||||
|
|
||||||
|
// 全局 API 中间件(语言设置)
|
||||||
|
$apiMiddleware = [app\middleware\LanguageMiddleware::class];
|
||||||
|
$authMiddleware = array_merge($apiMiddleware, [app\middleware\AuthMiddleware::class]);
|
||||||
|
|
||||||
// 认证路由(不需要认证)
|
// 认证路由(不需要认证)
|
||||||
Route::group('/api/v1', function () {
|
Route::group('/api/v1', function () {
|
||||||
Route::post('/auth/login', [app\controller\AuthController::class, 'login']);
|
Route::post('/auth/login', [app\controller\AuthController::class, 'login']);
|
||||||
Route::post('/auth/feishu-login', [app\controller\AuthController::class, 'feishuLogin']);
|
Route::post('/auth/feishu-login', [app\controller\AuthController::class, 'feishuLogin']);
|
||||||
});
|
})->middleware($apiMiddleware);
|
||||||
|
|
||||||
// 用户路由(需要认证)
|
// 用户路由(需要认证)
|
||||||
Route::group('/api/v1/user', function () {
|
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('/companies', [app\controller\UserController::class, 'companies']);
|
||||||
Route::get('/list', [app\controller\UserController::class, 'list']);
|
Route::get('/list', [app\controller\UserController::class, 'list']);
|
||||||
Route::post('/switch-company', [app\controller\UserController::class, 'switchCompany']);
|
Route::post('/switch-company', [app\controller\UserController::class, 'switchCompany']);
|
||||||
})->middleware([\app\middleware\AuthMiddleware::class]);
|
})->middleware($authMiddleware);
|
||||||
|
|
||||||
// 审批路由(需要认证)
|
// 审批路由(需要认证)
|
||||||
Route::group('/api/v1/approval', function () {
|
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('/approve/{id}', [app\controller\ApprovalController::class, 'approve']);
|
||||||
Route::post('/reject/{id}', [app\controller\ApprovalController::class, 'reject']);
|
Route::post('/reject/{id}', [app\controller\ApprovalController::class, 'reject']);
|
||||||
Route::post('/cancel/{id}', [app\controller\ApprovalController::class, 'cancel']);
|
Route::post('/cancel/{id}', [app\controller\ApprovalController::class, 'cancel']);
|
||||||
})->middleware([\app\middleware\AuthMiddleware::class]);
|
})->middleware($authMiddleware);
|
||||||
|
|
||||||
// 出差审批路由(需要认证)
|
// 出差审批路由(需要认证)
|
||||||
Route::group('/api/v1/business-trip', function () {
|
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::post('/cancel/{id}', [app\controller\BusinessTripController::class, 'cancel']);
|
||||||
Route::delete('/{id}', [app\controller\BusinessTripController::class, 'deleteDraft']);
|
Route::delete('/{id}', [app\controller\BusinessTripController::class, 'deleteDraft']);
|
||||||
Route::post('/approve/{id}', [app\controller\BusinessTripController::class, 'approve']);
|
Route::post('/approve/{id}', [app\controller\BusinessTripController::class, 'approve']);
|
||||||
})->middleware([\app\middleware\AuthMiddleware::class]);
|
})->middleware($authMiddleware);
|
||||||
|
|
||||||
// 默认路由
|
// 默认路由
|
||||||
Route::fallback(function () {
|
Route::fallback(function () {
|
||||||
|
|||||||
@@ -11,13 +11,16 @@ const api = axios.create({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 请求拦截器:添加 token
|
// 请求拦截器:添加 token 和语言
|
||||||
api.interceptors.request.use(
|
api.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
const token = localStorage.getItem('token')
|
const token = localStorage.getItem('token')
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
config.headers.Authorization = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
|
// 添加语言头
|
||||||
|
const lang = localStorage.getItem('i18nextLng') || 'zh'
|
||||||
|
config.headers['Accept-Language'] = lang
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user