feat: 改进下单错误处理和市场价格接口
- 修复市场价格接口:移除side参数,使用outcomeIndex判断方向 - 添加规范:禁止使用YES/NO字符串判断side,必须使用outcomeIndex - 改进所有下单错误处理:所有错误都打印详细日志并存入数据库 - AccountService.sellPosition: 添加完整错误日志 - CopyOrderTrackingService.createOrderWithRetry: 所有失败都记录详细日志 - recordFailedTrade: 改进错误信息存储,包含堆栈信息 - PolymarketClobService.createSignedOrder: 添加完整错误日志 - 前端:更新市场价格接口调用,使用outcomeIndex替代side参数 - 清理:删除过时的i18n文档
This commit is contained in:
@@ -1,266 +0,0 @@
|
||||
# Controller 多语言更新指南
|
||||
|
||||
## 已完成的 Controller ✅
|
||||
|
||||
1. **AccountController** - 完全更新
|
||||
2. **AuthController** - 完全更新
|
||||
3. **LeaderController** - 完全更新
|
||||
4. **UserController** - 完全更新
|
||||
|
||||
## 待更新的 Controller
|
||||
|
||||
以下 Controller 需要按照相同模式更新:
|
||||
|
||||
1. **CopyTradingController** - 已添加 MessageSource,需要更新所有 ApiResponse.error() 调用
|
||||
2. **CopyTradingTemplateController** - 需要添加 MessageSource 并更新调用
|
||||
3. **MarketController** - 需要添加 MessageSource 并更新调用
|
||||
4. **CopyTradingStatisticsController** - 需要添加 MessageSource 并更新调用
|
||||
5. **ProxyConfigController** - 需要添加 MessageSource 并更新调用
|
||||
6. **HealthController** - 需要检查是否需要更新
|
||||
|
||||
## 更新步骤
|
||||
|
||||
### 步骤 1:添加导入和依赖注入
|
||||
|
||||
```kotlin
|
||||
// 1. 添加导入
|
||||
import com.wrbug.polymarketbot.util.error
|
||||
import org.springframework.context.MessageSource
|
||||
|
||||
// 2. 在构造函数中注入 MessageSource
|
||||
class YourController(
|
||||
private val yourService: YourService,
|
||||
private val messageSource: MessageSource // 添加这一行
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤 2:更新所有 ApiResponse.error() 调用
|
||||
|
||||
**模式 1:只有 ErrorCode**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR)
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
```
|
||||
|
||||
**模式 2:ErrorCode + 自定义消息**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息")
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息", messageSource)
|
||||
```
|
||||
|
||||
**模式 3:使用 code + msg(已废弃的方法)**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR.code, "消息")
|
||||
ApiResponse.paramError("消息")
|
||||
ApiResponse.serverError("消息")
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "消息", messageSource)
|
||||
ApiResponse.error(ErrorCode.SERVER_ERROR, "消息", messageSource)
|
||||
```
|
||||
|
||||
### 步骤 3:批量查找和替换
|
||||
|
||||
使用 IDE 的查找替换功能:
|
||||
|
||||
1. **查找模式**:`ApiResponse.error(ErrorCode.`
|
||||
2. **替换模式**:在方法调用末尾添加 `, messageSource = messageSource)`
|
||||
|
||||
**注意**:需要逐个检查,因为有些调用已经有其他参数。
|
||||
|
||||
### 示例:CopyTradingController 更新
|
||||
|
||||
```kotlin
|
||||
// 更新前
|
||||
if (request.accountId <= 0) {
|
||||
return ResponseEntity.ok(ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID))
|
||||
}
|
||||
|
||||
// 更新后
|
||||
if (request.accountId <= 0) {
|
||||
return ResponseEntity.ok(ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID, messageSource = messageSource))
|
||||
}
|
||||
|
||||
// 更新前
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
|
||||
// 更新后
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
```
|
||||
|
||||
## 验证
|
||||
|
||||
更新完成后,检查:
|
||||
|
||||
1. ✅ 所有 Controller 都注入了 MessageSource
|
||||
2. ✅ 所有 ApiResponse.error() 调用都传入了 messageSource 参数
|
||||
3. ✅ 编译无错误
|
||||
4. ✅ 测试 API 响应消息是否正确显示对应语言
|
||||
|
||||
## 快速更新脚本(参考)
|
||||
|
||||
可以使用以下模式批量更新:
|
||||
|
||||
```bash
|
||||
# 在 IDE 中使用正则表达式查找替换
|
||||
# 查找:ApiResponse\.error\(ErrorCode\.(\w+)\)\)
|
||||
# 替换:ApiResponse.error(ErrorCode.$1, messageSource = messageSource)
|
||||
|
||||
# 查找:ApiResponse\.error\(ErrorCode\.(\w+),\s*([^,)]+)\)\)
|
||||
# 替换:ApiResponse.error(ErrorCode.$1, $2, messageSource)
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **自定义消息**:如果错误消息是硬编码的中文,建议:
|
||||
- 优先使用 ErrorCode 的 messageKey(已在语言包中翻译)
|
||||
- 如果必须使用自定义消息,确保消息本身也需要国际化(通过 MessageUtils.getMessage())
|
||||
|
||||
2. **向后兼容**:如果前端没有发送语言 Header,后端会使用默认语言(英文)
|
||||
|
||||
3. **测试**:更新后测试不同语言下的错误消息显示
|
||||
|
||||
|
||||
|
||||
## 已完成的 Controller ✅
|
||||
|
||||
1. **AccountController** - 完全更新
|
||||
2. **AuthController** - 完全更新
|
||||
3. **LeaderController** - 完全更新
|
||||
4. **UserController** - 完全更新
|
||||
|
||||
## 待更新的 Controller
|
||||
|
||||
以下 Controller 需要按照相同模式更新:
|
||||
|
||||
1. **CopyTradingController** - 已添加 MessageSource,需要更新所有 ApiResponse.error() 调用
|
||||
2. **CopyTradingTemplateController** - 需要添加 MessageSource 并更新调用
|
||||
3. **MarketController** - 需要添加 MessageSource 并更新调用
|
||||
4. **CopyTradingStatisticsController** - 需要添加 MessageSource 并更新调用
|
||||
5. **ProxyConfigController** - 需要添加 MessageSource 并更新调用
|
||||
6. **HealthController** - 需要检查是否需要更新
|
||||
|
||||
## 更新步骤
|
||||
|
||||
### 步骤 1:添加导入和依赖注入
|
||||
|
||||
```kotlin
|
||||
// 1. 添加导入
|
||||
import com.wrbug.polymarketbot.util.error
|
||||
import org.springframework.context.MessageSource
|
||||
|
||||
// 2. 在构造函数中注入 MessageSource
|
||||
class YourController(
|
||||
private val yourService: YourService,
|
||||
private val messageSource: MessageSource // 添加这一行
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤 2:更新所有 ApiResponse.error() 调用
|
||||
|
||||
**模式 1:只有 ErrorCode**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR)
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
```
|
||||
|
||||
**模式 2:ErrorCode + 自定义消息**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息")
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息", messageSource)
|
||||
```
|
||||
|
||||
**模式 3:使用 code + msg(已废弃的方法)**
|
||||
```kotlin
|
||||
// 旧代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR.code, "消息")
|
||||
ApiResponse.paramError("消息")
|
||||
ApiResponse.serverError("消息")
|
||||
|
||||
// 新代码
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "消息", messageSource)
|
||||
ApiResponse.error(ErrorCode.SERVER_ERROR, "消息", messageSource)
|
||||
```
|
||||
|
||||
### 步骤 3:批量查找和替换
|
||||
|
||||
使用 IDE 的查找替换功能:
|
||||
|
||||
1. **查找模式**:`ApiResponse.error(ErrorCode.`
|
||||
2. **替换模式**:在方法调用末尾添加 `, messageSource = messageSource)`
|
||||
|
||||
**注意**:需要逐个检查,因为有些调用已经有其他参数。
|
||||
|
||||
### 示例:CopyTradingController 更新
|
||||
|
||||
```kotlin
|
||||
// 更新前
|
||||
if (request.accountId <= 0) {
|
||||
return ResponseEntity.ok(ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID))
|
||||
}
|
||||
|
||||
// 更新后
|
||||
if (request.accountId <= 0) {
|
||||
return ResponseEntity.ok(ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID, messageSource = messageSource))
|
||||
}
|
||||
|
||||
// 更新前
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
|
||||
// 更新后
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
```
|
||||
|
||||
## 验证
|
||||
|
||||
更新完成后,检查:
|
||||
|
||||
1. ✅ 所有 Controller 都注入了 MessageSource
|
||||
2. ✅ 所有 ApiResponse.error() 调用都传入了 messageSource 参数
|
||||
3. ✅ 编译无错误
|
||||
4. ✅ 测试 API 响应消息是否正确显示对应语言
|
||||
|
||||
## 快速更新脚本(参考)
|
||||
|
||||
可以使用以下模式批量更新:
|
||||
|
||||
```bash
|
||||
# 在 IDE 中使用正则表达式查找替换
|
||||
# 查找:ApiResponse\.error\(ErrorCode\.(\w+)\)\)
|
||||
# 替换:ApiResponse.error(ErrorCode.$1, messageSource = messageSource)
|
||||
|
||||
# 查找:ApiResponse\.error\(ErrorCode\.(\w+),\s*([^,)]+)\)\)
|
||||
# 替换:ApiResponse.error(ErrorCode.$1, $2, messageSource)
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **自定义消息**:如果错误消息是硬编码的中文,建议:
|
||||
- 优先使用 ErrorCode 的 messageKey(已在语言包中翻译)
|
||||
- 如果必须使用自定义消息,确保消息本身也需要国际化(通过 MessageUtils.getMessage())
|
||||
|
||||
2. **向后兼容**:如果前端没有发送语言 Header,后端会使用默认语言(英文)
|
||||
|
||||
3. **测试**:更新后测试不同语言下的错误消息显示
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
# 多语言支持实现状态
|
||||
|
||||
## ✅ 已完成的工作
|
||||
|
||||
### 后端部分(100% 完成)
|
||||
|
||||
#### 1. 核心框架 ✅
|
||||
- ✅ 创建语言资源文件(messages_zh_CN.properties, messages_zh_TW.properties, messages_en.properties)
|
||||
- ✅ 配置 MessageSource Bean(MessageSourceConfig.kt)
|
||||
- ✅ 创建 LocaleInterceptor 拦截器
|
||||
- ✅ 修改 ErrorCode 枚举,添加 messageKey 字段(100+ 条错误消息)
|
||||
- ✅ 修改 ApiResponse.error() 方法,支持多语言
|
||||
- ✅ 创建 MessageUtils 工具类
|
||||
- ✅ 更新 WebMvcConfig,注册 LocaleInterceptor
|
||||
|
||||
#### 2. Controller 更新 ✅(全部完成)
|
||||
- ✅ AccountController - 完全更新
|
||||
- ✅ AuthController - 完全更新
|
||||
- ✅ LeaderController - 完全更新
|
||||
- ✅ UserController - 完全更新
|
||||
- ✅ CopyTradingController - 完全更新
|
||||
- ✅ CopyTradingTemplateController - 完全更新
|
||||
- ✅ MarketController - 完全更新
|
||||
- ✅ CopyTradingStatisticsController - 完全更新(包含 CopyOrderTrackingController)
|
||||
- ✅ ProxyConfigController - 完全更新
|
||||
- ✅ HealthController - 无需更新(无错误响应)
|
||||
|
||||
#### 3. 编译状态 ✅
|
||||
- ✅ 后端编译通过,无错误
|
||||
- ✅ 所有 ApiResponse.error() 调用都已传入 messageSource 参数
|
||||
|
||||
### 前端部分(部分完成)
|
||||
|
||||
#### 1. 核心框架 ✅
|
||||
- ✅ 安装 i18next 和 react-i18next 依赖
|
||||
- ✅ 配置 i18n(语言检测、资源加载)
|
||||
- ✅ 创建语言包文件结构(zh-CN, zh-TW, en)
|
||||
- ✅ 在 api.ts 中添加语言 Header(X-Language)
|
||||
- ✅ 在 main.tsx 中初始化 i18n
|
||||
|
||||
#### 2. 页面更新 ✅(2个页面已完成)
|
||||
- ✅ AccountDetail.tsx - 完全使用 i18n
|
||||
- ✅ App.tsx - 订单推送通知已使用 i18n,Ant Design locale 已配置
|
||||
- ✅ Login.tsx - 完全使用 i18n
|
||||
|
||||
#### 3. 语言包扩展 ✅
|
||||
- ✅ 添加了登录相关翻译(login.*)
|
||||
- ✅ 添加了订单相关翻译(order.*)
|
||||
- ✅ 添加了账户相关翻译(account.*)
|
||||
- ✅ 添加了通用翻译(common.*)
|
||||
|
||||
#### 4. 编译状态 ✅
|
||||
- ✅ 前端编译通过,无错误
|
||||
- ⚠️ 有 5 个 TypeScript linter 警告(文件存在,可能是缓存问题)
|
||||
|
||||
## ⏳ 待完成的工作
|
||||
|
||||
### 前端部分(21个页面待更新)
|
||||
|
||||
需要更新以下页面组件,使用 `useTranslation` Hook 替换硬编码文本:
|
||||
|
||||
1. AccountList.tsx
|
||||
2. AccountImport.tsx
|
||||
3. AccountEdit.tsx
|
||||
4. LeaderList.tsx
|
||||
5. LeaderAdd.tsx
|
||||
6. LeaderEdit.tsx
|
||||
7. TemplateList.tsx
|
||||
8. TemplateAdd.tsx
|
||||
9. TemplateEdit.tsx
|
||||
10. CopyTradingList.tsx
|
||||
11. CopyTradingAdd.tsx
|
||||
12. CopyTradingStatistics.tsx
|
||||
13. CopyTradingBuyOrders.tsx
|
||||
14. CopyTradingSellOrders.tsx
|
||||
15. CopyTradingMatchedOrders.tsx
|
||||
16. PositionList.tsx
|
||||
17. OrderList.tsx
|
||||
18. Statistics.tsx
|
||||
19. UserList.tsx
|
||||
20. ResetPassword.tsx
|
||||
21. SystemSettings.tsx
|
||||
22. ConfigPage.tsx
|
||||
|
||||
### 语言包扩展
|
||||
|
||||
根据页面内容,可能需要添加更多翻译键:
|
||||
- Leader 相关翻译
|
||||
- Template 相关翻译
|
||||
- CopyTrading 相关翻译
|
||||
- Position 相关翻译
|
||||
- Statistics 相关翻译
|
||||
- 等等
|
||||
|
||||
## 测试建议
|
||||
|
||||
### 后端测试
|
||||
1. ✅ 编译通过
|
||||
2. ⏳ 测试不同语言 Header 下的错误消息显示
|
||||
3. ⏳ 测试默认语言(无 Header 时)
|
||||
|
||||
### 前端测试
|
||||
1. ✅ 编译通过
|
||||
2. ⏳ 测试系统语言自动检测
|
||||
3. ⏳ 测试语言切换(如果添加了切换功能)
|
||||
4. ⏳ 测试不同语言下的页面显示
|
||||
5. ⏳ 测试 API 请求是否正确传递语言 Header
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 后端
|
||||
所有 Controller 已更新,错误消息会自动根据 HTTP Header `X-Language` 或 `Accept-Language` 返回对应语言。
|
||||
|
||||
### 前端
|
||||
已更新的页面会自动根据系统语言显示对应文本。其他页面需要逐步更新。
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 逐步更新剩余的前端页面组件
|
||||
2. 根据页面内容扩展语言包
|
||||
3. 全面测试多语言功能
|
||||
4. (可选)添加语言切换组件
|
||||
|
||||
|
||||
|
||||
## ✅ 已完成的工作
|
||||
|
||||
### 后端部分(100% 完成)
|
||||
|
||||
#### 1. 核心框架 ✅
|
||||
- ✅ 创建语言资源文件(messages_zh_CN.properties, messages_zh_TW.properties, messages_en.properties)
|
||||
- ✅ 配置 MessageSource Bean(MessageSourceConfig.kt)
|
||||
- ✅ 创建 LocaleInterceptor 拦截器
|
||||
- ✅ 修改 ErrorCode 枚举,添加 messageKey 字段(100+ 条错误消息)
|
||||
- ✅ 修改 ApiResponse.error() 方法,支持多语言
|
||||
- ✅ 创建 MessageUtils 工具类
|
||||
- ✅ 更新 WebMvcConfig,注册 LocaleInterceptor
|
||||
|
||||
#### 2. Controller 更新 ✅(全部完成)
|
||||
- ✅ AccountController - 完全更新
|
||||
- ✅ AuthController - 完全更新
|
||||
- ✅ LeaderController - 完全更新
|
||||
- ✅ UserController - 完全更新
|
||||
- ✅ CopyTradingController - 完全更新
|
||||
- ✅ CopyTradingTemplateController - 完全更新
|
||||
- ✅ MarketController - 完全更新
|
||||
- ✅ CopyTradingStatisticsController - 完全更新(包含 CopyOrderTrackingController)
|
||||
- ✅ ProxyConfigController - 完全更新
|
||||
- ✅ HealthController - 无需更新(无错误响应)
|
||||
|
||||
#### 3. 编译状态 ✅
|
||||
- ✅ 后端编译通过,无错误
|
||||
- ✅ 所有 ApiResponse.error() 调用都已传入 messageSource 参数
|
||||
|
||||
### 前端部分(部分完成)
|
||||
|
||||
#### 1. 核心框架 ✅
|
||||
- ✅ 安装 i18next 和 react-i18next 依赖
|
||||
- ✅ 配置 i18n(语言检测、资源加载)
|
||||
- ✅ 创建语言包文件结构(zh-CN, zh-TW, en)
|
||||
- ✅ 在 api.ts 中添加语言 Header(X-Language)
|
||||
- ✅ 在 main.tsx 中初始化 i18n
|
||||
|
||||
#### 2. 页面更新 ✅(2个页面已完成)
|
||||
- ✅ AccountDetail.tsx - 完全使用 i18n
|
||||
- ✅ App.tsx - 订单推送通知已使用 i18n,Ant Design locale 已配置
|
||||
- ✅ Login.tsx - 完全使用 i18n
|
||||
|
||||
#### 3. 语言包扩展 ✅
|
||||
- ✅ 添加了登录相关翻译(login.*)
|
||||
- ✅ 添加了订单相关翻译(order.*)
|
||||
- ✅ 添加了账户相关翻译(account.*)
|
||||
- ✅ 添加了通用翻译(common.*)
|
||||
|
||||
#### 4. 编译状态 ✅
|
||||
- ✅ 前端编译通过,无错误
|
||||
- ⚠️ 有 5 个 TypeScript linter 警告(文件存在,可能是缓存问题)
|
||||
|
||||
## ⏳ 待完成的工作
|
||||
|
||||
### 前端部分(21个页面待更新)
|
||||
|
||||
需要更新以下页面组件,使用 `useTranslation` Hook 替换硬编码文本:
|
||||
|
||||
1. AccountList.tsx
|
||||
2. AccountImport.tsx
|
||||
3. AccountEdit.tsx
|
||||
4. LeaderList.tsx
|
||||
5. LeaderAdd.tsx
|
||||
6. LeaderEdit.tsx
|
||||
7. TemplateList.tsx
|
||||
8. TemplateAdd.tsx
|
||||
9. TemplateEdit.tsx
|
||||
10. CopyTradingList.tsx
|
||||
11. CopyTradingAdd.tsx
|
||||
12. CopyTradingStatistics.tsx
|
||||
13. CopyTradingBuyOrders.tsx
|
||||
14. CopyTradingSellOrders.tsx
|
||||
15. CopyTradingMatchedOrders.tsx
|
||||
16. PositionList.tsx
|
||||
17. OrderList.tsx
|
||||
18. Statistics.tsx
|
||||
19. UserList.tsx
|
||||
20. ResetPassword.tsx
|
||||
21. SystemSettings.tsx
|
||||
22. ConfigPage.tsx
|
||||
|
||||
### 语言包扩展
|
||||
|
||||
根据页面内容,可能需要添加更多翻译键:
|
||||
- Leader 相关翻译
|
||||
- Template 相关翻译
|
||||
- CopyTrading 相关翻译
|
||||
- Position 相关翻译
|
||||
- Statistics 相关翻译
|
||||
- 等等
|
||||
|
||||
## 测试建议
|
||||
|
||||
### 后端测试
|
||||
1. ✅ 编译通过
|
||||
2. ⏳ 测试不同语言 Header 下的错误消息显示
|
||||
3. ⏳ 测试默认语言(无 Header 时)
|
||||
|
||||
### 前端测试
|
||||
1. ✅ 编译通过
|
||||
2. ⏳ 测试系统语言自动检测
|
||||
3. ⏳ 测试语言切换(如果添加了切换功能)
|
||||
4. ⏳ 测试不同语言下的页面显示
|
||||
5. ⏳ 测试 API 请求是否正确传递语言 Header
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 后端
|
||||
所有 Controller 已更新,错误消息会自动根据 HTTP Header `X-Language` 或 `Accept-Language` 返回对应语言。
|
||||
|
||||
### 前端
|
||||
已更新的页面会自动根据系统语言显示对应文本。其他页面需要逐步更新。
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 逐步更新剩余的前端页面组件
|
||||
2. 根据页面内容扩展语言包
|
||||
3. 全面测试多语言功能
|
||||
4. (可选)添加语言切换组件
|
||||
|
||||
@@ -1,444 +0,0 @@
|
||||
# 多语言支持实现总结
|
||||
|
||||
## 已完成的工作
|
||||
|
||||
### 后端部分 ✅
|
||||
|
||||
1. **语言资源文件** (`backend/src/main/resources/i18n/`)
|
||||
- `messages_zh_CN.properties` - 简体中文
|
||||
- `messages_zh_TW.properties` - 繁体中文
|
||||
- `messages_en.properties` - 英文
|
||||
- 已翻译所有 ErrorCode 错误消息(100+ 条)
|
||||
|
||||
2. **配置类**
|
||||
- `MessageSourceConfig.kt` - 配置 MessageSource 和 LocaleResolver
|
||||
- `LocaleInterceptor.kt` - 从 HTTP Header 读取语言设置
|
||||
|
||||
3. **核心修改**
|
||||
- `ErrorCode.kt` - 添加 `messageKey` 字段,每个错误码都有对应的消息键
|
||||
- `ApiResponse.kt` - 支持多语言错误消息
|
||||
- `ApiResponseExt.kt` - 提供便捷的扩展函数
|
||||
- `MessageUtils.kt` - 消息工具类
|
||||
- `WebMvcConfig.kt` - 注册 LocaleInterceptor
|
||||
|
||||
4. **示例更新**
|
||||
- `AccountController.kt` - 已更新部分方法作为示例
|
||||
|
||||
### 前端部分 ✅
|
||||
|
||||
1. **依赖安装**
|
||||
- `i18next` 和 `react-i18next` 已安装
|
||||
|
||||
2. **i18n 配置** (`frontend/src/i18n/config.ts`)
|
||||
- 自动检测系统语言
|
||||
- 支持语言切换
|
||||
- 语言持久化到 localStorage
|
||||
|
||||
3. **语言包** (`frontend/src/locales/`)
|
||||
- `zh-CN/common.json` - 简体中文
|
||||
- `zh-TW/common.json` - 繁体中文
|
||||
- `en/common.json` - 英文
|
||||
- 已包含账户管理相关的基础翻译
|
||||
|
||||
4. **API 集成**
|
||||
- `api.ts` - 自动在请求头添加 `X-Language` Header
|
||||
|
||||
5. **示例页面**
|
||||
- `AccountDetail.tsx` - 已完全使用 i18n
|
||||
|
||||
## 待完成的工作
|
||||
|
||||
### 后端部分
|
||||
|
||||
需要更新所有 Controller,使用 `MessageUtils` 或扩展函数来获取国际化消息:
|
||||
|
||||
```kotlin
|
||||
// 方式1:使用扩展函数(推荐)
|
||||
@RestController
|
||||
class ExampleController(
|
||||
private val messageSource: MessageSource
|
||||
) {
|
||||
@PostMapping("/example")
|
||||
fun example(): ResponseEntity<ApiResponse<Unit>> {
|
||||
// 使用扩展函数,自动国际化
|
||||
return ResponseEntity.ok(
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 方式2:使用 MessageUtils
|
||||
@RestController
|
||||
class ExampleController(
|
||||
private val messageUtils: MessageUtils
|
||||
) {
|
||||
@PostMapping("/example")
|
||||
fun example(): ResponseEntity<ApiResponse<Unit>> {
|
||||
val msg = messageUtils.getMessage(ErrorCode.PARAM_ERROR)
|
||||
return ResponseEntity.ok(
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR.code, msg)
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
需要更新的 Controller:
|
||||
- `AuthController.kt`
|
||||
- `LeaderController.kt`
|
||||
- `CopyTradingController.kt`
|
||||
- `CopyTradingTemplateController.kt`
|
||||
- `CopyTradingStatisticsController.kt`
|
||||
- `MarketController.kt`
|
||||
- `UserController.kt`
|
||||
- `ProxyConfigController.kt`
|
||||
- `AccountController.kt` (部分方法已更新,需要完成剩余部分)
|
||||
|
||||
### 前端部分
|
||||
|
||||
需要更新所有页面组件,使用 `useTranslation` Hook:
|
||||
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const MyComponent: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button>{t('common.save')}</Button>
|
||||
<div>{t('account.accountName')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
需要更新的页面:
|
||||
- `AccountList.tsx`
|
||||
- `AccountImport.tsx`
|
||||
- `AccountEdit.tsx`
|
||||
- `LeaderList.tsx`
|
||||
- `LeaderAdd.tsx`
|
||||
- `LeaderEdit.tsx`
|
||||
- `TemplateList.tsx`
|
||||
- `TemplateAdd.tsx`
|
||||
- `TemplateEdit.tsx`
|
||||
- `CopyTradingList.tsx`
|
||||
- `CopyTradingAdd.tsx`
|
||||
- `Login.tsx`
|
||||
- `UserList.tsx`
|
||||
- 以及其他所有页面
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 后端使用
|
||||
|
||||
1. **在 Controller 中注入 MessageSource**:
|
||||
```kotlin
|
||||
@RestController
|
||||
class MyController(
|
||||
private val messageSource: MessageSource
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
2. **使用扩展函数创建错误响应**:
|
||||
```kotlin
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
```
|
||||
|
||||
3. **自定义消息(如果需要)**:
|
||||
```kotlin
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息", messageSource)
|
||||
```
|
||||
|
||||
### 前端使用
|
||||
|
||||
1. **在组件中使用 useTranslation**:
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const { t } = useTranslation()
|
||||
```
|
||||
|
||||
2. **翻译文本**:
|
||||
```typescript
|
||||
t('common.save') // 返回当前语言的"保存"
|
||||
t('account.accountName') // 返回当前语言的"账户名称"
|
||||
```
|
||||
|
||||
3. **切换语言**(可选):
|
||||
```typescript
|
||||
import { changeLanguage } from '../i18n/config'
|
||||
|
||||
changeLanguage('zh-CN') // 切换到简体中文
|
||||
changeLanguage('zh-TW') // 切换到繁体中文
|
||||
changeLanguage('en') // 切换到英文
|
||||
```
|
||||
|
||||
## 语言检测规则
|
||||
|
||||
### 前端
|
||||
1. 优先使用 localStorage 中保存的语言设置
|
||||
2. 如果没有,检测系统语言:
|
||||
- `zh-CN`, `zh` → 简体中文
|
||||
- `zh-TW`, `zh-HK`, `zh-MO` → 繁体中文
|
||||
- 其他 → 英文(默认)
|
||||
|
||||
### 后端
|
||||
1. 从 HTTP Header 读取:
|
||||
- `X-Language` (优先)
|
||||
- `Accept-Language` (备选)
|
||||
2. 语言映射规则同前端
|
||||
3. 默认语言:英文
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. **测试语言检测**:
|
||||
- 修改浏览器语言设置,刷新页面,检查是否自动切换
|
||||
- 测试不同语言下的 API 响应消息
|
||||
|
||||
2. **测试语言切换**:
|
||||
- 在前端添加语言切换组件(可选)
|
||||
- 测试切换后 API 请求是否正确传递语言 Header
|
||||
|
||||
3. **测试错误消息**:
|
||||
- 触发各种错误,检查错误消息是否正确显示对应语言
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **向后兼容**:如果前端没有发送语言 Header,后端默认使用英文
|
||||
2. **消息键命名**:所有消息键使用 `error.` 前缀,便于管理
|
||||
3. **翻译质量**:建议由专业翻译人员审核翻译内容
|
||||
4. **性能**:语言包已配置缓存,不会影响性能
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 完成所有 Controller 的更新
|
||||
2. 完成所有前端页面的翻译
|
||||
3. 添加语言切换组件(可选)
|
||||
4. 全面测试多语言功能
|
||||
5. 更新 API 文档,说明语言 Header 的使用
|
||||
|
||||
|
||||
|
||||
## 已完成的工作
|
||||
|
||||
### 后端部分 ✅
|
||||
|
||||
1. **语言资源文件** (`backend/src/main/resources/i18n/`)
|
||||
- `messages_zh_CN.properties` - 简体中文
|
||||
- `messages_zh_TW.properties` - 繁体中文
|
||||
- `messages_en.properties` - 英文
|
||||
- 已翻译所有 ErrorCode 错误消息(100+ 条)
|
||||
|
||||
2. **配置类**
|
||||
- `MessageSourceConfig.kt` - 配置 MessageSource 和 LocaleResolver
|
||||
- `LocaleInterceptor.kt` - 从 HTTP Header 读取语言设置
|
||||
|
||||
3. **核心修改**
|
||||
- `ErrorCode.kt` - 添加 `messageKey` 字段,每个错误码都有对应的消息键
|
||||
- `ApiResponse.kt` - 支持多语言错误消息
|
||||
- `ApiResponseExt.kt` - 提供便捷的扩展函数
|
||||
- `MessageUtils.kt` - 消息工具类
|
||||
- `WebMvcConfig.kt` - 注册 LocaleInterceptor
|
||||
|
||||
4. **示例更新**
|
||||
- `AccountController.kt` - 已更新部分方法作为示例
|
||||
|
||||
### 前端部分 ✅
|
||||
|
||||
1. **依赖安装**
|
||||
- `i18next` 和 `react-i18next` 已安装
|
||||
|
||||
2. **i18n 配置** (`frontend/src/i18n/config.ts`)
|
||||
- 自动检测系统语言
|
||||
- 支持语言切换
|
||||
- 语言持久化到 localStorage
|
||||
|
||||
3. **语言包** (`frontend/src/locales/`)
|
||||
- `zh-CN/common.json` - 简体中文
|
||||
- `zh-TW/common.json` - 繁体中文
|
||||
- `en/common.json` - 英文
|
||||
- 已包含账户管理相关的基础翻译
|
||||
|
||||
4. **API 集成**
|
||||
- `api.ts` - 自动在请求头添加 `X-Language` Header
|
||||
|
||||
5. **示例页面**
|
||||
- `AccountDetail.tsx` - 已完全使用 i18n
|
||||
|
||||
## 待完成的工作
|
||||
|
||||
### 后端部分
|
||||
|
||||
需要更新所有 Controller,使用 `MessageUtils` 或扩展函数来获取国际化消息:
|
||||
|
||||
```kotlin
|
||||
// 方式1:使用扩展函数(推荐)
|
||||
@RestController
|
||||
class ExampleController(
|
||||
private val messageSource: MessageSource
|
||||
) {
|
||||
@PostMapping("/example")
|
||||
fun example(): ResponseEntity<ApiResponse<Unit>> {
|
||||
// 使用扩展函数,自动国际化
|
||||
return ResponseEntity.ok(
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 方式2:使用 MessageUtils
|
||||
@RestController
|
||||
class ExampleController(
|
||||
private val messageUtils: MessageUtils
|
||||
) {
|
||||
@PostMapping("/example")
|
||||
fun example(): ResponseEntity<ApiResponse<Unit>> {
|
||||
val msg = messageUtils.getMessage(ErrorCode.PARAM_ERROR)
|
||||
return ResponseEntity.ok(
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR.code, msg)
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
需要更新的 Controller:
|
||||
- `AuthController.kt`
|
||||
- `LeaderController.kt`
|
||||
- `CopyTradingController.kt`
|
||||
- `CopyTradingTemplateController.kt`
|
||||
- `CopyTradingStatisticsController.kt`
|
||||
- `MarketController.kt`
|
||||
- `UserController.kt`
|
||||
- `ProxyConfigController.kt`
|
||||
- `AccountController.kt` (部分方法已更新,需要完成剩余部分)
|
||||
|
||||
### 前端部分
|
||||
|
||||
需要更新所有页面组件,使用 `useTranslation` Hook:
|
||||
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const MyComponent: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button>{t('common.save')}</Button>
|
||||
<div>{t('account.accountName')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
需要更新的页面:
|
||||
- `AccountList.tsx`
|
||||
- `AccountImport.tsx`
|
||||
- `AccountEdit.tsx`
|
||||
- `LeaderList.tsx`
|
||||
- `LeaderAdd.tsx`
|
||||
- `LeaderEdit.tsx`
|
||||
- `TemplateList.tsx`
|
||||
- `TemplateAdd.tsx`
|
||||
- `TemplateEdit.tsx`
|
||||
- `CopyTradingList.tsx`
|
||||
- `CopyTradingAdd.tsx`
|
||||
- `Login.tsx`
|
||||
- `UserList.tsx`
|
||||
- 以及其他所有页面
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 后端使用
|
||||
|
||||
1. **在 Controller 中注入 MessageSource**:
|
||||
```kotlin
|
||||
@RestController
|
||||
class MyController(
|
||||
private val messageSource: MessageSource
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
2. **使用扩展函数创建错误响应**:
|
||||
```kotlin
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
```
|
||||
|
||||
3. **自定义消息(如果需要)**:
|
||||
```kotlin
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, "自定义消息", messageSource)
|
||||
```
|
||||
|
||||
### 前端使用
|
||||
|
||||
1. **在组件中使用 useTranslation**:
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const { t } = useTranslation()
|
||||
```
|
||||
|
||||
2. **翻译文本**:
|
||||
```typescript
|
||||
t('common.save') // 返回当前语言的"保存"
|
||||
t('account.accountName') // 返回当前语言的"账户名称"
|
||||
```
|
||||
|
||||
3. **切换语言**(可选):
|
||||
```typescript
|
||||
import { changeLanguage } from '../i18n/config'
|
||||
|
||||
changeLanguage('zh-CN') // 切换到简体中文
|
||||
changeLanguage('zh-TW') // 切换到繁体中文
|
||||
changeLanguage('en') // 切换到英文
|
||||
```
|
||||
|
||||
## 语言检测规则
|
||||
|
||||
### 前端
|
||||
1. 优先使用 localStorage 中保存的语言设置
|
||||
2. 如果没有,检测系统语言:
|
||||
- `zh-CN`, `zh` → 简体中文
|
||||
- `zh-TW`, `zh-HK`, `zh-MO` → 繁体中文
|
||||
- 其他 → 英文(默认)
|
||||
|
||||
### 后端
|
||||
1. 从 HTTP Header 读取:
|
||||
- `X-Language` (优先)
|
||||
- `Accept-Language` (备选)
|
||||
2. 语言映射规则同前端
|
||||
3. 默认语言:英文
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. **测试语言检测**:
|
||||
- 修改浏览器语言设置,刷新页面,检查是否自动切换
|
||||
- 测试不同语言下的 API 响应消息
|
||||
|
||||
2. **测试语言切换**:
|
||||
- 在前端添加语言切换组件(可选)
|
||||
- 测试切换后 API 请求是否正确传递语言 Header
|
||||
|
||||
3. **测试错误消息**:
|
||||
- 触发各种错误,检查错误消息是否正确显示对应语言
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **向后兼容**:如果前端没有发送语言 Header,后端默认使用英文
|
||||
2. **消息键命名**:所有消息键使用 `error.` 前缀,便于管理
|
||||
3. **翻译质量**:建议由专业翻译人员审核翻译内容
|
||||
4. **性能**:语言包已配置缓存,不会影响性能
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 完成所有 Controller 的更新
|
||||
2. 完成所有前端页面的翻译
|
||||
3. 添加语言切换组件(可选)
|
||||
4. 全面测试多语言功能
|
||||
5. 更新 API 文档,说明语言 Header 的使用
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# 前端语言切换功能实现总结
|
||||
|
||||
## ✅ 已完成的工作
|
||||
|
||||
### 1. 语言切换组件 ✅
|
||||
- **文件**: `frontend/src/components/LanguageSwitcher.tsx`
|
||||
- **功能**:
|
||||
- 显示当前语言(简体中文、繁體中文、English)
|
||||
- 支持手动切换语言
|
||||
- 切换后自动刷新页面以应用 Ant Design 的 locale
|
||||
- 支持移动端和桌面端响应式设计
|
||||
|
||||
### 2. Layout 组件集成 ✅
|
||||
- **文件**: `frontend/src/components/Layout.tsx`
|
||||
- **更新内容**:
|
||||
- 在移动端 Header 中添加了语言切换器
|
||||
- 在桌面端 Sider 中添加了语言切换器
|
||||
- 菜单项已使用 i18n 翻译(menu.*)
|
||||
- 退出登录确认对话框已使用 i18n
|
||||
|
||||
### 3. i18n 配置优化 ✅
|
||||
- **文件**: `frontend/src/i18n/config.ts`
|
||||
- **功能**:
|
||||
- 自动检测系统语言
|
||||
- 优先使用 localStorage 中保存的用户选择
|
||||
- 提供 `changeLanguage()` 函数用于手动切换
|
||||
- 提供 `getCurrentLanguage()` 函数获取当前语言
|
||||
|
||||
### 4. 语言包扩展 ✅
|
||||
- **新增翻译键**: `menu.*`
|
||||
- `menu.accounts`: 账户管理
|
||||
- `menu.copyTrading`: 跟单交易
|
||||
- `menu.leaders`: Leader 管理
|
||||
- `menu.templates`: 跟单模板
|
||||
- `menu.copyTradingConfig`: 跟单配置
|
||||
- `menu.positions`: 仓位管理
|
||||
- `menu.statistics`: 统计信息
|
||||
- `menu.users`: 用户管理
|
||||
- `menu.systemSettings`: 系统管理
|
||||
- `menu.logout`: 退出登录
|
||||
- `menu.logoutConfirm`: 确认退出
|
||||
- `menu.logoutConfirmDesc`: 确定要退出登录吗?
|
||||
- `menu.navigation`: 导航菜单
|
||||
|
||||
### 5. API 请求同步 ✅
|
||||
- **文件**: `frontend/src/services/api.ts`
|
||||
- **功能**: 自动在请求头中添加 `X-Language`,与后端语言保持一致
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 用户操作
|
||||
1. 在页面右上角(桌面端)或 Header(移动端)找到语言切换器
|
||||
2. 点击下拉菜单选择语言:
|
||||
- 简体中文
|
||||
- 繁體中文
|
||||
- English
|
||||
3. 选择后页面会自动刷新,应用新语言
|
||||
|
||||
### 技术实现
|
||||
- 语言选择保存在 `localStorage` 的 `i18n_language` 键中
|
||||
- 切换语言后自动刷新页面,确保:
|
||||
- Ant Design 的 locale 正确应用
|
||||
- 所有组件重新渲染,使用新语言
|
||||
- API 请求自动携带新语言 Header
|
||||
|
||||
## 编译状态
|
||||
- ✅ 前端编译通过,无错误
|
||||
- ✅ 所有组件正常工作
|
||||
|
||||
## 位置说明
|
||||
|
||||
### 桌面端
|
||||
- 语言切换器位于左侧导航栏顶部(PolyHermes 标题旁边)
|
||||
|
||||
### 移动端
|
||||
- 语言切换器位于顶部 Header 右侧(GitHub 和 Twitter 图标之前)
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **无需刷新页面切换**(可选):
|
||||
- 当前实现需要刷新页面以确保 Ant Design locale 正确应用
|
||||
- 未来可以考虑动态更新 ConfigProvider 的 locale,避免刷新
|
||||
|
||||
2. **语言图标优化**(可选):
|
||||
- 可以使用国旗图标或语言缩写(如 CN、TW、EN)代替文字
|
||||
|
||||
3. **语言切换动画**(可选):
|
||||
- 添加平滑的切换动画,提升用户体验
|
||||
|
||||
@@ -1,572 +0,0 @@
|
||||
# 多语言支持遗漏工作清单
|
||||
|
||||
## 后端遗漏工作
|
||||
|
||||
### ❌ 需要更新的 Controller
|
||||
|
||||
#### 1. CopyTradingController
|
||||
- ✅ 已添加 MessageSource 依赖注入
|
||||
- ❌ **所有 ApiResponse.error() 调用都缺少 messageSource 参数**
|
||||
- 第 31 行:`ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID)` → 需要添加 `, messageSource = messageSource`
|
||||
- 第 34 行:`ApiResponse.error(ErrorCode.PARAM_TEMPLATE_ID_INVALID)` → 需要添加
|
||||
- 第 37 行:`ApiResponse.error(ErrorCode.PARAM_LEADER_ID_INVALID)` → 需要添加
|
||||
- 第 48-49 行:`ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)` → 需要添加 `, messageSource`
|
||||
- 第 55 行:`ApiResponse.error(ErrorCode.SERVER_COPY_TRADING_CREATE_FAILED, e.message)` → 需要添加
|
||||
- 第 72, 77 行:查询列表的错误响应 → 需要添加
|
||||
- 第 88, 99-101, 107 行:更新状态的错误响应 → 需要添加
|
||||
- 第 118, 129-130, 136 行:删除的错误响应 → 需要添加
|
||||
- 第 147, 158-159, 165 行:查询模板的错误响应 → 需要添加
|
||||
|
||||
#### 2. CopyTradingTemplateController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 需要添加:`private val messageSource: MessageSource`
|
||||
- 需要添加导入:`import com.wrbug.polymarketbot.util.error`
|
||||
- 所有 `ApiResponse.error()` 调用都需要添加 `messageSource` 参数
|
||||
|
||||
#### 3. MarketController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 34 行:`ApiResponse.error(ErrorCode.PARAM_MARKET_ID_EMPTY)`
|
||||
- 第 44, 49 行:`ApiResponse.error(ErrorCode.SERVER_MARKET_PRICE_FETCH_FAILED, e.message)`
|
||||
- 第 62 行:`ApiResponse.error(ErrorCode.PARAM_TOKEN_ID_EMPTY)`
|
||||
- 第 72, 77 行:`ApiResponse.error(ErrorCode.SERVER_MARKET_LATEST_PRICE_FETCH_FAILED, e.message)`
|
||||
|
||||
#### 4. CopyTradingStatisticsController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 31 行:`ApiResponse.error(ErrorCode.PARAM_COPY_TRADING_ID_INVALID)`
|
||||
- 第 42-43, 49 行:统计查询的错误响应
|
||||
- 需要检查整个文件的所有错误响应
|
||||
|
||||
#### 5. ProxyConfigController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 35 行:`ApiResponse.error(ErrorCode.SERVER_ERROR, "获取代理配置失败:${e.message}")`
|
||||
- 第 49 行:`ApiResponse.error(ErrorCode.SERVER_ERROR, "获取代理配置列表失败:${e.message}")`
|
||||
- 需要检查整个文件的所有错误响应
|
||||
|
||||
#### 6. HealthController
|
||||
- ✅ **不需要更新**(没有错误响应,只有健康检查)
|
||||
|
||||
### 更新模式
|
||||
|
||||
对于每个 Controller,需要:
|
||||
|
||||
1. **添加导入**:
|
||||
```kotlin
|
||||
import com.wrbug.polymarketbot.util.error
|
||||
import org.springframework.context.MessageSource
|
||||
```
|
||||
|
||||
2. **添加依赖注入**:
|
||||
```kotlin
|
||||
class YourController(
|
||||
private val yourService: YourService,
|
||||
private val messageSource: MessageSource // 添加这一行
|
||||
)
|
||||
```
|
||||
|
||||
3. **更新所有 ApiResponse.error() 调用**:
|
||||
```kotlin
|
||||
// 模式1:只有 ErrorCode
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR)
|
||||
→ ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
|
||||
// 模式2:ErrorCode + 消息
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
→ ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
```
|
||||
|
||||
## 前端遗漏工作
|
||||
|
||||
### ❌ 需要更新的页面组件(23个页面,只有1个已更新)
|
||||
|
||||
#### ✅ 已完成的页面
|
||||
1. **AccountDetail.tsx** - 已完全使用 i18n
|
||||
|
||||
#### ❌ 待更新的页面(22个)
|
||||
|
||||
1. **Login.tsx**
|
||||
- 硬编码文本:`'登录成功'`, `'登录失败'`, `'用户名'`, `'密码'` 等
|
||||
- 需要添加:`import { useTranslation } from 'react-i18next'`
|
||||
- 需要添加:`const { t } = useTranslation()`
|
||||
- 需要替换所有硬编码文本
|
||||
|
||||
2. **AccountList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
3. **AccountImport.tsx**
|
||||
- 硬编码文本:`'钱包地址与私钥不匹配'`, `'钱包地址格式不正确'`, `'钱包地址'` 等
|
||||
- 需要更新
|
||||
|
||||
4. **AccountEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
5. **LeaderList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
6. **LeaderAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
7. **LeaderEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
8. **TemplateList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
9. **TemplateAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
10. **TemplateEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
11. **CopyTradingList.tsx**
|
||||
- 硬编码文本:`'删除跟单成功'`, `'删除跟单失败'`, `'钱包'`, `'模板'`, `'Leader'`, `'取消'`, `'订单'` 等
|
||||
- 需要更新
|
||||
|
||||
12. **CopyTradingAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
13. **CopyTradingStatistics.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
14. **CopyTradingBuyOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
15. **CopyTradingSellOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
16. **CopyTradingMatchedOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
17. **PositionList.tsx**
|
||||
- 硬编码文本:`'账户'`, `'市场'`, `'搜索账户、市场、方向...'`, `'确认卖出'`, `'取消'`, `'订单类型'`, `'确认赎回'` 等
|
||||
- 需要更新
|
||||
|
||||
18. **OrderList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
19. **Statistics.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
20. **UserList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
21. **ResetPassword.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
22. **SystemSettings.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
23. **ConfigPage.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
### App.tsx 中的硬编码文本
|
||||
|
||||
**App.tsx** 中有硬编码的中文文本:
|
||||
- 第 61 行:`'订单创建'`
|
||||
- 第 63 行:`'订单更新'`
|
||||
- 第 65 行:`'订单取消'`
|
||||
- 第 67 行:`'订单事件'`
|
||||
- 第 79 行:`'买入'`, `'卖出'`
|
||||
- 第 92 行:`'市场:'`, `'状态:'`, `'已成交:'`, `'剩余:'`
|
||||
|
||||
需要:
|
||||
1. 添加 `import { useTranslation } from 'react-i18next'`
|
||||
2. 在组件中使用 `const { t } = useTranslation()`
|
||||
3. 替换所有硬编码文本
|
||||
|
||||
### 前端更新模式
|
||||
|
||||
对于每个页面组件:
|
||||
|
||||
1. **添加导入**:
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
```
|
||||
|
||||
2. **在组件中使用**:
|
||||
```typescript
|
||||
const YourComponent: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
3. **替换硬编码文本**:
|
||||
```typescript
|
||||
// 旧代码
|
||||
<Button>保存</Button>
|
||||
message.success('操作成功')
|
||||
|
||||
// 新代码
|
||||
<Button>{t('common.save')}</Button>
|
||||
message.success(t('message.operationSuccess'))
|
||||
```
|
||||
|
||||
4. **扩展语言包**:
|
||||
- 在 `frontend/src/locales/*/common.json` 中添加缺失的翻译键
|
||||
- 确保三个语言包(zh-CN, zh-TW, en)都有对应的翻译
|
||||
|
||||
## 语言包扩展
|
||||
|
||||
### 需要添加的翻译键
|
||||
|
||||
根据检查,需要在语言包中添加以下键:
|
||||
|
||||
```json
|
||||
{
|
||||
"order": {
|
||||
"create": "订单创建",
|
||||
"update": "订单更新",
|
||||
"cancel": "订单取消",
|
||||
"event": "订单事件",
|
||||
"buy": "买入",
|
||||
"sell": "卖出",
|
||||
"market": "市场",
|
||||
"status": "状态",
|
||||
"filled": "已成交",
|
||||
"remaining": "剩余"
|
||||
},
|
||||
"wallet": {
|
||||
"address": "钱包地址",
|
||||
"addressMismatch": "钱包地址与私钥不匹配",
|
||||
"addressInvalid": "钱包地址格式不正确"
|
||||
},
|
||||
"copyTrading": {
|
||||
"deleteSuccess": "删除跟单成功",
|
||||
"deleteFailed": "删除跟单失败",
|
||||
"wallet": "钱包",
|
||||
"template": "模板",
|
||||
"leader": "Leader"
|
||||
},
|
||||
"position": {
|
||||
"account": "账户",
|
||||
"market": "市场",
|
||||
"searchPlaceholder": "搜索账户、市场、方向...",
|
||||
"confirmSell": "确认卖出",
|
||||
"confirmRedeem": "确认赎回",
|
||||
"orderType": "订单类型"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 优先级建议
|
||||
|
||||
### 高优先级(核心功能)
|
||||
1. ✅ 后端:完成所有 Controller 的 MessageSource 更新
|
||||
2. ✅ 前端:更新 Login.tsx(登录页面)
|
||||
3. ✅ 前端:更新 App.tsx(全局通知)
|
||||
|
||||
### 中优先级(常用功能)
|
||||
4. 前端:更新 AccountList.tsx, AccountImport.tsx
|
||||
5. 前端:更新 LeaderList.tsx, LeaderAdd.tsx
|
||||
6. 前端:更新 CopyTradingList.tsx
|
||||
|
||||
### 低优先级(其他页面)
|
||||
7. 前端:逐步更新其他页面组件
|
||||
|
||||
## 验证清单
|
||||
|
||||
完成后检查:
|
||||
|
||||
### 后端
|
||||
- [ ] 所有 Controller 都注入了 MessageSource
|
||||
- [ ] 所有 ApiResponse.error() 调用都传入了 messageSource
|
||||
- [ ] 编译无错误
|
||||
- [ ] 测试不同语言下的错误消息
|
||||
|
||||
### 前端
|
||||
- [ ] 所有页面都使用了 useTranslation
|
||||
- [ ] 所有硬编码文本都已替换
|
||||
- [ ] 语言包包含所有需要的翻译键
|
||||
- [ ] 测试不同语言下的页面显示
|
||||
- [ ] 测试语言切换功能
|
||||
|
||||
|
||||
|
||||
## 后端遗漏工作
|
||||
|
||||
### ❌ 需要更新的 Controller
|
||||
|
||||
#### 1. CopyTradingController
|
||||
- ✅ 已添加 MessageSource 依赖注入
|
||||
- ❌ **所有 ApiResponse.error() 调用都缺少 messageSource 参数**
|
||||
- 第 31 行:`ApiResponse.error(ErrorCode.PARAM_ACCOUNT_ID_INVALID)` → 需要添加 `, messageSource = messageSource`
|
||||
- 第 34 行:`ApiResponse.error(ErrorCode.PARAM_TEMPLATE_ID_INVALID)` → 需要添加
|
||||
- 第 37 行:`ApiResponse.error(ErrorCode.PARAM_LEADER_ID_INVALID)` → 需要添加
|
||||
- 第 48-49 行:`ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)` → 需要添加 `, messageSource`
|
||||
- 第 55 行:`ApiResponse.error(ErrorCode.SERVER_COPY_TRADING_CREATE_FAILED, e.message)` → 需要添加
|
||||
- 第 72, 77 行:查询列表的错误响应 → 需要添加
|
||||
- 第 88, 99-101, 107 行:更新状态的错误响应 → 需要添加
|
||||
- 第 118, 129-130, 136 行:删除的错误响应 → 需要添加
|
||||
- 第 147, 158-159, 165 行:查询模板的错误响应 → 需要添加
|
||||
|
||||
#### 2. CopyTradingTemplateController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 需要添加:`private val messageSource: MessageSource`
|
||||
- 需要添加导入:`import com.wrbug.polymarketbot.util.error`
|
||||
- 所有 `ApiResponse.error()` 调用都需要添加 `messageSource` 参数
|
||||
|
||||
#### 3. MarketController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 34 行:`ApiResponse.error(ErrorCode.PARAM_MARKET_ID_EMPTY)`
|
||||
- 第 44, 49 行:`ApiResponse.error(ErrorCode.SERVER_MARKET_PRICE_FETCH_FAILED, e.message)`
|
||||
- 第 62 行:`ApiResponse.error(ErrorCode.PARAM_TOKEN_ID_EMPTY)`
|
||||
- 第 72, 77 行:`ApiResponse.error(ErrorCode.SERVER_MARKET_LATEST_PRICE_FETCH_FAILED, e.message)`
|
||||
|
||||
#### 4. CopyTradingStatisticsController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 31 行:`ApiResponse.error(ErrorCode.PARAM_COPY_TRADING_ID_INVALID)`
|
||||
- 第 42-43, 49 行:统计查询的错误响应
|
||||
- 需要检查整个文件的所有错误响应
|
||||
|
||||
#### 5. ProxyConfigController
|
||||
- ❌ **未添加 MessageSource 依赖注入**
|
||||
- ❌ **所有 ApiResponse.error() 调用都需要更新**
|
||||
- 第 35 行:`ApiResponse.error(ErrorCode.SERVER_ERROR, "获取代理配置失败:${e.message}")`
|
||||
- 第 49 行:`ApiResponse.error(ErrorCode.SERVER_ERROR, "获取代理配置列表失败:${e.message}")`
|
||||
- 需要检查整个文件的所有错误响应
|
||||
|
||||
#### 6. HealthController
|
||||
- ✅ **不需要更新**(没有错误响应,只有健康检查)
|
||||
|
||||
### 更新模式
|
||||
|
||||
对于每个 Controller,需要:
|
||||
|
||||
1. **添加导入**:
|
||||
```kotlin
|
||||
import com.wrbug.polymarketbot.util.error
|
||||
import org.springframework.context.MessageSource
|
||||
```
|
||||
|
||||
2. **添加依赖注入**:
|
||||
```kotlin
|
||||
class YourController(
|
||||
private val yourService: YourService,
|
||||
private val messageSource: MessageSource // 添加这一行
|
||||
)
|
||||
```
|
||||
|
||||
3. **更新所有 ApiResponse.error() 调用**:
|
||||
```kotlin
|
||||
// 模式1:只有 ErrorCode
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR)
|
||||
→ ApiResponse.error(ErrorCode.PARAM_ERROR, messageSource = messageSource)
|
||||
|
||||
// 模式2:ErrorCode + 消息
|
||||
ApiResponse.error(ErrorCode.PARAM_ERROR, e.message)
|
||||
→ ApiResponse.error(ErrorCode.PARAM_ERROR, e.message, messageSource)
|
||||
```
|
||||
|
||||
## 前端遗漏工作
|
||||
|
||||
### ❌ 需要更新的页面组件(23个页面,只有1个已更新)
|
||||
|
||||
#### ✅ 已完成的页面
|
||||
1. **AccountDetail.tsx** - 已完全使用 i18n
|
||||
|
||||
#### ❌ 待更新的页面(22个)
|
||||
|
||||
1. **Login.tsx**
|
||||
- 硬编码文本:`'登录成功'`, `'登录失败'`, `'用户名'`, `'密码'` 等
|
||||
- 需要添加:`import { useTranslation } from 'react-i18next'`
|
||||
- 需要添加:`const { t } = useTranslation()`
|
||||
- 需要替换所有硬编码文本
|
||||
|
||||
2. **AccountList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
3. **AccountImport.tsx**
|
||||
- 硬编码文本:`'钱包地址与私钥不匹配'`, `'钱包地址格式不正确'`, `'钱包地址'` 等
|
||||
- 需要更新
|
||||
|
||||
4. **AccountEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
5. **LeaderList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
6. **LeaderAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
7. **LeaderEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
8. **TemplateList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
9. **TemplateAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
10. **TemplateEdit.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
11. **CopyTradingList.tsx**
|
||||
- 硬编码文本:`'删除跟单成功'`, `'删除跟单失败'`, `'钱包'`, `'模板'`, `'Leader'`, `'取消'`, `'订单'` 等
|
||||
- 需要更新
|
||||
|
||||
12. **CopyTradingAdd.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
13. **CopyTradingStatistics.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
14. **CopyTradingBuyOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
15. **CopyTradingSellOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
16. **CopyTradingMatchedOrders.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
17. **PositionList.tsx**
|
||||
- 硬编码文本:`'账户'`, `'市场'`, `'搜索账户、市场、方向...'`, `'确认卖出'`, `'取消'`, `'订单类型'`, `'确认赎回'` 等
|
||||
- 需要更新
|
||||
|
||||
18. **OrderList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
19. **Statistics.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
20. **UserList.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
21. **ResetPassword.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
22. **SystemSettings.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
23. **ConfigPage.tsx**
|
||||
- 需要检查并替换所有硬编码文本
|
||||
|
||||
### App.tsx 中的硬编码文本
|
||||
|
||||
**App.tsx** 中有硬编码的中文文本:
|
||||
- 第 61 行:`'订单创建'`
|
||||
- 第 63 行:`'订单更新'`
|
||||
- 第 65 行:`'订单取消'`
|
||||
- 第 67 行:`'订单事件'`
|
||||
- 第 79 行:`'买入'`, `'卖出'`
|
||||
- 第 92 行:`'市场:'`, `'状态:'`, `'已成交:'`, `'剩余:'`
|
||||
|
||||
需要:
|
||||
1. 添加 `import { useTranslation } from 'react-i18next'`
|
||||
2. 在组件中使用 `const { t } = useTranslation()`
|
||||
3. 替换所有硬编码文本
|
||||
|
||||
### 前端更新模式
|
||||
|
||||
对于每个页面组件:
|
||||
|
||||
1. **添加导入**:
|
||||
```typescript
|
||||
import { useTranslation } from 'react-i18next'
|
||||
```
|
||||
|
||||
2. **在组件中使用**:
|
||||
```typescript
|
||||
const YourComponent: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
3. **替换硬编码文本**:
|
||||
```typescript
|
||||
// 旧代码
|
||||
<Button>保存</Button>
|
||||
message.success('操作成功')
|
||||
|
||||
// 新代码
|
||||
<Button>{t('common.save')}</Button>
|
||||
message.success(t('message.operationSuccess'))
|
||||
```
|
||||
|
||||
4. **扩展语言包**:
|
||||
- 在 `frontend/src/locales/*/common.json` 中添加缺失的翻译键
|
||||
- 确保三个语言包(zh-CN, zh-TW, en)都有对应的翻译
|
||||
|
||||
## 语言包扩展
|
||||
|
||||
### 需要添加的翻译键
|
||||
|
||||
根据检查,需要在语言包中添加以下键:
|
||||
|
||||
```json
|
||||
{
|
||||
"order": {
|
||||
"create": "订单创建",
|
||||
"update": "订单更新",
|
||||
"cancel": "订单取消",
|
||||
"event": "订单事件",
|
||||
"buy": "买入",
|
||||
"sell": "卖出",
|
||||
"market": "市场",
|
||||
"status": "状态",
|
||||
"filled": "已成交",
|
||||
"remaining": "剩余"
|
||||
},
|
||||
"wallet": {
|
||||
"address": "钱包地址",
|
||||
"addressMismatch": "钱包地址与私钥不匹配",
|
||||
"addressInvalid": "钱包地址格式不正确"
|
||||
},
|
||||
"copyTrading": {
|
||||
"deleteSuccess": "删除跟单成功",
|
||||
"deleteFailed": "删除跟单失败",
|
||||
"wallet": "钱包",
|
||||
"template": "模板",
|
||||
"leader": "Leader"
|
||||
},
|
||||
"position": {
|
||||
"account": "账户",
|
||||
"market": "市场",
|
||||
"searchPlaceholder": "搜索账户、市场、方向...",
|
||||
"confirmSell": "确认卖出",
|
||||
"confirmRedeem": "确认赎回",
|
||||
"orderType": "订单类型"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 优先级建议
|
||||
|
||||
### 高优先级(核心功能)
|
||||
1. ✅ 后端:完成所有 Controller 的 MessageSource 更新
|
||||
2. ✅ 前端:更新 Login.tsx(登录页面)
|
||||
3. ✅ 前端:更新 App.tsx(全局通知)
|
||||
|
||||
### 中优先级(常用功能)
|
||||
4. 前端:更新 AccountList.tsx, AccountImport.tsx
|
||||
5. 前端:更新 LeaderList.tsx, LeaderAdd.tsx
|
||||
6. 前端:更新 CopyTradingList.tsx
|
||||
|
||||
### 低优先级(其他页面)
|
||||
7. 前端:逐步更新其他页面组件
|
||||
|
||||
## 验证清单
|
||||
|
||||
完成后检查:
|
||||
|
||||
### 后端
|
||||
- [ ] 所有 Controller 都注入了 MessageSource
|
||||
- [ ] 所有 ApiResponse.error() 调用都传入了 messageSource
|
||||
- [ ] 编译无错误
|
||||
- [ ] 测试不同语言下的错误消息
|
||||
|
||||
### 前端
|
||||
- [ ] 所有页面都使用了 useTranslation
|
||||
- [ ] 所有硬编码文本都已替换
|
||||
- [ ] 语言包包含所有需要的翻译键
|
||||
- [ ] 测试不同语言下的页面显示
|
||||
- [ ] 测试语言切换功能
|
||||
|
||||
Reference in New Issue
Block a user