92 lines
5.2 KiB
Markdown
92 lines
5.2 KiB
Markdown
<!-- 22f17591-d664-4371-a1b6-9e4769285ad8 -->
|
|
---
|
|
todos:
|
|
- id: "middleware"
|
|
content: "新建 app/middleware/Language.php:读 X-Lang、归一化、每请求 locale()、设 $request->language"
|
|
status: pending
|
|
- id: "register"
|
|
content: "config/middleware.php 全局组在 TraceId 前注册 Language 中间件"
|
|
status: pending
|
|
- id: "config"
|
|
content: "config/translation.php 增加 supported=['zh_CN','en'],保留默认 zh_CN"
|
|
status: pending
|
|
- id: "trans-files"
|
|
content: "新建 resource/translations/{zh_CN,en}/messages.php,含 errors(按 OtaErrorCode)+ validation + common.ok"
|
|
status: pending
|
|
- id: "exception"
|
|
content: "BusinessException message 改可选;Handler 渲染时 trans('errors.'+code);Logic 7 处抛出去掉中文只传 code"
|
|
status: pending
|
|
- id: "result-auth"
|
|
content: "Result::fail 支持空 message 回退 trans;AdminAuth/InternalTokenAuth 去掉中文消息"
|
|
status: pending
|
|
- id: "validate"
|
|
content: "3 个 validator 的 $message 改翻译 key;AdminController::validate 返回前 trans();补全 validation.* 译文"
|
|
status: pending
|
|
- id: "verify"
|
|
content: "internal/admin 带 X-Lang 验证消息随 locale 变化 + 连续请求无串台,跑收尾检测脚本"
|
|
status: pending
|
|
isProject: false
|
|
---
|
|
# OTA 接口国际化(i18n)
|
|
|
|
## 结论先行
|
|
|
|
「中间件解析 header」思路正确,但在 Webman(常驻进程)里**核心动作是 `locale($lang)`**,不是把语言塞进 `$request->language`。`$request->language` 只作附带标记(给 Logic/日志用,非必须)。已具备:`config/translation.php`、`symfony/translation`。缺:语言中间件、翻译文件、把硬编码消息接到 `trans()`。
|
|
|
|
约定:自定义头 `X-Lang`(值 `zh_CN` / `en`),默认 `zh_CN`,覆盖 internal + admin。
|
|
|
|
## 数据流
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
req["HTTP 请求 X-Lang: en"] --> lang["Language 中间件 locale(en) + request->language"]
|
|
lang --> auth["Auth 中间件 Result::fail(code)"]
|
|
auth --> ctrl["Controller / Validate"]
|
|
ctrl --> logic["Logic throw BusinessException(code)"]
|
|
logic --> handler["Handler trans(code) 渲染"]
|
|
handler --> resp["{code, message(已按 locale 翻译), data}"]
|
|
```
|
|
|
|
## 改动点
|
|
|
|
### 1. 语言中间件(新增)
|
|
新建 `app/middleware/Language.php`(`MiddlewareInterface`):
|
|
- 读 `X-Lang`(可兼容 `X-Language`),归一化(`zh`/`zh-CN`/`zh_cn` → `zh_CN`;`en`/`en-US` → `en`),不在支持列表则用默认。
|
|
- **每个请求都调 `locale($lang)`**(进程级全局状态,必须每请求重置,否则串语言)。
|
|
- 设 `$request->language = $lang`(附带)。
|
|
- 支持列表 + 默认值读 `config('translation')`(见第 5 步)。
|
|
|
|
### 2. 注册为全局中间件
|
|
[config/middleware.php](config/middleware.php) 的 `''` 组在 `TraceId` 前加入 `app\middleware\Language::class`,确保 admin/internal 鉴权失败消息也按 locale 翻译。
|
|
|
|
### 3. 翻译文件(新增)
|
|
新建 `resource/translations/zh_CN/messages.php` 与 `resource/translations/en/messages.php`,返回两段:
|
|
- `errors` => 以 `OtaErrorCode` 各常量字符串为 key 的消息(对应现 Logic / Auth 里的中文)。
|
|
- `validation` => 校验消息 key(见第 6 步)。
|
|
|
|
调用形如 `trans('errors.' . $code)`、`trans($validationKey)`。
|
|
|
|
### 4. 消息改为 trans() 取值
|
|
- [app/exception/Handler.php](app/exception/Handler.php):渲染 `BusinessException` 时 `message = trans('errors.' . $code)`(为空回退 code)。
|
|
- [app/exception/BusinessException.php](app/exception/BusinessException.php):`message` 改为可选;Logic 抛出时只传 code,去掉硬编码中文(`FirmwareLogic` 5 处、`OtaReportLogic`/`OtaCheckLogic`/`UpgradeRecordQueryLogic` 各 1 处)。需要动态文案的保留可选 message 入参。
|
|
- [app/support/Result.php](app/support/Result.php):`fail(string $code, ?string $message = null, ...)`,`$message` 为空时取 `trans('errors.' . $code)`;成功 `message` 用 `trans('common.ok')`。
|
|
- 两个 Auth 中间件(`AdminAuth`、`InternalTokenAuth`)`Result::fail` 去掉中文,只传 code。
|
|
|
|
### 5. 配置补充
|
|
[config/translation.php](config/translation.php) 增加 `supported => ['zh_CN','en']`,`locale` 维持 `zh_CN` 作默认。中间件据此校验/回退。
|
|
|
|
### 6. 校验消息国际化(think\Validate)
|
|
为统一到单一 i18n(trans),不引入 think\Lang 第二套:
|
|
- 3 个 validator(`FirmwareCreateValidate`、`FirmwareListValidate`、`UpgradeRecordListValidate`)的 `$message` 值改为翻译 key(如 `validation.firmware.product_key_required`)。
|
|
- [app/admin/controller/AdminController.php](app/admin/controller/AdminController.php) `validate()` 返回前对错误信息做 `trans()`(key 命中则翻译,未命中原样返回)。
|
|
- 两个 locale 的 `messages.php` 补全这些 `validation.*` key。
|
|
|
|
## 验证
|
|
- internal:`POST /internal/ota/check` 带/不带 `X-Lang: en`,断言鉴权失败、业务异常、参数错误的 message 随 locale 变化。
|
|
- admin:固件创建非法参数,`X-Lang: en` 返回英文校验消息。
|
|
- 连续两请求(en 后 zh_CN)验证无 locale 串台(常驻进程回归)。
|
|
- 收尾跑 `~/.cursor/skills/slot-backend-completion-report/scripts/report.sh` 并附检测结果。
|
|
|
|
## 不做 / 待确认
|
|
- 不替换为 Accept-Language(已选自定义头)。
|
|
- 英文译文先给准确直译,文案润色后续可调。 |