package apimart import ( "context" "encoding/json" "errors" "fmt" "io" "net/http" "strings" "juhe-factory/api/internal/provider" ) type BalanceResult struct { RemainBalance float64 `json:"remain_balance"` RemainCredits float64 `json:"remain_credits"` UsedBalance float64 `json:"used_balance"` UsedCredits float64 `json:"used_credits"` UnlimitedQuota bool `json:"unlimited_quota"` } func (c Client) Balance(ctx context.Context, baseURL, apiKey string) (BalanceResult, error) { var result BalanceResult request, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(baseURL, "/")+"/user/balance", nil) if err != nil { return result, err } request.Header.Set("Authorization", "Bearer "+apiKey) client := c.HTTPClient if client == nil { client = http.DefaultClient } response, err := client.Do(request) if err != nil { return result, err } defer response.Body.Close() data, err := io.ReadAll(io.LimitReader(response.Body, 1024*1024)) if err != nil { return result, err } if response.StatusCode < 200 || response.StatusCode >= 300 { return result, &provider.HTTPError{StatusCode: response.StatusCode, Body: safeBody(data), RetryAfter: response.Header.Get("Retry-After")} } var decoded struct { Success bool `json:"success"` Message string `json:"message"` BalanceResult } if err := json.Unmarshal(data, &decoded); err != nil { return result, fmt.Errorf("余额响应不是有效 JSON: %w", err) } if !decoded.Success { if decoded.Message == "" { return result, errors.New("获取渠道余额失败") } return result, errors.New(decoded.Message) } return decoded.BalanceResult, nil }