Files
go-utils/utils/url.go
2024-10-28 11:05:02 +08:00

87 lines
1.9 KiB
Go

package utils
import (
"fmt"
"reflect"
"strings"
)
var Url = &UrlClass{}
type UrlClass struct {
}
// Encoded - 将 map 编码为 URL 查询字符串 - x-www-form-urlencoded
func (this *UrlClass) Encoded(params map[string]any) string {
var parts []string
for key, value := range params {
parts = append(parts, this.build(key, value)...)
}
return strings.Join(parts, "&")
}
// EncodedKeys - 获取 URL 查询字符串的键
func (this *UrlClass) EncodedKeys(params map[string]any) []string {
encoded := this.Encoded(params)
// & 分隔数组,字符串转数组
keys := strings.Split(encoded, "&")
// 去除 = 号之后的内容,包含 = 号
for i, item := range keys {
keys[i] = item[:strings.Index(item, "=")]
}
return keys
}
// build - 构建 URL 查询字符串
func (this *UrlClass) build(key string, value any) []string {
var parts []string
switch item := value.(type) {
case string:
parts = append(parts, fmt.Sprintf("%s=%v", key, item))
case []string:
for _, sv := range item {
parts = append(parts, fmt.Sprintf("%s[]=%v", key, sv))
}
case []int:
for _, iv := range item {
parts = append(parts, fmt.Sprintf("%s[]=%d", key, iv))
}
case map[string]any:
for k, sub := range item {
parts = append(parts, this.build(fmt.Sprintf("%s[%s]", key, k), sub)...)
}
case []any:
for i, sub := range item {
parts = append(parts, this.build(fmt.Sprintf("%s[%d]", key, i), sub)...)
}
default:
parts = append(parts, fmt.Sprintf("%s=%v", key, this.stringify(value)))
}
return parts
}
// stringify - 将任意类型转换为字符串
func (this *UrlClass) stringify(value any) string {
item := reflect.ValueOf(value)
switch item.Kind() {
case reflect.Array, reflect.Slice:
var strVals []string
for i := 0; i < item.Len(); i++ {
strVals = append(strVals, fmt.Sprintf("%v", item.Index(i)))
}
return strings.Join(strVals, ",")
default:
return fmt.Sprintf("%v", value)
}
}