package utils import ( "crypto/md5" "crypto/sha1" "encoding/hex" "encoding/json" "fmt" "github.com/jinzhu/copier" "github.com/joho/godotenv" "io" "log" "os" "reflect" "sort" "strings" "zhiyuan/pkg/config" "zhiyuan/pkg/logger" ) func GetEnv(envName string) string { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } return os.Getenv(envName) } func PowInt(x int, y int) int { if y <= 0 { return 1 } else { if y%2 == 0 { sqrt := PowInt(x, y/2) return sqrt * sqrt } else { return PowInt(x, y-1) * x } } } func MergeMap(src, dest map[string]interface{}) map[string]interface{} { for k, v := range dest { src[k] = v } return src } func StructToMapViaJson(data interface{}) (map[string]interface{}, error) { dataBytes, err := json.Marshal(data) if err != nil { return nil, err } mapData := make(map[string]interface{}) err = json.Unmarshal(dataBytes, &mapData) if err != nil { return nil, err } return mapData, nil } func StructToMapViaReflect(target interface{}, useTag string) map[string]interface{} { if nil == target { return nil } v := reflect.ValueOf(target) for v.Kind() == reflect.Ptr { v = v.Elem() } if v.Kind() != reflect.Struct { return nil } t := v.Type() result := make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { keyName := t.Field(i).Tag.Get(useTag) if keyName == "" { keyName = t.Field(i).Name } else { keyName = strings.TrimSpace(strings.Split(keyName, ",")[0]) } result[keyName] = v.Field(i).Interface() } return result } func JsonToString(v interface{}) string { res, err := json.Marshal(v) if err != nil { logger.Log.Fatal("Error json") } return string(res) } func RemoveRepeatByLoop(arr []string) []string { newArr := make([]string, 0) for i := 0; i < len(arr); i++ { repeat := false for j := i + 1; j < len(arr); j++ { if arr[i] == arr[j] { repeat = true break } } if !repeat { newArr = append(newArr, arr[i]) } } return newArr } func RemoveRepeatByMap(arr []string) []string { newArr := make([]string, 0) tempMap := make(map[string]interface{}, 0) for _, v := range arr { if tempMap[v] == nil { newArr = append(newArr, v) tempMap[v] = v } } return newArr } func RemoveRepeat(arr []string) []string { if len(arr) < 1024 { return RemoveRepeatByLoop(arr) } else { return RemoveRepeatByMap(arr) } } func ParseSliceMap(value interface{}, mapKey string) map[string]map[string]interface{} { res := make(map[string]map[string]interface{}, 0) if valueMap, ok := value.([]map[string]interface{}); ok { for _, v := range valueMap { res[ToStr(v[mapKey])] = v } } else if valueSlice, ok := value.([]interface{}); ok { for _, v := range valueSlice { mapV := StructToMapViaReflect(v, "json") res[ToStr(mapV[mapKey])] = mapV } } else if reflect.TypeOf(value).Kind() == reflect.Slice { s := reflect.ValueOf(value) for i := 0; i < s.Len(); i++ { mapV := StructToMapViaReflect(s.Index(i).Interface(), "json") res[ToStr(mapV[mapKey])] = mapV } } return res } func JoinSliceMap(value interface{}, mapKey string, joinStr string) string { var strList []string if valueMap, ok := value.([]map[string]interface{}); ok { for _, v := range valueMap { strList = append(strList, ToStr(v[mapKey])) } } else if valueSlice, ok := value.([]interface{}); ok { for _, v := range valueSlice { mapV := StructToMapViaReflect(v, "json") strList = append(strList, ToStr(mapV[mapKey])) } } else if reflect.TypeOf(value).Kind() == reflect.Slice { s := reflect.ValueOf(value) for i := 0; i < s.Len(); i++ { mapV := StructToMapViaReflect(s.Index(i).Interface(), "json") strList = append(strList, ToStr(mapV[mapKey])) } } return strings.Join(strList, joinStr) } func JoinIntSlice(a []int, delim string) string { return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]") //return strings.Trim(strings.Join(strings.Split(fmt.Sprint(a), " "), delim), "[]") //return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(a)), delim), "[]") } func MD5(s string) string { h := md5.New() h.Write([]byte(s)) return hex.EncodeToString(h.Sum(nil)) } func SHA1(data string) string { t := sha1.New() io.WriteString(t, data) return fmt.Sprintf("%x", t.Sum(nil)) } func IsContain(sliceData interface{}, sliceItem interface{}) bool { itemType := reflect.TypeOf(sliceItem).Kind() if reflect.TypeOf(sliceData).Kind() == reflect.Slice { s := reflect.ValueOf(sliceData) for i := 0; i < s.Len(); i++ { itemVal := s.Index(i).Interface() if itemType == reflect.Map || itemType == reflect.Slice { if reflect.DeepEqual(itemVal, sliceItem) { return true } } else if itemVal == sliceItem { return true } } } return false } func AppendUniqueInt(sliceData []int, sliceItem int) []int { if !IsContain(sliceData, sliceItem) { return append(sliceData, sliceItem) } return sliceData } func AppendUniqueInterface(sliceData []interface{}, sliceItem interface{}) []interface{} { if !IsContain(sliceData, sliceItem) { return append(sliceData, sliceItem) } return sliceData } func DeepCopy(toValue interface{}, fromValue interface{}) error { return copier.Copy(toValue, fromValue) } func GenTree(value interface{}, id string, pid string, child string, filterID int) []map[string]interface{} { res := make([]map[string]interface{}, 0) if valueSlice, ok := value.([]interface{}); ok { for _, v := range valueSlice { res = append(res, StructToMapViaReflect(v, "json")) } } else if valueMap, ok := value.([]map[string]interface{}); ok { res = valueMap } else if reflect.TypeOf(value).Kind() == reflect.Slice { s := reflect.ValueOf(value) for i := 0; i < s.Len(); i++ { res = append(res, StructToMapViaReflect(s.Index(i).Interface(), "json")) } } items := make(map[string]interface{}) tree := make([]map[string]interface{}, 0) keys := make([]int, 0) for _, v := range res { vNew := make(map[string]interface{}) DeepCopy(&vNew, &v) keys = append(keys, ToInt(vNew[id])) items[ToStr(vNew[id])] = vNew } sort.Ints(keys) for _, v := range keys { v := items[ToStr(v)].(map[string]interface{}) parentInfo := items[ToStr(v[pid])] if parentInfo != nil { parentInfo := parentInfo.(map[string]interface{}) if parentInfo[child] == nil { parentInfo[child] = make([]interface{}, 0) } parentInfo[child] = append(parentInfo[child].([]interface{}), v) } else { if filterID == 0 || v[id] == filterID { tree = append(tree, v) } } } return tree } func Min(x, y int) int { if x <= y { return x } return y } func Max(x, y int) int { if x <= y { return y } return x } func Between(x, min, max int) int { if x <= min { return min } else if x >= max { return max } else { return x } } func GetType(val interface{}) string { return reflect.ValueOf(val).Kind().String() } func GetSlice(sliceData interface{}, sliceIndex int, sliceDefault interface{}) interface{} { if reflect.TypeOf(sliceData).Kind() == reflect.Slice { s := reflect.ValueOf(sliceData) if sliceIndex >= s.Len() { return sliceDefault } return s.Index(sliceIndex).Interface() } else { return sliceDefault } } func ParseImgStr(imgStr string) []string { if imgStr == "" { return make([]string, 0) } imgUrlList := strings.Split(imgStr, ",") for k, v := range imgUrlList { imgUrlList[k] = ParseImg(v) } return imgUrlList } func ParseImg(imgUrl string) string { if imgUrl == "" { return imgUrl } return config.Cfg.App.ImgHost + imgUrl } func GetRootPath() string { return config.GetRootPath() }