diff --git a/web/src/App.tsx b/web/src/App.tsx index 228c87ef..c6092b5d 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -179,7 +179,7 @@ function App() { style={{ background: 'linear-gradient(135deg, #F0B90B 0%, #FCD535 100%)' }}> ⚡ -

加载中...

+

{t('loading', language)}

); @@ -299,7 +299,7 @@ function App() { className="px-3 py-2 rounded text-sm font-semibold transition-all hover:scale-105" style={{ background: 'rgba(246, 70, 93, 0.1)', color: '#F6465D', border: '1px solid rgba(246, 70, 93, 0.2)' }} > - 退出 + {t('logout', language)} )} diff --git a/web/src/components/AITradersPage.tsx b/web/src/components/AITradersPage.tsx index bc2516cf..9c3da522 100644 --- a/web/src/components/AITradersPage.tsx +++ b/web/src/components/AITradersPage.tsx @@ -3,7 +3,7 @@ import useSWR from 'swr'; import { api } from '../lib/api'; import type { TraderInfo, CreateTraderRequest, AIModel, Exchange } from '../types'; import { useLanguage } from '../contexts/LanguageContext'; -import { t } from '../i18n/translations'; +import { t, type Language } from '../i18n/translations'; import { getExchangeIcon } from './ExchangeIcons'; import { getModelIcon } from './ModelIcons'; import { TraderConfigModal } from './TraderConfigModal'; @@ -149,7 +149,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to create trader:', error); - alert('创建交易员失败'); + alert(t('createTraderFailed', language)); } }; @@ -160,7 +160,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setShowEditModal(true); } catch (error) { console.error('Failed to fetch trader config:', error); - alert('获取交易员配置失败'); + alert(t('getTraderConfigFailed', language)); } }; @@ -170,14 +170,14 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { try { const model = enabledModels?.find(m => m.id === data.ai_model_id); const exchange = enabledExchanges?.find(e => e.id === data.exchange_id); - + if (!model) { - alert('AI模型配置不存在或未启用'); + alert(t('modelConfigNotExist', language)); return; } - + if (!exchange) { - alert('交易所配置不存在或未启用'); + alert(t('exchangeConfigNotExist', language)); return; } @@ -202,19 +202,19 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to update trader:', error); - alert('更新交易员失败'); + alert(t('updateTraderFailed', language)); } }; const handleDeleteTrader = async (traderId: string) => { if (!confirm(t('confirmDeleteTrader', language))) return; - + try { await api.deleteTrader(traderId); mutateTraders(); } catch (error) { console.error('Failed to delete trader:', error); - alert('删除交易员失败'); + alert(t('deleteTraderFailed', language)); } }; @@ -228,7 +228,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to toggle trader:', error); - alert('操作失败'); + alert(t('operationFailed', language)); } }; @@ -247,7 +247,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { }; const handleDeleteModelConfig = async (modelId: string) => { - if (!confirm('确定要删除此AI模型配置吗?')) return; + if (!confirm(t('confirmDeleteModel', language))) return; try { const updatedModels = allModels?.map(m => @@ -272,7 +272,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingModel(null); } catch (error) { console.error('Failed to delete model config:', error); - alert('删除配置失败'); + alert(t('deleteConfigFailed', language)); } }; @@ -281,7 +281,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { // 找到要配置的模型(从supportedModels中) const modelToUpdate = supportedModels?.find(m => m.id === modelId); if (!modelToUpdate) { - alert('模型不存在'); + alert(t('modelNotExist', language)); return; } @@ -323,12 +323,12 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingModel(null); } catch (error) { console.error('Failed to save model config:', error); - alert('保存配置失败'); + alert(t('saveConfigFailed', language)); } }; const handleDeleteExchangeConfig = async (exchangeId: string) => { - if (!confirm('确定要删除此交易所配置吗?')) return; + if (!confirm(t('confirmDeleteExchange', language))) return; try { const updatedExchanges = allExchanges?.map(e => @@ -355,7 +355,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingExchange(null); } catch (error) { console.error('Failed to delete exchange config:', error); - alert('删除交易所配置失败'); + alert(t('deleteExchangeConfigFailed', language)); } }; @@ -364,7 +364,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { // 找到要配置的交易所(从supportedExchanges中) const exchangeToUpdate = supportedExchanges?.find(e => e.id === exchangeId); if (!exchangeToUpdate) { - alert('交易所不存在'); + alert(t('exchangeNotExist', language)); return; } @@ -411,7 +411,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingExchange(null); } catch (error) { console.error('Failed to save exchange config:', error); - alert('保存交易所配置失败'); + alert(t('saveConfigFailed', language)); } }; @@ -432,7 +432,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setShowSignalSourceModal(false); } catch (error) { console.error('Failed to save signal source:', error); - alert('保存信号源配置失败'); + alert(t('saveSignalSourceFailed', language)); } }; @@ -493,13 +493,13 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { @@ -899,7 +904,8 @@ function ModelConfigModal({ editingModelId, onSave, onDelete, - onClose + onClose, + language }: { allModels: AIModel[]; configuredModels: AIModel[]; @@ -907,6 +913,7 @@ function ModelConfigModal({ onSave: (modelId: string, apiKey: string, baseUrl?: string) => void; onDelete: (modelId: string) => void; onClose: () => void; + language: Language; }) { const [selectedModelId, setSelectedModelId] = useState(editingModelId || ''); const [apiKey, setApiKey] = useState(''); @@ -940,30 +947,30 @@ function ModelConfigModal({

- {editingModelId ? '编辑AI模型' : '添加AI模型'} + {editingModelId ? t('editAIModel', language) : t('addAIModel', language)}

{editingModelId && ( )}
- +
{!editingModelId && (
setBaseUrl(e.target.value)} - placeholder="自定义API基础URL,如: https://api.openai.com/v1" + placeholder={t('customBaseURLPlaceholder', language)} className="w-full px-3 py-2 rounded" style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }} />
- 留空则使用默认API地址 + {t('leaveBlankForDefault', language)}
- ℹ️ 说明 + ℹ️ {t('information', language)}
-
• API Key将被加密存储,请确保密钥有效
-
• Base URL用于自定义API服务器地址
-
• 删除配置后,使用此模型的交易员将无法正常工作
+
{t('modelConfigInfo1', language)}
+
{t('modelConfigInfo2', language)}
+
{t('modelConfigInfo3', language)}
@@ -1060,7 +1067,7 @@ function ModelConfigModal({ className="flex-1 px-4 py-2 rounded text-sm font-semibold" style={{ background: '#2B3139', color: '#848E9C' }} > - 取消 + {t('cancel', language)}
@@ -1083,13 +1090,15 @@ function ExchangeConfigModal({ editingExchangeId, onSave, onDelete, - onClose + onClose, + language }: { allExchanges: Exchange[]; editingExchangeId: string | null; onSave: (exchangeId: string, apiKey: string, secretKey?: string, testnet?: boolean, hyperliquidWalletAddr?: string, asterUser?: string, asterSigner?: string, asterPrivateKey?: string) => Promise; onDelete: (exchangeId: string) => void; onClose: () => void; + language: Language; }) { const [selectedExchangeId, setSelectedExchangeId] = useState(editingExchangeId || ''); const [apiKey, setApiKey] = useState(''); @@ -1132,30 +1141,30 @@ function ExchangeConfigModal({

- {editingExchangeId ? '编辑交易所' : '添加交易所'} + {editingExchangeId ? t('editExchange', language) : t('addExchange', language)}

{editingExchangeId && ( )}
- +
{!editingExchangeId && (