|
|
package mapx |
|
|
|
|
|
import ( |
|
|
"encoding/json" |
|
|
"fmt" |
|
|
"net/url" |
|
|
"reflect" |
|
|
"sort" |
|
|
"strconv" |
|
|
"strings" |
|
|
"time" |
|
|
) |
|
|
|
|
|
const dot = "." |
|
|
|
|
|
type Mapx map[string]interface{} |
|
|
|
|
|
func (m *Mapx) IsNil(key string) bool { |
|
|
return m.Get(key) == nil |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetString(key string) string { |
|
|
return fmt.Sprintf("%v", m.Get(key)) |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetTime(key string) time.Time { |
|
|
t, _ := time.ParseInLocation(time.RFC3339, m.GetString(key), time.Local) |
|
|
return t |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetInt(key string) int64 { |
|
|
i, _ := strconv.ParseInt(m.GetString(key), 10, 64) |
|
|
return i |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetFloat(key string) float64 { |
|
|
f, _ := strconv.ParseFloat(fmt.Sprintf("%v", m.Get(key)), 64) |
|
|
return f |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetBool(key string) bool { |
|
|
b, _ := strconv.ParseBool(fmt.Sprintf("%v", m.Get(key))) |
|
|
return b |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetMapx(key string) *Mapx { |
|
|
v, _ := m.Get(key).(map[string]interface{}) |
|
|
return (*Mapx)(&v) |
|
|
} |
|
|
|
|
|
func (m *Mapx) GetSlice(key string, fn func(item *Mapx, index int) bool) { |
|
|
value := reflect.ValueOf(m.Get(key)) |
|
|
if value.Kind() != reflect.Slice { |
|
|
return |
|
|
} |
|
|
for i := 0; i < value.Len(); i++ { |
|
|
item := value.Index(i) |
|
|
if item.Kind() != reflect.Invalid { |
|
|
v, _ := item.Interface().(map[string]interface{}) |
|
|
if !fn((*Mapx)(&v), i) { |
|
|
break |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
func (m *Mapx) Set(key string, val any) *Mapx { |
|
|
(*m)[key] = val |
|
|
return m |
|
|
} |
|
|
|
|
|
func (m *Mapx) Get(key string) any { |
|
|
if m == nil { |
|
|
return nil |
|
|
} |
|
|
var v any = map[string]interface{}(*m) |
|
|
keys := strings.Split(key, dot) |
|
|
for i := 0; i < len(keys); i++ { |
|
|
if v == nil { |
|
|
return nil |
|
|
} |
|
|
k := keys[i] |
|
|
switch kind := reflect.TypeOf(v).Kind(); kind { |
|
|
case reflect.Map: |
|
|
_v := reflect.ValueOf(v).MapIndex(reflect.ValueOf(k)) |
|
|
if _v.Kind() != reflect.Invalid { |
|
|
v = _v.Interface() |
|
|
} else { |
|
|
v = nil |
|
|
} |
|
|
case reflect.Slice: |
|
|
if len(k) > 2 && k[0] == '[' && k[len(k)-1] == ']' { |
|
|
idx, err := strconv.Atoi(k[1 : len(k)-1]) |
|
|
if err != nil { |
|
|
return nil |
|
|
} |
|
|
_v := reflect.ValueOf(v).Index(idx) |
|
|
if _v.Kind() != reflect.Invalid { |
|
|
v = _v.Interface() |
|
|
} else { |
|
|
v = nil |
|
|
} |
|
|
} |
|
|
case reflect.Struct: |
|
|
_v := reflect.ValueOf(v).FieldByName(k) |
|
|
if _v.Kind() != reflect.Invalid { |
|
|
v = _v.Interface() |
|
|
} else { |
|
|
v = nil |
|
|
} |
|
|
|
|
|
case reflect.Ptr: |
|
|
v = reflect.ValueOf(v).Elem().Interface() |
|
|
i-- |
|
|
case reflect.Invalid: |
|
|
return nil |
|
|
default: |
|
|
return nil |
|
|
} |
|
|
} |
|
|
return v |
|
|
} |
|
|
|
|
|
func (m *Mapx) Remove(key string) { |
|
|
delete(*m, key) |
|
|
} |
|
|
|
|
|
func (m *Mapx) Json() string { |
|
|
b, _ := json.Marshal(&m) |
|
|
return string(b) |
|
|
} |
|
|
|
|
|
func UnmarshalJSON(data []byte) (m *Mapx) { |
|
|
_ = json.Unmarshal(data, &m) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
func (m *Mapx) EncodeAliPaySignParams() string { |
|
|
if m == nil { |
|
|
return "" |
|
|
} |
|
|
var ( |
|
|
buf strings.Builder |
|
|
keyList []string |
|
|
) |
|
|
for k := range *m { |
|
|
keyList = append(keyList, k) |
|
|
} |
|
|
sort.Strings(keyList) |
|
|
for _, k := range keyList { |
|
|
if v := m.GetString(k); v != "" { |
|
|
buf.WriteString(k) |
|
|
buf.WriteByte('=') |
|
|
buf.WriteString(v) |
|
|
buf.WriteByte('&') |
|
|
} |
|
|
} |
|
|
if buf.Len() <= 0 { |
|
|
return "" |
|
|
} |
|
|
return buf.String()[:buf.Len()-1] |
|
|
} |
|
|
|
|
|
|
|
|
func (m *Mapx) EncodeURLParams() string { |
|
|
if m == nil { |
|
|
return "" |
|
|
} |
|
|
var ( |
|
|
buf strings.Builder |
|
|
keys []string |
|
|
) |
|
|
for k := range *m { |
|
|
keys = append(keys, k) |
|
|
} |
|
|
sort.Strings(keys) |
|
|
for _, k := range keys { |
|
|
if v := m.GetString(k); v != "" { |
|
|
buf.WriteString(url.QueryEscape(k)) |
|
|
buf.WriteByte('=') |
|
|
buf.WriteString(url.QueryEscape(v)) |
|
|
buf.WriteByte('&') |
|
|
} |
|
|
} |
|
|
if buf.Len() <= 0 { |
|
|
return "" |
|
|
} |
|
|
return buf.String()[:buf.Len()-1] |
|
|
} |
|
|
|
|
|
func (m *Mapx) ValidateEmpty(keys ...string) error { |
|
|
var emptyKeys []string |
|
|
for _, k := range keys { |
|
|
if m.IsNil(k) { |
|
|
emptyKeys = append(emptyKeys, k) |
|
|
} |
|
|
} |
|
|
if len(emptyKeys) > 0 { |
|
|
return fmt.Errorf("[miss param error], %v", strings.Join(emptyKeys, ", ")) |
|
|
} |
|
|
return nil |
|
|
} |
|
|
|