package pkg import ( "encoding/json" "fmt" "io" "net/http" "os" "time" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/log" ) // GetPublicIP 获取公网 IP func GetPublicIP() (string, error) { client := http.Client{ Timeout: 5 * time.Second, } // 多个备用服务,提高可用性 services := []struct { url string isJSON bool parseFn func([]byte) (string, error) }{ { url: "https://api.ipify.org?format=json", isJSON: true, parseFn: func(body []byte) (string, error) { var result map[string]string if err := json.Unmarshal(body, &result); err != nil { return "", err } if ip, ok := result["ip"]; ok { return ip, nil } return "", fmt.Errorf("未找到 IP 字段") }, }, { url: "https://ipinfo.io/ip", isJSON: false, parseFn: func(body []byte) (string, error) { return string(body), nil }, }, { url: "https://api.my-ip.io/ip", isJSON: false, parseFn: func(body []byte) (string, error) { return string(body), nil }, }, { url: "https://httpbin.org/ip", isJSON: true, parseFn: func(body []byte) (string, error) { var result map[string]string if err := json.Unmarshal(body, &result); err != nil { return "", err } if ip, ok := result["origin"]; ok { return ip, nil } return "", fmt.Errorf("未找到 IP 字段") }, }, } for _, service := range services { resp, err := client.Get(service.url) if err != nil { continue } body, err := io.ReadAll(resp.Body) resp.Body.Close() if err != nil { continue } ip, err := service.parseFn(body) if err == nil && ip != "" { return ip, nil } } return "", fmt.Errorf("所有服务都无法获取公网 IP") } func HandleResponse(c *fiber.Ctx, data interface{}) (err error) { if os.Getenv("env") == "unit_test" { log.Debug(data) } switch data.(type) { case error: err = data.(error) case int, int32, int64, float32, float64, string, bool: c.Response().SetBody([]byte(fmt.Sprintf("%s", data))) case []byte: c.Response().SetBody(data.([]byte)) default: dataByte, _ := json.Marshal(data) c.Response().SetBody(dataByte) } return } // StructToMap 将结构体转换为 map[string]any func StructToMap(v any) (map[string]any, error) { b, err := json.Marshal(v) if err != nil { return nil, err } var m map[string]any err = json.Unmarshal(b, &m) return m, err } func StructToMapWithOutErr(v any) map[string]any { b, _ := json.Marshal(v) var m map[string]any _ = json.Unmarshal(b, &m) return m }