mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-06 12:30:59 +08:00
refactor: optimize codebase encoding
This commit is contained in:
@@ -183,13 +183,13 @@ export const backtestApi = {
|
||||
try {
|
||||
const data = text ? JSON.parse(text) : null
|
||||
throw new Error(
|
||||
data?.error || data?.message || text || '导出失败,请稍后再试'
|
||||
data?.error || data?.message || text || 'Export failed, please try again later'
|
||||
)
|
||||
} catch (err) {
|
||||
if (err instanceof Error && err.message) {
|
||||
throw err
|
||||
}
|
||||
throw new Error(text || '导出失败,请稍后再试')
|
||||
throw new Error(text || 'Export failed, please try again later')
|
||||
}
|
||||
}
|
||||
return res.blob()
|
||||
|
||||
@@ -10,7 +10,7 @@ import { API_BASE, httpClient, CryptoService } from './helpers'
|
||||
export const configApi = {
|
||||
async getModelConfigs(): Promise<AIModel[]> {
|
||||
const result = await httpClient.get<AIModel[]>(`${API_BASE}/models`)
|
||||
if (!result.success) throw new Error('获取模型配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch model configs')
|
||||
return Array.isArray(result.data) ? result.data : []
|
||||
},
|
||||
|
||||
@@ -18,13 +18,13 @@ export const configApi = {
|
||||
const result = await httpClient.get<AIModel[]>(
|
||||
`${API_BASE}/supported-models`
|
||||
)
|
||||
if (!result.success) throw new Error('获取支持的模型失败')
|
||||
if (!result.success) throw new Error('Failed to fetch supported models')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getPromptTemplates(): Promise<string[]> {
|
||||
const res = await fetch(`${API_BASE}/prompt-templates`)
|
||||
if (!res.ok) throw new Error('获取提示词模板失败')
|
||||
if (!res.ok) throw new Error('Failed to fetch prompt templates')
|
||||
const data = await res.json()
|
||||
if (Array.isArray(data.templates)) {
|
||||
return data.templates.map((item: { name: string }) => item.name)
|
||||
@@ -33,41 +33,41 @@ export const configApi = {
|
||||
},
|
||||
|
||||
async updateModelConfigs(request: UpdateModelConfigRequest): Promise<void> {
|
||||
// 检查是否启用了传输加密
|
||||
// Check if transport encryption is enabled
|
||||
const config = await CryptoService.fetchCryptoConfig()
|
||||
|
||||
if (!config.transport_encryption) {
|
||||
// 传输加密禁用时,直接发送明文
|
||||
// Transport encryption disabled, send plaintext
|
||||
const result = await httpClient.put(`${API_BASE}/models`, request)
|
||||
if (!result.success) throw new Error('更新模型配置失败')
|
||||
if (!result.success) throw new Error('Failed to update model configs')
|
||||
return
|
||||
}
|
||||
|
||||
// 获取RSA公钥
|
||||
// Fetch RSA public key
|
||||
const publicKey = await CryptoService.fetchPublicKey()
|
||||
|
||||
// 初始化加密服务
|
||||
// Initialize crypto service
|
||||
await CryptoService.initialize(publicKey)
|
||||
|
||||
// 获取用户信息(从localStorage或其他地方)
|
||||
// Get user info from localStorage
|
||||
const userId = localStorage.getItem('user_id') || ''
|
||||
const sessionId = sessionStorage.getItem('session_id') || ''
|
||||
|
||||
// 加密敏感数据
|
||||
// Encrypt sensitive data
|
||||
const encryptedPayload = await CryptoService.encryptSensitiveData(
|
||||
JSON.stringify(request),
|
||||
userId,
|
||||
sessionId
|
||||
)
|
||||
|
||||
// 发送加密数据
|
||||
// Send encrypted data
|
||||
const result = await httpClient.put(`${API_BASE}/models`, encryptedPayload)
|
||||
if (!result.success) throw new Error('更新模型配置失败')
|
||||
if (!result.success) throw new Error('Failed to update model configs')
|
||||
},
|
||||
|
||||
async getExchangeConfigs(): Promise<Exchange[]> {
|
||||
const result = await httpClient.get<Exchange[]>(`${API_BASE}/exchanges`)
|
||||
if (!result.success) throw new Error('获取交易所配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch exchange configs')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ export const configApi = {
|
||||
const result = await httpClient.get<Exchange[]>(
|
||||
`${API_BASE}/supported-exchanges`
|
||||
)
|
||||
if (!result.success) throw new Error('获取支持的交易所失败')
|
||||
if (!result.success) throw new Error('Failed to fetch supported exchanges')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -83,93 +83,93 @@ export const configApi = {
|
||||
request: UpdateExchangeConfigRequest
|
||||
): Promise<void> {
|
||||
const result = await httpClient.put(`${API_BASE}/exchanges`, request)
|
||||
if (!result.success) throw new Error('更新交易所配置失败')
|
||||
if (!result.success) throw new Error('Failed to update exchange configs')
|
||||
},
|
||||
|
||||
async createExchange(request: CreateExchangeRequest): Promise<{ id: string }> {
|
||||
const result = await httpClient.post<{ id: string }>(`${API_BASE}/exchanges`, request)
|
||||
if (!result.success) throw new Error('创建交易所账户失败')
|
||||
if (!result.success) throw new Error('Failed to create exchange account')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async createExchangeEncrypted(request: CreateExchangeRequest): Promise<{ id: string }> {
|
||||
// 检查是否启用了传输加密
|
||||
// Check if transport encryption is enabled
|
||||
const config = await CryptoService.fetchCryptoConfig()
|
||||
|
||||
if (!config.transport_encryption) {
|
||||
// 传输加密禁用时,直接发送明文
|
||||
// Transport encryption disabled, send plaintext
|
||||
const result = await httpClient.post<{ id: string }>(`${API_BASE}/exchanges`, request)
|
||||
if (!result.success) throw new Error('创建交易所账户失败')
|
||||
if (!result.success) throw new Error('Failed to create exchange account')
|
||||
return result.data!
|
||||
}
|
||||
|
||||
// 获取RSA公钥
|
||||
// Fetch RSA public key
|
||||
const publicKey = await CryptoService.fetchPublicKey()
|
||||
|
||||
// 初始化加密服务
|
||||
// Initialize crypto service
|
||||
await CryptoService.initialize(publicKey)
|
||||
|
||||
// 获取用户信息
|
||||
// Get user info
|
||||
const userId = localStorage.getItem('user_id') || ''
|
||||
const sessionId = sessionStorage.getItem('session_id') || ''
|
||||
|
||||
// 加密敏感数据
|
||||
// Encrypt sensitive data
|
||||
const encryptedPayload = await CryptoService.encryptSensitiveData(
|
||||
JSON.stringify(request),
|
||||
userId,
|
||||
sessionId
|
||||
)
|
||||
|
||||
// 发送加密数据
|
||||
// Send encrypted data
|
||||
const result = await httpClient.post<{ id: string }>(
|
||||
`${API_BASE}/exchanges`,
|
||||
encryptedPayload
|
||||
)
|
||||
if (!result.success) throw new Error('创建交易所账户失败')
|
||||
if (!result.success) throw new Error('Failed to create exchange account')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async deleteExchange(exchangeId: string): Promise<void> {
|
||||
const result = await httpClient.delete(`${API_BASE}/exchanges/${exchangeId}`)
|
||||
if (!result.success) throw new Error('删除交易所账户失败')
|
||||
if (!result.success) throw new Error('Failed to delete exchange account')
|
||||
},
|
||||
|
||||
async updateExchangeConfigsEncrypted(
|
||||
request: UpdateExchangeConfigRequest
|
||||
): Promise<void> {
|
||||
// 检查是否启用了传输加密
|
||||
// Check if transport encryption is enabled
|
||||
const config = await CryptoService.fetchCryptoConfig()
|
||||
|
||||
if (!config.transport_encryption) {
|
||||
// 传输加密禁用时,直接发送明文
|
||||
// Transport encryption disabled, send plaintext
|
||||
const result = await httpClient.put(`${API_BASE}/exchanges`, request)
|
||||
if (!result.success) throw new Error('更新交易所配置失败')
|
||||
if (!result.success) throw new Error('Failed to update exchange configs')
|
||||
return
|
||||
}
|
||||
|
||||
// 获取RSA公钥
|
||||
// Fetch RSA public key
|
||||
const publicKey = await CryptoService.fetchPublicKey()
|
||||
|
||||
// 初始化加密服务
|
||||
// Initialize crypto service
|
||||
await CryptoService.initialize(publicKey)
|
||||
|
||||
// 获取用户信息(从localStorage或其他地方)
|
||||
// Get user info from localStorage
|
||||
const userId = localStorage.getItem('user_id') || ''
|
||||
const sessionId = sessionStorage.getItem('session_id') || ''
|
||||
|
||||
// 加密敏感数据
|
||||
// Encrypt sensitive data
|
||||
const encryptedPayload = await CryptoService.encryptSensitiveData(
|
||||
JSON.stringify(request),
|
||||
userId,
|
||||
sessionId
|
||||
)
|
||||
|
||||
// 发送加密数据
|
||||
// Send encrypted data
|
||||
const result = await httpClient.put(
|
||||
`${API_BASE}/exchanges`,
|
||||
encryptedPayload
|
||||
)
|
||||
if (!result.success) throw new Error('更新交易所配置失败')
|
||||
if (!result.success) throw new Error('Failed to update exchange configs')
|
||||
},
|
||||
|
||||
async getServerIP(): Promise<{
|
||||
@@ -180,7 +180,7 @@ export const configApi = {
|
||||
public_ip: string
|
||||
message: string
|
||||
}>(`${API_BASE}/server-ip`)
|
||||
if (!result.success) throw new Error('获取服务器IP失败')
|
||||
if (!result.success) throw new Error('Failed to fetch server IP')
|
||||
return result.data!
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/status?trader_id=${traderId}`
|
||||
: `${API_BASE}/status`
|
||||
const result = await httpClient.get<SystemStatus>(url)
|
||||
if (!result.success) throw new Error('获取系统状态失败')
|
||||
if (!result.success) throw new Error('Failed to fetch system status')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -24,8 +24,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/account?trader_id=${traderId}`
|
||||
: `${API_BASE}/account`
|
||||
const result = await httpClient.get<AccountInfo>(url)
|
||||
if (!result.success) throw new Error('获取账户信息失败')
|
||||
console.log('Account data fetched:', result.data)
|
||||
if (!result.success) throw new Error('Failed to fetch account info')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -34,7 +33,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/positions?trader_id=${traderId}`
|
||||
: `${API_BASE}/positions`
|
||||
const result = await httpClient.get<Position[]>(url)
|
||||
if (!result.success) throw new Error('获取持仓列表失败')
|
||||
if (!result.success) throw new Error('Failed to fetch positions')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -43,7 +42,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/decisions?trader_id=${traderId}`
|
||||
: `${API_BASE}/decisions`
|
||||
const result = await httpClient.get<DecisionRecord[]>(url)
|
||||
if (!result.success) throw new Error('获取决策日志失败')
|
||||
if (!result.success) throw new Error('Failed to fetch decision logs')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -60,7 +59,7 @@ export const dataApi = {
|
||||
const result = await httpClient.get<DecisionRecord[]>(
|
||||
`${API_BASE}/decisions/latest?${params}`
|
||||
)
|
||||
if (!result.success) throw new Error('获取最新决策失败')
|
||||
if (!result.success) throw new Error('Failed to fetch latest decisions')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -69,7 +68,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/statistics?trader_id=${traderId}`
|
||||
: `${API_BASE}/statistics`
|
||||
const result = await httpClient.get<Statistics>(url)
|
||||
if (!result.success) throw new Error('获取统计信息失败')
|
||||
if (!result.success) throw new Error('Failed to fetch statistics')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -78,7 +77,7 @@ export const dataApi = {
|
||||
? `${API_BASE}/equity-history?trader_id=${traderId}`
|
||||
: `${API_BASE}/equity-history`
|
||||
const result = await httpClient.get<any[]>(url)
|
||||
if (!result.success) throw new Error('获取历史数据失败')
|
||||
if (!result.success) throw new Error('Failed to fetch equity history')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -87,13 +86,13 @@ export const dataApi = {
|
||||
`${API_BASE}/equity-history-batch`,
|
||||
{ trader_ids: traderIds, hours: hours || 0 }
|
||||
)
|
||||
if (!result.success) throw new Error('获取批量历史数据失败')
|
||||
if (!result.success) throw new Error('Failed to fetch batch equity history')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getTopTraders(): Promise<any[]> {
|
||||
const result = await httpClient.get<any[]>(`${API_BASE}/top-traders`)
|
||||
if (!result.success) throw new Error('获取前5名交易员失败')
|
||||
if (!result.success) throw new Error('Failed to fetch top traders')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -101,7 +100,7 @@ export const dataApi = {
|
||||
const result = await httpClient.get<any>(
|
||||
`${API_BASE}/trader/${traderId}/config`
|
||||
)
|
||||
if (!result.success) throw new Error('获取公开交易员配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch public trader config')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -109,7 +108,7 @@ export const dataApi = {
|
||||
const result = await httpClient.get<CompetitionData>(
|
||||
`${API_BASE}/competition`
|
||||
)
|
||||
if (!result.success) throw new Error('获取竞赛数据失败')
|
||||
if (!result.success) throw new Error('Failed to fetch competition data')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -117,7 +116,7 @@ export const dataApi = {
|
||||
const result = await httpClient.get<PositionHistoryResponse>(
|
||||
`${API_BASE}/positions/history?trader_id=${traderId}&limit=${limit}`
|
||||
)
|
||||
if (!result.success) throw new Error('获取历史仓位失败')
|
||||
if (!result.success) throw new Error('Failed to fetch position history')
|
||||
return result.data!
|
||||
},
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export async function handleJSONResponse<T>(res: Response): Promise<T> {
|
||||
} catch {
|
||||
/* ignore JSON parse errors */
|
||||
}
|
||||
throw new Error(message || '请求失败')
|
||||
throw new Error(message || 'Request failed')
|
||||
}
|
||||
if (!text) {
|
||||
return {} as T
|
||||
|
||||
@@ -7,26 +7,26 @@ import { API_BASE, httpClient } from './helpers'
|
||||
export const strategyApi = {
|
||||
async getStrategies(): Promise<Strategy[]> {
|
||||
const result = await httpClient.get<{ strategies: Strategy[] }>(`${API_BASE}/strategies`)
|
||||
if (!result.success) throw new Error('获取策略列表失败')
|
||||
if (!result.success) throw new Error('Failed to fetch strategy list')
|
||||
const strategies = result.data?.strategies
|
||||
return Array.isArray(strategies) ? strategies : []
|
||||
},
|
||||
|
||||
async getStrategy(strategyId: string): Promise<Strategy> {
|
||||
const result = await httpClient.get<Strategy>(`${API_BASE}/strategies/${strategyId}`)
|
||||
if (!result.success) throw new Error('获取策略失败')
|
||||
if (!result.success) throw new Error('Failed to fetch strategy')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getActiveStrategy(): Promise<Strategy> {
|
||||
const result = await httpClient.get<Strategy>(`${API_BASE}/strategies/active`)
|
||||
if (!result.success) throw new Error('获取激活策略失败')
|
||||
if (!result.success) throw new Error('Failed to fetch active strategy')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getDefaultStrategyConfig(): Promise<StrategyConfig> {
|
||||
const result = await httpClient.get<StrategyConfig>(`${API_BASE}/strategies/default-config`)
|
||||
if (!result.success) throw new Error('获取默认策略配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch default strategy config')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ export const strategyApi = {
|
||||
config: StrategyConfig
|
||||
}): Promise<Strategy> {
|
||||
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies`, data)
|
||||
if (!result.success) throw new Error('创建策略失败')
|
||||
if (!result.success) throw new Error('Failed to create strategy')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -49,24 +49,24 @@ export const strategyApi = {
|
||||
}
|
||||
): Promise<Strategy> {
|
||||
const result = await httpClient.put<Strategy>(`${API_BASE}/strategies/${strategyId}`, data)
|
||||
if (!result.success) throw new Error('更新策略失败')
|
||||
if (!result.success) throw new Error('Failed to update strategy')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async deleteStrategy(strategyId: string): Promise<void> {
|
||||
const result = await httpClient.delete(`${API_BASE}/strategies/${strategyId}`)
|
||||
if (!result.success) throw new Error('删除策略失败')
|
||||
if (!result.success) throw new Error('Failed to delete strategy')
|
||||
},
|
||||
|
||||
async activateStrategy(strategyId: string): Promise<Strategy> {
|
||||
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies/${strategyId}/activate`)
|
||||
if (!result.success) throw new Error('激活策略失败')
|
||||
if (!result.success) throw new Error('Failed to activate strategy')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async duplicateStrategy(strategyId: string): Promise<Strategy> {
|
||||
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies/${strategyId}/duplicate`)
|
||||
if (!result.success) throw new Error('复制策略失败')
|
||||
if (!result.success) throw new Error('Failed to duplicate strategy')
|
||||
return result.data!
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,22 +4,22 @@ import { API_BASE, httpClient } from './helpers'
|
||||
export const telegramApi = {
|
||||
async getTelegramConfig(): Promise<TelegramConfig> {
|
||||
const result = await httpClient.get<TelegramConfig>(`${API_BASE}/telegram`)
|
||||
if (!result.success) throw new Error('获取Telegram配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch Telegram config')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async updateTelegramConfig(token: string, modelId?: string): Promise<void> {
|
||||
const result = await httpClient.post(`${API_BASE}/telegram`, { bot_token: token, model_id: modelId ?? '' })
|
||||
if (!result.success) throw new Error('保存Telegram配置失败')
|
||||
if (!result.success) throw new Error('Failed to save Telegram config')
|
||||
},
|
||||
|
||||
async unbindTelegram(): Promise<void> {
|
||||
const result = await httpClient.delete(`${API_BASE}/telegram/binding`)
|
||||
if (!result.success) throw new Error('解绑Telegram失败')
|
||||
if (!result.success) throw new Error('Failed to unbind Telegram')
|
||||
},
|
||||
|
||||
async updateTelegramModel(modelId: string): Promise<void> {
|
||||
const result = await httpClient.post(`${API_BASE}/telegram/model`, { model_id: modelId })
|
||||
if (!result.success) throw new Error('更新Telegram模型失败')
|
||||
if (!result.success) throw new Error('Failed to update Telegram model')
|
||||
},
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import { API_BASE, httpClient } from './helpers'
|
||||
export const traderApi = {
|
||||
async getTraders(): Promise<TraderInfo[]> {
|
||||
const result = await httpClient.get<TraderInfo[]>(`${API_BASE}/my-traders`)
|
||||
if (!result.success) throw new Error('获取trader列表失败')
|
||||
if (!result.success) throw new Error('Failed to fetch trader list')
|
||||
return Array.isArray(result.data) ? result.data : []
|
||||
},
|
||||
|
||||
async getPublicTraders(): Promise<any[]> {
|
||||
const result = await httpClient.get<any[]>(`${API_BASE}/traders`)
|
||||
if (!result.success) throw new Error('获取公开trader列表失败')
|
||||
if (!result.success) throw new Error('Failed to fetch public trader list')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -23,25 +23,25 @@ export const traderApi = {
|
||||
`${API_BASE}/traders`,
|
||||
request
|
||||
)
|
||||
if (!result.success) throw new Error('创建交易员失败')
|
||||
if (!result.success) throw new Error('Failed to create trader')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async deleteTrader(traderId: string): Promise<void> {
|
||||
const result = await httpClient.delete(`${API_BASE}/traders/${traderId}`)
|
||||
if (!result.success) throw new Error('删除交易员失败')
|
||||
if (!result.success) throw new Error('Failed to delete trader')
|
||||
},
|
||||
|
||||
async startTrader(traderId: string): Promise<void> {
|
||||
const result = await httpClient.post(
|
||||
`${API_BASE}/traders/${traderId}/start`
|
||||
)
|
||||
if (!result.success) throw new Error('启动交易员失败')
|
||||
if (!result.success) throw new Error('Failed to start trader')
|
||||
},
|
||||
|
||||
async stopTrader(traderId: string): Promise<void> {
|
||||
const result = await httpClient.post(`${API_BASE}/traders/${traderId}/stop`)
|
||||
if (!result.success) throw new Error('停止交易员失败')
|
||||
if (!result.success) throw new Error('Failed to stop trader')
|
||||
},
|
||||
|
||||
async toggleCompetition(traderId: string, showInCompetition: boolean): Promise<void> {
|
||||
@@ -49,7 +49,7 @@ export const traderApi = {
|
||||
`${API_BASE}/traders/${traderId}/competition`,
|
||||
{ show_in_competition: showInCompetition }
|
||||
)
|
||||
if (!result.success) throw new Error('更新竞技场显示设置失败')
|
||||
if (!result.success) throw new Error('Failed to update competition visibility')
|
||||
},
|
||||
|
||||
async closePosition(traderId: string, symbol: string, side: string): Promise<{ message: string }> {
|
||||
@@ -57,7 +57,7 @@ export const traderApi = {
|
||||
`${API_BASE}/traders/${traderId}/close-position`,
|
||||
{ symbol, side }
|
||||
)
|
||||
if (!result.success) throw new Error('平仓失败')
|
||||
if (!result.success) throw new Error('Failed to close position')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -69,14 +69,14 @@ export const traderApi = {
|
||||
`${API_BASE}/traders/${traderId}/prompt`,
|
||||
{ custom_prompt: customPrompt }
|
||||
)
|
||||
if (!result.success) throw new Error('更新自定义策略失败')
|
||||
if (!result.success) throw new Error('Failed to update custom prompt')
|
||||
},
|
||||
|
||||
async getTraderConfig(traderId: string): Promise<TraderConfigData> {
|
||||
const result = await httpClient.get<TraderConfigData>(
|
||||
`${API_BASE}/traders/${traderId}/config`
|
||||
)
|
||||
if (!result.success) throw new Error('获取交易员配置失败')
|
||||
if (!result.success) throw new Error('Failed to fetch trader config')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
@@ -88,7 +88,7 @@ export const traderApi = {
|
||||
`${API_BASE}/traders/${traderId}`,
|
||||
request
|
||||
)
|
||||
if (!result.success) throw new Error('更新交易员失败')
|
||||
if (!result.success) throw new Error('Failed to update trader')
|
||||
return result.data!
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { notify } from './notify'
|
||||
|
||||
/**
|
||||
* 复制文本到剪贴板,并显示轻量提示。
|
||||
* Copy text to clipboard and show a toast notification.
|
||||
*/
|
||||
export async function copyWithToast(text: string, successMsg = '已复制') {
|
||||
export async function copyWithToast(text: string, successMsg = 'Copied') {
|
||||
try {
|
||||
if (navigator?.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(text)
|
||||
} else {
|
||||
// 兼容降级:创建临时文本域执行复制
|
||||
// Fallback: create temporary textarea for copy
|
||||
const el = document.createElement('textarea')
|
||||
el.value = text
|
||||
el.style.position = 'fixed'
|
||||
@@ -22,7 +22,7 @@ export async function copyWithToast(text: string, successMsg = '已复制') {
|
||||
return true
|
||||
} catch (err) {
|
||||
console.error('Clipboard copy failed:', err)
|
||||
notify.error('复制失败')
|
||||
notify.error('Copy failed')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user