Files
workspace/code/allapp/allapp-go2/utils/httpx/index.go
T
2026-02-25 17:31:09 +08:00

166 lines
3.3 KiB
Go

package httpx
import (
"context"
"encoding/json"
"fmt"
"net/url"
"sync"
"time"
"github.com/cloudwego/hertz/pkg/app/client"
"github.com/cloudwego/hertz/pkg/protocol"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
var (
once sync.Once
clientInstance *HertzClient
)
// HertzClient 定义
type HertzClient struct {
Client *client.Client
Timeout time.Duration
Header map[string]string
}
// Init 初始化单例
func Init() {
once.Do(func() {
c, _ := client.NewClient()
clientInstance = &HertzClient{
Client: c,
Timeout: 5 * time.Second,
Header: make(map[string]string),
}
})
}
// SetHeader 设置默认 header
func SetHeader(key, value string) {
if clientInstance == nil {
Init()
}
clientInstance.Header[key] = value
}
// 支持 value 为任意类型
func buildQueryString(query map[string][]any) string {
if len(query) == 0 {
return ""
}
values := url.Values{}
for k, arr := range query {
for _, v := range arr {
values.Add(k, fmt.Sprintf("%v", v)) // 自动转 string
}
}
return values.Encode()
}
func Get(ctx context.Context, urlStr string, query map[string][]any) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodGet)
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err := h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func PostJSON(ctx context.Context, urlStr string, query map[string][]any, payload any) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodPost)
req.Header.SetContentTypeBytes([]byte("application/json"))
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
data, err := json.Marshal(payload)
if err != nil {
return 0, "", fmt.Errorf("marshal json error: %w", err)
}
req.SetBody(data)
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err = h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func PostForm(ctx context.Context, urlStr string, query map[string][]any, form map[string]string) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodPost)
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
req.SetFormData(form)
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err := h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func JSONStringToMap(jsonStr string) (map[string]interface{}, error) {
var result map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &result); err != nil {
return nil, err
}
return result, nil
}