mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
Merge branch 'dev' of https://github.com/tinkle-community/nofx into dev
# Conflicts: # api/server.go
This commit is contained in:
196
api/server.go
196
api/server.go
@@ -71,20 +71,20 @@ func (s *Server) setupRoutes() {
|
||||
{
|
||||
// 健康检查
|
||||
api.Any("/health", s.handleHealth)
|
||||
|
||||
|
||||
// 认证相关路由(无需认证)
|
||||
api.POST("/register", s.handleRegister)
|
||||
api.POST("/login", s.handleLogin)
|
||||
api.POST("/verify-otp", s.handleVerifyOTP)
|
||||
api.POST("/complete-registration", s.handleCompleteRegistration)
|
||||
|
||||
|
||||
// 系统支持的模型和交易所(无需认证)
|
||||
api.GET("/supported-models", s.handleGetSupportedModels)
|
||||
api.GET("/supported-exchanges", s.handleGetSupportedExchanges)
|
||||
|
||||
|
||||
// 系统配置(无需认证)
|
||||
api.GET("/config", s.handleGetSystemConfig)
|
||||
|
||||
|
||||
// 系统提示词模板管理(无需认证)
|
||||
api.GET("/prompt-templates", s.handleGetPromptTemplates)
|
||||
api.GET("/prompt-templates/:name", s.handleGetPromptTemplate)
|
||||
@@ -118,8 +118,6 @@ func (s *Server) setupRoutes() {
|
||||
protected.GET("/user/signal-sources", s.handleGetUserSignalSource)
|
||||
protected.POST("/user/signal-sources", s.handleSaveUserSignalSource)
|
||||
|
||||
|
||||
|
||||
// 指定trader的数据(使用query参数 ?trader_id=xxx)
|
||||
protected.GET("/status", s.handleStatus)
|
||||
protected.GET("/account", s.handleAccount)
|
||||
@@ -153,24 +151,24 @@ func (s *Server) handleGetSystemConfig(c *gin.Context) {
|
||||
// 使用硬编码的默认币种
|
||||
defaultCoins = []string{"BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "XRPUSDT", "DOGEUSDT", "ADAUSDT", "HYPEUSDT"}
|
||||
}
|
||||
|
||||
|
||||
// 获取杠杆配置
|
||||
btcEthLeverageStr, _ := s.database.GetSystemConfig("btc_eth_leverage")
|
||||
altcoinLeverageStr, _ := s.database.GetSystemConfig("altcoin_leverage")
|
||||
|
||||
|
||||
btcEthLeverage := 5
|
||||
if val, err := strconv.Atoi(btcEthLeverageStr); err == nil && val > 0 {
|
||||
btcEthLeverage = val
|
||||
}
|
||||
|
||||
|
||||
altcoinLeverage := 5
|
||||
if val, err := strconv.Atoi(altcoinLeverageStr); err == nil && val > 0 {
|
||||
altcoinLeverage = val
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"admin_mode": auth.IsAdminMode(),
|
||||
"default_coins": defaultCoins,
|
||||
"admin_mode": auth.IsAdminMode(),
|
||||
"default_coins": defaultCoins,
|
||||
"btc_eth_leverage": btcEthLeverage,
|
||||
"altcoin_leverage": altcoinLeverage,
|
||||
})
|
||||
@@ -180,20 +178,20 @@ func (s *Server) handleGetSystemConfig(c *gin.Context) {
|
||||
func (s *Server) getTraderFromQuery(c *gin.Context) (*manager.TraderManager, string, error) {
|
||||
userID := c.GetString("user_id")
|
||||
traderID := c.Query("trader_id")
|
||||
|
||||
|
||||
// 确保用户的交易员已加载到内存中
|
||||
err := s.traderManager.LoadUserTraders(s.database, userID)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 加载用户 %s 的交易员失败: %v", userID, err)
|
||||
}
|
||||
|
||||
|
||||
if traderID == "" {
|
||||
// 如果没有指定trader_id,返回该用户的第一个trader
|
||||
ids := s.traderManager.GetTraderIDs()
|
||||
if len(ids) == 0 {
|
||||
return nil, "", fmt.Errorf("没有可用的trader")
|
||||
}
|
||||
|
||||
|
||||
// 获取用户的交易员列表,优先返回用户自己的交易员
|
||||
userTraders, err := s.database.GetTraders(userID)
|
||||
if err == nil && len(userTraders) > 0 {
|
||||
@@ -202,7 +200,7 @@ func (s *Server) getTraderFromQuery(c *gin.Context) (*manager.TraderManager, str
|
||||
traderID = ids[0]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return s.traderManager, traderID, nil
|
||||
}
|
||||
|
||||
@@ -298,13 +296,13 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
|
||||
|
||||
// 生成交易员ID
|
||||
traderID := fmt.Sprintf("%s_%s_%d", req.ExchangeID, req.AIModelID, time.Now().Unix())
|
||||
|
||||
|
||||
// 设置默认值
|
||||
isCrossMargin := true // 默认为全仓模式
|
||||
if req.IsCrossMargin != nil {
|
||||
isCrossMargin = *req.IsCrossMargin
|
||||
}
|
||||
|
||||
|
||||
// 设置杠杆默认值(从系统配置获取)
|
||||
btcEthLeverage := 5
|
||||
altcoinLeverage := 5
|
||||
@@ -328,7 +326,7 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 设置系统提示词模板默认值
|
||||
systemPromptTemplate := "default"
|
||||
if req.SystemPromptTemplate != "" {
|
||||
@@ -341,8 +339,8 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
|
||||
scanIntervalMinutes = 3 // 默认3分钟
|
||||
}
|
||||
|
||||
// 创建交易员配置(数据库实体)
|
||||
trader := &config.TraderRecord{
|
||||
// 创建交易员配置(数据库实体)
|
||||
trader := &config.TraderRecord{
|
||||
ID: traderID,
|
||||
UserID: userID,
|
||||
Name: req.Name,
|
||||
@@ -359,7 +357,7 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
|
||||
SystemPromptTemplate: systemPromptTemplate,
|
||||
IsCrossMargin: isCrossMargin,
|
||||
ScanIntervalMinutes: scanIntervalMinutes,
|
||||
IsRunning: false,
|
||||
IsRunning: false,
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
@@ -388,24 +386,24 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
|
||||
|
||||
// UpdateTraderRequest 更新交易员请求
|
||||
type UpdateTraderRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
AIModelID string `json:"ai_model_id" binding:"required"`
|
||||
ExchangeID string `json:"exchange_id" binding:"required"`
|
||||
InitialBalance float64 `json:"initial_balance"`
|
||||
ScanIntervalMinutes int `json:"scan_interval_minutes"`
|
||||
BTCETHLeverage int `json:"btc_eth_leverage"`
|
||||
AltcoinLeverage int `json:"altcoin_leverage"`
|
||||
TradingSymbols string `json:"trading_symbols"`
|
||||
CustomPrompt string `json:"custom_prompt"`
|
||||
OverrideBasePrompt bool `json:"override_base_prompt"`
|
||||
IsCrossMargin *bool `json:"is_cross_margin"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
AIModelID string `json:"ai_model_id" binding:"required"`
|
||||
ExchangeID string `json:"exchange_id" binding:"required"`
|
||||
InitialBalance float64 `json:"initial_balance"`
|
||||
ScanIntervalMinutes int `json:"scan_interval_minutes"`
|
||||
BTCETHLeverage int `json:"btc_eth_leverage"`
|
||||
AltcoinLeverage int `json:"altcoin_leverage"`
|
||||
TradingSymbols string `json:"trading_symbols"`
|
||||
CustomPrompt string `json:"custom_prompt"`
|
||||
OverrideBasePrompt bool `json:"override_base_prompt"`
|
||||
IsCrossMargin *bool `json:"is_cross_margin"`
|
||||
}
|
||||
|
||||
// handleUpdateTrader 更新交易员配置
|
||||
func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
traderID := c.Param("id")
|
||||
|
||||
|
||||
var req UpdateTraderRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
@@ -418,7 +416,7 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取交易员列表失败"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var existingTrader *config.TraderRecord
|
||||
for _, trader := range traders {
|
||||
if trader.ID == traderID {
|
||||
@@ -426,7 +424,7 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if existingTrader == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "交易员不存在"})
|
||||
return
|
||||
@@ -437,7 +435,7 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
if req.IsCrossMargin != nil {
|
||||
isCrossMargin = *req.IsCrossMargin
|
||||
}
|
||||
|
||||
|
||||
// 设置杠杆默认值
|
||||
btcEthLeverage := req.BTCETHLeverage
|
||||
altcoinLeverage := req.AltcoinLeverage
|
||||
@@ -454,8 +452,8 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
scanIntervalMinutes = existingTrader.ScanIntervalMinutes // 保持原值
|
||||
}
|
||||
|
||||
// 更新交易员配置
|
||||
trader := &config.TraderRecord{
|
||||
// 更新交易员配置
|
||||
trader := &config.TraderRecord{
|
||||
ID: traderID,
|
||||
UserID: userID,
|
||||
Name: req.Name,
|
||||
@@ -500,14 +498,14 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
func (s *Server) handleDeleteTrader(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
traderID := c.Param("id")
|
||||
|
||||
|
||||
// 从数据库删除
|
||||
err := s.database.DeleteTrader(userID, traderID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("删除交易员失败: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 如果交易员正在运行,先停止它
|
||||
if trader, err := s.traderManager.GetTrader(traderID); err == nil {
|
||||
status := trader.GetStatus()
|
||||
@@ -516,7 +514,7 @@ func (s *Server) handleDeleteTrader(c *gin.Context) {
|
||||
log.Printf("⏹ 已停止运行中的交易员: %s", traderID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log.Printf("✓ 交易员已删除: %s", traderID)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "交易员已删除"})
|
||||
}
|
||||
@@ -524,20 +522,20 @@ func (s *Server) handleDeleteTrader(c *gin.Context) {
|
||||
// handleStartTrader 启动交易员
|
||||
func (s *Server) handleStartTrader(c *gin.Context) {
|
||||
traderID := c.Param("id")
|
||||
|
||||
|
||||
trader, err := s.traderManager.GetTrader(traderID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "交易员不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 检查交易员是否已经在运行
|
||||
status := trader.GetStatus()
|
||||
if isRunning, ok := status["is_running"].(bool); ok && isRunning {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "交易员已在运行中"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 启动交易员
|
||||
go func() {
|
||||
log.Printf("▶️ 启动交易员 %s (%s)", traderID, trader.GetName())
|
||||
@@ -545,14 +543,14 @@ func (s *Server) handleStartTrader(c *gin.Context) {
|
||||
log.Printf("❌ 交易员 %s 运行错误: %v", trader.GetName(), err)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
// 更新数据库中的运行状态
|
||||
userID := c.GetString("user_id")
|
||||
err = s.database.UpdateTraderStatus(userID, traderID, true)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 更新交易员状态失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
log.Printf("✓ 交易员 %s 已启动", trader.GetName())
|
||||
c.JSON(http.StatusOK, gin.H{"message": "交易员已启动"})
|
||||
}
|
||||
@@ -560,30 +558,30 @@ func (s *Server) handleStartTrader(c *gin.Context) {
|
||||
// handleStopTrader 停止交易员
|
||||
func (s *Server) handleStopTrader(c *gin.Context) {
|
||||
traderID := c.Param("id")
|
||||
|
||||
|
||||
trader, err := s.traderManager.GetTrader(traderID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "交易员不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 检查交易员是否正在运行
|
||||
status := trader.GetStatus()
|
||||
if isRunning, ok := status["is_running"].(bool); ok && !isRunning {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "交易员已停止"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 停止交易员
|
||||
trader.Stop()
|
||||
|
||||
|
||||
// 更新数据库中的运行状态
|
||||
userID := c.GetString("user_id")
|
||||
err = s.database.UpdateTraderStatus(userID, traderID, false)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 更新交易员状态失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
log.Printf("⏹ 交易员 %s 已停止", trader.GetName())
|
||||
c.JSON(http.StatusOK, gin.H{"message": "交易员已停止"})
|
||||
}
|
||||
@@ -592,24 +590,24 @@ func (s *Server) handleStopTrader(c *gin.Context) {
|
||||
func (s *Server) handleUpdateTraderPrompt(c *gin.Context) {
|
||||
traderID := c.Param("id")
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
|
||||
var req struct {
|
||||
CustomPrompt string `json:"custom_prompt"`
|
||||
OverrideBasePrompt bool `json:"override_base_prompt"`
|
||||
CustomPrompt string `json:"custom_prompt"`
|
||||
OverrideBasePrompt bool `json:"override_base_prompt"`
|
||||
}
|
||||
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 更新数据库
|
||||
err := s.database.UpdateTraderCustomPrompt(userID, traderID, req.CustomPrompt, req.OverrideBasePrompt)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("更新自定义prompt失败: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 如果trader在内存中,更新其custom prompt和override设置
|
||||
trader, err := s.traderManager.GetTrader(traderID)
|
||||
if err == nil {
|
||||
@@ -617,7 +615,7 @@ func (s *Server) handleUpdateTraderPrompt(c *gin.Context) {
|
||||
trader.SetOverrideBasePrompt(req.OverrideBasePrompt)
|
||||
log.Printf("✓ 已更新交易员 %s 的自定义prompt (覆盖基础=%v)", trader.GetName(), req.OverrideBasePrompt)
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "自定义prompt已更新"})
|
||||
}
|
||||
|
||||
@@ -632,7 +630,7 @@ func (s *Server) handleGetModelConfigs(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
log.Printf("✅ 找到 %d 个AI模型配置", len(models))
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, models)
|
||||
}
|
||||
|
||||
@@ -676,7 +674,7 @@ func (s *Server) handleGetExchangeConfigs(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
log.Printf("✅ 找到 %d 个交易所配置", len(exchanges))
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, exchanges)
|
||||
}
|
||||
|
||||
@@ -721,7 +719,7 @@ func (s *Server) handleGetUserSignalSource(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"coin_pool_url": source.CoinPoolURL,
|
||||
"oi_top_url": source.OITopURL,
|
||||
@@ -735,18 +733,18 @@ func (s *Server) handleSaveUserSignalSource(c *gin.Context) {
|
||||
CoinPoolURL string `json:"coin_pool_url"`
|
||||
OITopURL string `json:"oi_top_url"`
|
||||
}
|
||||
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
err := s.database.CreateUserSignalSource(userID, req.CoinPoolURL, req.OITopURL)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("保存用户信号源配置失败: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
log.Printf("✓ 用户信号源配置已保存: user=%s, coin_pool=%s, oi_top=%s", userID, req.CoinPoolURL, req.OITopURL)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "用户信号源配置已保存"})
|
||||
}
|
||||
@@ -822,21 +820,21 @@ func (s *Server) handleGetTraderConfig(c *gin.Context) {
|
||||
aiModelID := traderConfig.AIModelID
|
||||
|
||||
result := map[string]interface{}{
|
||||
"trader_id": traderConfig.ID,
|
||||
"trader_name": traderConfig.Name,
|
||||
"ai_model": aiModelID,
|
||||
"exchange_id": traderConfig.ExchangeID,
|
||||
"initial_balance": traderConfig.InitialBalance,
|
||||
"scan_interval_minutes": traderConfig.ScanIntervalMinutes,
|
||||
"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,
|
||||
"trader_id": traderConfig.ID,
|
||||
"trader_name": traderConfig.Name,
|
||||
"ai_model": aiModelID,
|
||||
"exchange_id": traderConfig.ExchangeID,
|
||||
"initial_balance": traderConfig.InitialBalance,
|
||||
"scan_interval_minutes": traderConfig.ScanIntervalMinutes,
|
||||
"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,
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
@@ -1003,13 +1001,13 @@ func (s *Server) handleStatistics(c *gin.Context) {
|
||||
// handleCompetition 竞赛总览(对比所有trader)
|
||||
func (s *Server) handleCompetition(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
|
||||
// 确保用户的交易员已加载到内存中
|
||||
err := s.traderManager.LoadUserTraders(s.database, userID)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 加载用户 %s 的交易员失败: %v", userID, err)
|
||||
}
|
||||
|
||||
|
||||
competition, err := s.traderManager.GetCompetitionData()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
@@ -1017,7 +1015,7 @@ func (s *Server) handleCompetition(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, competition)
|
||||
}
|
||||
|
||||
@@ -1144,7 +1142,7 @@ func (s *Server) authMiddleware() gin.HandlerFunc {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "缺少Authorization头"})
|
||||
@@ -1227,11 +1225,11 @@ func (s *Server) handleRegister(c *gin.Context) {
|
||||
// 返回OTP设置信息
|
||||
qrCodeURL := auth.GetOTPQRCodeURL(otpSecret, req.Email)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user_id": userID,
|
||||
"email": req.Email,
|
||||
"otp_secret": otpSecret,
|
||||
"user_id": userID,
|
||||
"email": req.Email,
|
||||
"otp_secret": otpSecret,
|
||||
"qr_code_url": qrCodeURL,
|
||||
"message": "请使用Google Authenticator扫描二维码并验证OTP",
|
||||
"message": "请使用Google Authenticator扫描二维码并验证OTP",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1316,8 +1314,8 @@ func (s *Server) handleLogin(c *gin.Context) {
|
||||
// 检查OTP是否已验证
|
||||
if !user.OTPVerified {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": "账户未完成OTP设置",
|
||||
"user_id": user.ID,
|
||||
"error": "账户未完成OTP设置",
|
||||
"user_id": user.ID,
|
||||
"requires_otp_setup": true,
|
||||
})
|
||||
return
|
||||
@@ -1325,9 +1323,9 @@ func (s *Server) handleLogin(c *gin.Context) {
|
||||
|
||||
// 返回需要OTP验证的状态
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user_id": user.ID,
|
||||
"email": user.Email,
|
||||
"message": "请输入Google Authenticator验证码",
|
||||
"user_id": user.ID,
|
||||
"email": user.Email,
|
||||
"message": "请输入Google Authenticator验证码",
|
||||
"requires_otp": true,
|
||||
})
|
||||
}
|
||||
@@ -1389,7 +1387,7 @@ func (s *Server) handleGetSupportedModels(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取支持的AI模型失败"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, models)
|
||||
}
|
||||
|
||||
@@ -1402,7 +1400,7 @@ func (s *Server) handleGetSupportedExchanges(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取支持的交易所失败"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, exchanges)
|
||||
}
|
||||
|
||||
@@ -1438,7 +1436,7 @@ func (s *Server) Start() error {
|
||||
func (s *Server) handleGetPromptTemplates(c *gin.Context) {
|
||||
// 导入 decision 包
|
||||
templates := decision.GetAllPromptTemplates()
|
||||
|
||||
|
||||
// 转换为响应格式
|
||||
response := make([]map[string]interface{}, 0, len(templates))
|
||||
for _, tmpl := range templates {
|
||||
@@ -1446,7 +1444,7 @@ func (s *Server) handleGetPromptTemplates(c *gin.Context) {
|
||||
"name": tmpl.Name,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"templates": response,
|
||||
})
|
||||
@@ -1455,13 +1453,13 @@ func (s *Server) handleGetPromptTemplates(c *gin.Context) {
|
||||
// handleGetPromptTemplate 获取指定名称的提示词模板内容
|
||||
func (s *Server) handleGetPromptTemplate(c *gin.Context) {
|
||||
templateName := c.Param("name")
|
||||
|
||||
|
||||
template, err := decision.GetPromptTemplate(templateName)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("模板不存在: %s", templateName)})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"name": template.Name,
|
||||
"content": template.Content,
|
||||
|
||||
Reference in New Issue
Block a user