# i18n 契约 — 多语言规范

## 语言包文件

| 文件 | 语言 | 用途 |
|------|------|------|
| `lang/zh-CN.php` | 中文（默认） | key 和 value 均为中文原文 |
| `lang/en.php` | 英文 | key 为中文原文，value 为英文译文 |

语言包格式：`'中文原文' => '译文'`，key 统一用中文原文（不用英文 key）。

## lg() 使用规则

### 基本用法

```php
lg('用户列表')         // 取当前语言的译文，找不到时原样返回中文
```

### 符号/箭头/标点必须在 lg() 外面

```php
// 正确
lg('请先选择') . ' →'
'← ' . lg('请先在左侧选择一个属性类型')
lg('共') . ' ' . $count . ' ' . lg('条')

// 错误（符号被包进去，英文语言下符号跟着一起被翻译掉）
lg('← 请先在左侧选择一个属性类型')
lg('共 100 条')
```

### 动态数字/变量不进 lg()

```php
// 正确
lg('共') . $count . lg('个文案')

// 错误
lg("共 {$count} 个文案")
```

### 哪些内容不需要 lg()

- 纯英文专有名词（`DevExtreme`、`Grid`、`Excel`）
- 数字、日期格式字符串
- HTML 属性值（`class`、`id`、`name`）
- JS / CSS 中的字符串（JS 端从 `APP.GRID_TEXT` 读，不直接调用 `lg()`）

## 语言包维护流程

### 新增文案时

1. 直接在 PHP / 视图里写 `lg('新文案')`，先用中文开发
2. 开发完成后跑扫描工具：
   ```
   php pdc/lang/scan.php
   ```
3. 扫描工具会：
   - 找出所有 `lg('...')` 的字面量
   - 在 `zh-CN.php` 和 `en.php` 里补充缺失的 key
   - 已有的 key 不覆盖
4. 在 `en.php` 里给新增条目填英文译文

### 删除文案时

- 直接删代码里的 `lg('...')` 调用
- 语言包里对应的 key 可以保留（不影响运行），定期清理即可
- 不用每次删文案就同步清语言包

## 语言切换机制

- URL 传参 `?lang=en` 切换语言，写入 `$_SESSION['lang']`，立即生效
- 刷新后从 Session 恢复，无 Session 时默认 `zh-CN`
- 前端 JS 通过 `APP.LOCALE` 读取当前语言
- DevExtreme 组件语言由 `dx.messages.{locale}.js` 控制，已在 `header.view.php` 自动加载

## 菜单文案特殊规则

`config/admin.php` 的菜单配置里，title 必须用 `lg('中文原文')` 字面量调用：

```php
// 正确（扫描工具能识别字面量）
['title' => lg('用户'), 'url' => '/users/index']

// 错误（扫描工具无法扫描变量）
$title = '用户';
['title' => lg($title), 'url' => '/users/index']
```

## header.view.php 注入规则

Grid 工具栏文案统一在 `header.view.php` 用 PHP `lg()` 翻译后注入到 `APP.GRID_TEXT`：

```php
'GRID_TEXT' => [
    'refresh' => lg('刷新'),
    'export'  => lg('导出'),
    // 新增工具栏按钮时，在这里添加对应 key
]
```

新增 Grid 工具栏按钮时，**必须同时**：
1. 在 `header.view.php` 的 `GRID_TEXT` 里添加 key
2. 在 `dxGrid.js` 里用 `APP.GRID_TEXT.xxx` 读取
3. 运行 `scan.php` 同步语言包
