package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "strings" "time" "qiweimanager/config" ) // WanchuanLogin 登录万川平台并返回原始响应 func (a *App) WanchuanLogin(baseURL, username, password string) string { startTime := time.Now() // 构建请求体 loginData := map[string]interface{}{ "username": username, "password": password, "loginType": "user", } jsonData, err := json.Marshal(loginData) if err != nil { globalLogger.Error("[WanchuanLogin] 序列化登录数据失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "序列化登录数据失败: %v"}`, err) } // 打印日志(密码打码) globalLogger.Info("[WanchuanLogin] 登录请求 - URL: %s/api/login, 用户名: %s, 密码: %s", baseURL, username, maskString(password)) // 发送 POST 请求 url := fmt.Sprintf("%s/api/login", strings.TrimRight(baseURL, "/")) req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { globalLogger.Error("[WanchuanLogin] 创建请求失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "创建请求失败: %v"}`, err) } req.Header.Set("Content-Type", "application/json;charset=UTF-8") client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) if err != nil { globalLogger.Error("[WanchuanLogin] 请求失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "请求失败: %v"}`, err) } defer resp.Body.Close() // 读取响应 body, err := io.ReadAll(resp.Body) if err != nil { globalLogger.Error("[WanchuanLogin] 读取响应失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "读取响应失败: %v"}`, err) } responseStr := string(body) // 打印日志(token 打码) maskedResponse := maskToken(responseStr) duration := time.Since(startTime).Milliseconds() globalLogger.Info("[WanchuanLogin] 登录完成 - 耗时: %dms, 响应: %s", duration, maskedResponse) a.AddLogEntry("Wanchuan", "info", fmt.Sprintf("平台登录完成 - 用户: %s", username), duration) // 原样返回平台响应 return responseStr } // WanchuanGetModel 获取模型配置并返回原始响应 func (a *App) WanchuanGetModel(baseURL, code, token string) string { startTime := time.Now() globalLogger.Info("[WanchuanGetModel] 获取模型 - URL: %s/api/system/model/getByCode/%s, Token: %s", baseURL, code, maskString(token)) // 发送 GET 请求 url := fmt.Sprintf("%s/api/system/model/getByCode/%s", strings.TrimRight(baseURL, "/"), code) req, err := http.NewRequest("GET", url, nil) if err != nil { globalLogger.Error("[WanchuanGetModel] 创建请求失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "创建请求失败: %v"}`, err) } // 设置认证头(平台同时支持两种) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) req.Header.Set("token", fmt.Sprintf("Bearer %s", token)) client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) if err != nil { globalLogger.Error("[WanchuanGetModel] 请求失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "请求失败: %v"}`, err) } defer resp.Body.Close() // 读取响应 body, err := io.ReadAll(resp.Body) if err != nil { globalLogger.Error("[WanchuanGetModel] 读取响应失败: %v", err) return fmt.Sprintf(`{"success": false, "error": "读取响应失败: %v"}`, err) } responseStr := string(body) // 打印日志(apiKey 打码) maskedResponse := maskApiKey(responseStr) duration := time.Since(startTime).Milliseconds() globalLogger.Info("[WanchuanGetModel] 获取模型完成 - code: %s, 耗时: %dms, 响应: %s", code, duration, maskedResponse) a.AddLogEntry("Wanchuan", "info", fmt.Sprintf("获取模型配置 - code: %s", code), duration) // 原样返回平台响应 return responseStr } // GetPlatformConfig 获取平台配置 func (a *App) GetPlatformConfig() interface{} { globalLogger.Info("[GetPlatformConfig] 读取平台配置") appConfig := config.GetGlobalConfig() if appConfig == nil { globalLogger.Warn("[GetPlatformConfig] 全局配置不存在") return config.PlatformConfig{} } return appConfig.PlatformConfig } // SavePlatformConfig 保存平台配置 func (a *App) SavePlatformConfig(jsonData string) (bool, string) { startTime := time.Now() globalLogger.Info("[SavePlatformConfig] 保存平台配置 - 数据: %s", maskPlatformConfig(jsonData)) var platformConfig config.PlatformConfig if err := json.Unmarshal([]byte(jsonData), &platformConfig); err != nil { msg := fmt.Sprintf("解析平台配置失败: %v", err) globalLogger.Error("%s", msg) return false, msg } if err := config.UpdatePlatformConfig(platformConfig); err != nil { msg := fmt.Sprintf("保存平台配置失败: %v", err) globalLogger.Error("%s", msg) return false, msg } duration := time.Since(startTime).Milliseconds() globalLogger.Info("[SavePlatformConfig] 保存成功 - 耗时: %dms", duration) a.AddLogEntry("Wanchuan", "info", "平台配置已保存", duration) return true, "success" } // maskString 对字符串打码(保留首尾,中间用 * 替换) func maskString(s string) string { if len(s) <= 8 { return "***" } return s[:4] + "****" + s[len(s)-4:] } // maskToken 对 JSON 响应中的 token 打码 func maskToken(jsonStr string) string { var data map[string]interface{} if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { return jsonStr } // 递归打码 token 字段 maskTokenInMap(data) masked, _ := json.Marshal(data) return string(masked) } // maskApiKey 对 JSON 响应中的 apiKey 打码 func maskApiKey(jsonStr string) string { var data map[string]interface{} if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { return jsonStr } // 递归打码 apiKey 字段 maskApiKeyInMap(data) masked, _ := json.Marshal(data) return string(masked) } // maskPlatformConfig 对平台配置中的密码打码 func maskPlatformConfig(jsonStr string) string { var data map[string]interface{} if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { return jsonStr } if pwd, ok := data["password"].(string); ok && pwd != "" { data["password"] = maskString(pwd) } masked, _ := json.Marshal(data) return string(masked) } func maskTokenInMap(m map[string]interface{}) { for k, v := range m { if k == "token" || k == "access_token" { if s, ok := v.(string); ok && s != "" { m[k] = maskString(s) } } else if subMap, ok := v.(map[string]interface{}); ok { maskTokenInMap(subMap) } } } func maskApiKeyInMap(m map[string]interface{}) { for k, v := range m { if k == "apiKey" || k == "api_key" { if s, ok := v.(string); ok && s != "" { m[k] = maskString(s) } } else if k == "encryptedConfig" { if s, ok := v.(string); ok && s != "" { // encryptedConfig 是 JSON 字符串,需要二次解析 var configMap map[string]interface{} if err := json.Unmarshal([]byte(s), &configMap); err == nil { maskApiKeyInMap(configMap) masked, _ := json.Marshal(configMap) m[k] = string(masked) } } } else if subMap, ok := v.(map[string]interface{}); ok { maskApiKeyInMap(subMap) } } }