xy_sh-20260727101126/xy_sh/pkg/func.go

128 lines
2.5 KiB
Go

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
}