## 项目中英文转换逻辑说明
### 一、国际化(i18n)架构概述
本项目采用 **Vue I18n** 实现中英文双语切换,核心架构包含配置层、语言包层和组件调用层三个层次。
---
### 二、核心文件结构
| 文件路径 | 功能说明 |
|---------|---------|
| `src/i18n.ts` | Vue I18n 核心配置,注册语言包 |
| `src/i18n.d.ts` | TypeScript 类型定义文件 |
| `src/locales/zh.json` | 中文语言包(键值对存储) |
| `src/locales/en.json` | 英文语言包(与中文键结构一致) |
| `src/locales/index.js` | 备用语言管理模块 |
| `scripts/extract-i18n.js` | 自动提取国际化标记的脚本 |
---
### 三、中英文转换核心逻辑
#### 3.1 配置初始化 (`src/i18n.ts`)
```typescript
import { createI18n } from 'vue-i18n';
import zh from './locales/zh.json';
import en from './locales/en.json';
const i18n = createI18n({
legacy: false, // 使用 Composition API 模式
locale: 'zh', // 默认语言:中文
fallbackLocale: 'en', // 回退语言:英文
messages: { zh, en }, // 语言包映射对象
});
export default i18n;
```
**关键配置说明:**
- `legacy: false` - 启用 Vue 3 Composition API 兼容模式
- `locale` - 当前活跃语言标识
- `fallbackLocale` - 当某个 key 在当前语言包不存在时,使用回退语言
#### 3.2 语言包结构
语言包采用**嵌套 JSON 结构**,支持层级键路径:
```json
// src/locales/zh.json
{
"Header": {
"title": "土壤酸化智能预测专家系统",
"welcome": "欢迎",
"logout": "退出登录"
},
"login": {
"userTitle": "用户登录",
"loginButton": "登录",
"loginFailed": "登录失败,请检查用户名或密码"
},
"validation": {
"usernameRequired": "请输入账号",
"passwordLength": "密码长度为 3 到 16 个字符"
}
}
```
#### 3.3 组件调用方式
**Vue 模板中的使用:**
```vue
{{ t('login.userTitle') }}
{{ t('login.loginButton') }}
```
**TypeScript 文件中的使用:**
```typescript
// 在组合式函数中使用
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// 用于消息提示
ElMessage.success(t('login.loginSuccess'));
// 用于动态文本
const errorMsg = t('login.loginFailed');
```
---
### 四、语言切换流程
#### 4.1 完整切换流程(以登录页为例)
```typescript
// src/views/login/loginView.vue
const toggleLanguage = async () => {
// 1. 计算新语言
const newLocale = locale.value === "zh" ? "en" : "zh";
// 2. 更新 Vue I18n locale(触发视图自动更新)
locale.value = newLocale;
// 3. 持久化到 localStorage(刷新页面保持语言设置)
localStorage.setItem("lang", newLocale);
// 4. 可选:同步到后端(保存用户语言偏好)
try {
await changeLanguageAPI({
language: newLocale,
userId: store.userInfo?.userId,
timestamp: Date.now(),
});
} catch (error) {
console.error("语言切换同步失败:", error);
}
};
```
#### 4.2 初始化时的语言恢复
在应用启动时,从 localStorage 读取上次保存的语言:
```typescript
// src/main.ts
const savedLang = localStorage.getItem('lang') || 'zh';
const i18n = createI18n({
locale: savedLang,
// ... 其他配置
});
```
---
### 五、国际化标记提取脚本
#### 5.1 脚本位置和功能
**脚本文件:** `scripts/extract-i18n.js`
**核心功能:**
- 自动扫描 `.vue` 和 `.ts` 文件
- 识别特定标记格式的中文文本
- 自动生成/更新语言包文件
#### 5.2 使用方法
```bash
# 扫描整个 src 目录(默认)
node scripts/extract-i18n.js
# 扫描指定目录
node scripts/extract-i18n.js src/views/User
# 扫描单个文件
node scripts/extract-i18n.js src/components/layout/AppLayout.vue
```
#### 5.3 提取标记格式
在 Vue/TS 文件中使用以下格式标记需要国际化的文本:
```vue
中文文本内容
```
**示例:**
```vue
土壤酸化智能预测专家系统
用户登录
数据管理
```
#### 5.4 脚本处理流程
```
1. 解析命令行参数 → 确定扫描路径
2. 读取已有语言包 → 保留历史翻译
3. 递归扫描文件 → 收集 .vue/.ts 文件
4. 正则匹配标记 → 提取键名和中文文本
5. 构建嵌套对象 → 处理键路径(如 Menu.subMenu.item)
6. 写入语言包 → 更新 zh.json 和 en.json
```
#### 5.5 脚本核心代码解析
**标记匹配正则:**
```javascript
const regex = /([\u4e00-\u9fa5\w\s,.,。;;!!??::()()]+?)(?=\r?\n|['"<]|$)/g;
```
**嵌套键设置函数:**
```javascript
function setNestedValue(obj, keyPath, value) {
const keys = keyPath.split('.');
let current = obj;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (typeof current[key] === 'string') {
console.warn(`键名冲突:"${key}" 已作为字符串存在`);
return;
}
if (!current[key] || typeof current[key] !== 'object') {
current[key] = {};
}
current = current[key];
}
const lastKey = keys[keys.length - 1];
if (current[lastKey] === undefined) {
current[lastKey] = value;
}
}
```
---
### 六、语言包维护规范
| 规范项 | 说明 |
|-------|------|
| **键命名** | 使用 `模块名.子模块.键名` 格式,如 `Menu.dataManagement` |
| **结构对齐** | 中英文语言包必须保持**完全相同的键结构** |
| **值处理** | 中文包存储中文原文,英文包存储对应英文翻译 |
| **新增翻译** | 同时在 `zh.json` 和 `en.json` 中添加键值对 |
| **标记规范** | 使用 `` 标记便于脚本提取 |
| **避免硬编码** | 所有用户可见文本必须通过 `t()` 函数获取 |
---
### 七、现有翻译覆盖范围
| 模块 | 说明 |
|-----|------|
| **Header** | 顶部导航栏文本 |
| **login/register/logout** | 登录、注册、退出相关 |
| **Menu** | 侧边栏菜单项 |
| **validation** | 表单验证提示 |
| **AcidModelMap** | 酸化模型地图相关 |
| **PhPrediction** | pH 预测模型相关 |
| **Calculation** | 计算模块相关 |
| **DetectionStatistics** | 检测统计相关 |
| **SoilCdStatistics** | 土壤镉统计相关 |
| **LandCultivatedStatistics** | 耕地统计相关 |
---
### 八、Element Plus 组件国际化
Element Plus 组件默认使用中文,如需支持英文需额外配置:
```typescript
// src/main.ts
import ElementPlus from 'element-plus';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import en from 'element-plus/es/locale/lang/en';
// 根据当前语言动态切换 Element Plus 语言
app.use(ElementPlus, {
locale: locale.value === 'zh' ? zhCn : en,
});
```
---
### 九、扩展说明
#### 9.1 添加新翻译流程
1. **标记文本**:在 Vue/TS 文件中添加 `` 标记
2. **运行脚本**:执行 `node scripts/extract-i18n.js` 提取标记
3. **翻译英文**:在 `en.json` 中填写对应英文翻译
4. **使用翻译**:在组件中使用 `t('键名')` 获取文本
#### 9.2 语言切换事件通知
通过自定义事件通知其他组件语言变化:
```typescript
// 触发语言切换事件
window.dispatchEvent(new CustomEvent('languageChanged', {
detail: { locale: locale.value }
}));
// 监听语言切换事件
window.addEventListener('languageChanged', (e) => {
console.log('语言已切换为:', e.detail.locale);
});
```