package sync import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "time" ) type HttpClient struct { BaseURL string Timeout time.Duration HTTPClient *http.Client } func NewHttpClient(baseURL string, timeout time.Duration) *HttpClient { if timeout == 0 { timeout = 30 * time.Second } return &HttpClient{ BaseURL: baseURL, Timeout: timeout, HTTPClient: &http.Client{ Timeout: timeout, }, } } func (c *HttpClient) Post(ctx context.Context, url string, body interface{}) ([]byte, error) { jsonData, err := json.Marshal(body) if err != nil { return nil, fmt.Errorf("序列化请求失败:%w", err) } fullURL := url if c.BaseURL != "" && len(url) > 0 && url[0] != '/' { fullURL = c.BaseURL + url } else if c.BaseURL != "" { fullURL = c.BaseURL + url } req, err := http.NewRequestWithContext(ctx, "POST", fullURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("创建请求失败:%w", err) } req.Header.Set("Content-Type", "application/json") resp, err := c.HTTPClient.Do(req) if err != nil { return nil, fmt.Errorf("请求失败:%w", err) } defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("读取响应失败:%w", err) } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("HTTP 错误状态码:%d", resp.StatusCode) } return respBody, nil }