mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
Resolve merge conflicts in AITradersPage.tsx
- Fixed import statement conflict (using 'type Language') - Merged exchange configuration logic preserving support for multiple exchange types - Kept comprehensive form handling for Binance, Hyperliquid, Aster, and OKX exchanges - Updated security warning messages to use proper translation keys 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
@@ -235,9 +235,10 @@ type ExchangeConfig struct {
|
||||
|
||||
type UpdateModelConfigRequest struct {
|
||||
Models map[string]struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
APIKey string `json:"api_key"`
|
||||
CustomAPIURL string `json:"custom_api_url"`
|
||||
Enabled bool `json:"enabled"`
|
||||
APIKey string `json:"api_key"`
|
||||
CustomAPIURL string `json:"custom_api_url"`
|
||||
CustomModelName string `json:"custom_model_name"`
|
||||
} `json:"models"`
|
||||
}
|
||||
|
||||
@@ -612,16 +613,23 @@ func (s *Server) handleUpdateModelConfigs(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 更新每个模型的配置
|
||||
for modelID, modelData := range req.Models {
|
||||
err := s.database.UpdateAIModel(userID, modelID, modelData.Enabled, modelData.APIKey, modelData.CustomAPIURL)
|
||||
err := s.database.UpdateAIModel(userID, modelID, modelData.Enabled, modelData.APIKey, modelData.CustomAPIURL, modelData.CustomModelName)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("更新模型 %s 失败: %v", modelID, err)})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 重新加载该用户的所有交易员,使新配置立即生效
|
||||
err := s.traderManager.LoadUserTraders(s.database, userID)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 重新加载用户交易员到内存失败: %v", err)
|
||||
// 这里不返回错误,因为模型配置已经成功更新到数据库
|
||||
}
|
||||
|
||||
log.Printf("✓ AI模型配置已更新: %+v", req.Models)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "模型配置已更新"})
|
||||
}
|
||||
@@ -649,7 +657,7 @@ func (s *Server) handleUpdateExchangeConfigs(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 更新每个交易所的配置
|
||||
for exchangeID, exchangeData := range req.Exchanges {
|
||||
err := s.database.UpdateExchange(userID, exchangeID, exchangeData.Enabled, exchangeData.APIKey, exchangeData.SecretKey, exchangeData.Testnet, exchangeData.HyperliquidWalletAddr, exchangeData.AsterUser, exchangeData.AsterSigner, exchangeData.AsterPrivateKey)
|
||||
@@ -658,7 +666,14 @@ func (s *Server) handleUpdateExchangeConfigs(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 重新加载该用户的所有交易员,使新配置立即生效
|
||||
err := s.traderManager.LoadUserTraders(s.database, userID)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 重新加载用户交易员到内存失败: %v", err)
|
||||
// 这里不返回错误,因为交易所配置已经成功更新到数据库
|
||||
}
|
||||
|
||||
log.Printf("✓ 交易所配置已更新: %+v", req.Exchanges)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "交易所配置已更新"})
|
||||
}
|
||||
@@ -725,12 +740,21 @@ func (s *Server) handleTraderList(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// AIModelID 应该已经是 provider(如 "deepseek"),直接使用
|
||||
// 如果是旧数据格式(如 "admin_deepseek"),提取 provider 部分
|
||||
aiModelID := trader.AIModelID
|
||||
// 兼容旧数据:如果包含下划线,提取最后一部分作为 provider
|
||||
if strings.Contains(aiModelID, "_") {
|
||||
parts := strings.Split(aiModelID, "_")
|
||||
aiModelID = parts[len(parts)-1]
|
||||
}
|
||||
|
||||
result = append(result, map[string]interface{}{
|
||||
"trader_id": trader.ID,
|
||||
"trader_name": trader.Name,
|
||||
"ai_model": trader.AIModelID,
|
||||
"exchange_id": trader.ExchangeID,
|
||||
"is_running": isRunning,
|
||||
"trader_id": trader.ID,
|
||||
"trader_name": trader.Name,
|
||||
"ai_model": aiModelID,
|
||||
"exchange_id": trader.ExchangeID,
|
||||
"is_running": isRunning,
|
||||
"initial_balance": trader.InitialBalance,
|
||||
})
|
||||
}
|
||||
@@ -763,21 +787,30 @@ func (s *Server) handleGetTraderConfig(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// AIModelID 应该已经是 provider(如 "deepseek"),直接使用
|
||||
// 如果是旧数据格式(如 "admin_deepseek"),提取 provider 部分
|
||||
aiModelID := traderConfig.AIModelID
|
||||
// 兼容旧数据:如果包含下划线,提取最后一部分作为 provider
|
||||
if strings.Contains(aiModelID, "_") {
|
||||
parts := strings.Split(aiModelID, "_")
|
||||
aiModelID = parts[len(parts)-1]
|
||||
}
|
||||
|
||||
result := map[string]interface{}{
|
||||
"trader_id": traderConfig.ID,
|
||||
"trader_name": traderConfig.Name,
|
||||
"ai_model": traderConfig.AIModelID,
|
||||
"exchange_id": traderConfig.ExchangeID,
|
||||
"initial_balance": traderConfig.InitialBalance,
|
||||
"btc_eth_leverage": traderConfig.BTCETHLeverage,
|
||||
"altcoin_leverage": traderConfig.AltcoinLeverage,
|
||||
"trading_symbols": traderConfig.TradingSymbols,
|
||||
"custom_prompt": traderConfig.CustomPrompt,
|
||||
"trader_id": traderConfig.ID,
|
||||
"trader_name": traderConfig.Name,
|
||||
"ai_model": aiModelID,
|
||||
"exchange_id": traderConfig.ExchangeID,
|
||||
"initial_balance": traderConfig.InitialBalance,
|
||||
"btc_eth_leverage": traderConfig.BTCETHLeverage,
|
||||
"altcoin_leverage": traderConfig.AltcoinLeverage,
|
||||
"trading_symbols": traderConfig.TradingSymbols,
|
||||
"custom_prompt": traderConfig.CustomPrompt,
|
||||
"override_base_prompt": traderConfig.OverrideBasePrompt,
|
||||
"is_cross_margin": traderConfig.IsCrossMargin,
|
||||
"use_coin_pool": traderConfig.UseCoinPool,
|
||||
"use_oi_top": traderConfig.UseOITop,
|
||||
"is_running": isRunning,
|
||||
"is_cross_margin": traderConfig.IsCrossMargin,
|
||||
"use_coin_pool": traderConfig.UseCoinPool,
|
||||
"use_oi_top": traderConfig.UseOITop,
|
||||
"is_running": isRunning,
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
|
||||
Reference in New Issue
Block a user