package utils import ( "bytes" "context" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "os" "path/filepath" "time" ) // HTTPClient 封装HTTP客户端 type HTTPClient struct { client *http.Client baseURL string Authorization string } // NewHTTPClient 创建新的HTTP客户端 func NewHTTPClient(baseURL, token string) *HTTPClient { return &HTTPClient{ client: &http.Client{ Timeout: 30 * time.Second, }, baseURL: baseURL, Authorization: token, } } // SetToken 设置认证token func (c *HTTPClient) SetToken(token string) { c.Authorization = token } // Get 发起GET请求 func (c *HTTPClient) Get(ctx context.Context, endpoint string, headers map[string]string) (*http.Response, error) { url := c.baseURL + endpoint req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } // 设置默认headers req.Header.Set("Content-Type", "application/json") if c.Authorization != "" { req.Header.Set("Authorization", "Bearer "+c.Authorization) } // 设置自定义headers for key, value := range headers { req.Header.Set(key, value) } println("Header====>>>>", req.Header) return c.client.Do(req) } // Post 发起POST请求 func (c *HTTPClient) Post(ctx context.Context, endpoint string, data interface{}, headers map[string]string) (*http.Response, error) { url := c.baseURL + endpoint var reqBody io.Reader if data != nil { jsonData, err := json.Marshal(data) if err != nil { return nil, fmt.Errorf("序列化请求数据失败: %w", err) } reqBody = bytes.NewBuffer(jsonData) } req, err := http.NewRequestWithContext(ctx, "POST", url, reqBody) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } // 设置默认headers req.Header.Set("Content-Type", "application/json") if c.Authorization != "" { req.Header.Set("Authorization", "Bearer "+c.Authorization) } // 设置自定义headers for key, value := range headers { req.Header.Set(key, value) } return c.client.Do(req) } // UploadFile 上传文件 func (c *HTTPClient) UploadFile(ctx context.Context, endpoint string, filePath string, fieldName string, headers map[string]string, result interface{}) error { url := c.baseURL + endpoint // 打开文件 file, err := os.Open(filePath) if err != nil { return fmt.Errorf("打开文件失败: %w", err) } defer file.Close() // 创建multipart表单 var buf bytes.Buffer writer := multipart.NewWriter(&buf) // 添加文件字段 fileWriter, err := writer.CreateFormFile(fieldName, filepath.Base(filePath)) if err != nil { return fmt.Errorf("创建表单文件字段失败: %w", err) } // 复制文件内容到表单 _, err = io.Copy(fileWriter, file) if err != nil { return fmt.Errorf("复制文件内容失败: %w", err) } // 关闭表单写入器 err = writer.Close() if err != nil { return fmt.Errorf("关闭表单写入器失败: %w", err) } // 创建请求 req, err := http.NewRequestWithContext(ctx, "POST", url, &buf) if err != nil { return fmt.Errorf("创建请求失败: %w", err) } // 设置内容类型为multipart表单 req.Header.Set("Content-Type", writer.FormDataContentType()) // 设置认证头 if c.Authorization != "" { req.Header.Set("Authorization", "Bearer "+c.Authorization) } // 设置自定义headers for key, value := range headers { req.Header.Set(key, value) } resp, err := c.client.Do(req) if err != nil { return err } return c.ParseJSON(resp, result) } // ParseJSON 解析JSON响应 func (c *HTTPClient) ParseJSON(resp *http.Response, result interface{}) error { defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("读取响应体失败: %w", err) } if resp.StatusCode >= 400 { return fmt.Errorf("请求失败 status=%d body=%s", resp.StatusCode, string(body)) } if err := json.Unmarshal(body, result); err != nil { return fmt.Errorf("解析JSON失败: %w, body=%s", err, string(body)) } return nil } // GetJSON 发起GET请求并解析JSON响应 func (c *HTTPClient) GetJSON(ctx context.Context, endpoint string, result interface{}, headers map[string]string) error { resp, err := c.Get(ctx, endpoint, headers) if err != nil { return err } return c.ParseJSON(resp, result) } // PostJSON 发起POST请求并解析JSON响应 func (c *HTTPClient) PostJSON(ctx context.Context, endpoint string, data interface{}, result interface{}, headers map[string]string) error { resp, err := c.Post(ctx, endpoint, data, headers) if err != nil { return err } return c.ParseJSON(resp, result) }