package utils import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "reflect" "strconv" "strings" "time" "git.rosy.net.cn/baseapi" "github.com/satori/go.uuid" ) func GetConcretValue(value reflect.Value) reflect.Value { for { if value.Kind() == reflect.Interface || value.Kind() == reflect.Ptr { value = value.Elem() } else { break } } return value } func DictKeysMan(data interface{}, keysToRemove []string, keysToKeep []string) interface{} { if data == nil || (keysToKeep == nil && keysToRemove == nil) { return data } var keysToRemoveMap map[string]int var keysToKeepMap map[string]int if keysToKeep != nil { keysToKeepMap = make(map[string]int) for _, v := range keysToKeep { keysToKeepMap[v] = 1 } } else if keysToRemove != nil { keysToRemoveMap = make(map[string]int) for _, v := range keysToRemove { keysToRemoveMap[v] = 1 } } dataIsSlice := true valueOfData := reflect.ValueOf(data) if valueOfData.Kind() != reflect.Slice { dataIsSlice = false valueOfData = reflect.ValueOf([]interface{}{data}) } else if valueOfData.Len() == 0 { return data } retVal := make([]interface{}, valueOfData.Len()) for index := 0; index < valueOfData.Len(); index++ { realV := GetConcretValue(valueOfData.Index(index)) if keysToRemoveMap != nil || keysToKeepMap != nil { mapV := make(map[string]interface{}) for _, key := range realV.MapKeys() { fieldName := key.String() wantThisField := true if keysToKeepMap != nil { if _, ok := keysToKeepMap[fieldName]; !ok { wantThisField = false } } else if keysToRemoveMap != nil { if _, ok := keysToRemoveMap[fieldName]; ok { wantThisField = false } } if wantThisField { mapV[fieldName] = GetConcretValue(realV.MapIndex(key)).Interface() } } retVal[index] = mapV } else { retVal[index] = realV.Interface() } } if !dataIsSlice { return retVal[0] } return retVal } func UnmarshalUseNumber(data []byte, result interface{}) error { d := json.NewDecoder(bytes.NewReader(data)) d.UseNumber() err := d.Decode(result) if err != nil { baseapi.SugarLogger.Errorf("decode data:%v, error:%v", string(data), err) } return err } func MustMarshal(obj interface{}) []byte { byteArr, err := json.Marshal(obj) if err != nil { panic(fmt.Sprintf("err when Marshal obj:%v", obj)) } return byteArr } func Bool2String(value bool) string { if value { return "true" } return "false" } func Str2Int64WithDefault(str string, defValue int64) int64 { retVal, err := strconv.ParseInt(str, 10, 64) if err != nil { return defValue } return retVal } func Str2Int64(str string) int64 { retVal, err := strconv.ParseInt(str, 10, 64) if err != nil { baseapi.SugarLogger.Errorf("error when convert %s to int64", str) } return retVal } func Int64ToStr(value int64) string { return strconv.FormatInt(value, 10) } func Int2Str(value int) string { return strconv.Itoa(value) } // 去除-号,全部大写,比如:929ADB626EB911E893E452540009DAB3 func GetUUID() string { return strings.ToUpper(strings.Replace(uuid.Must(uuid.NewV1()).String(), "-", "", -1)) } func GetCurTimeStr() string { return Time2Str(time.Now()) } // timestamp is in second func GetCurTimestamp() int64 { return time.Now().Unix() } func GetAPIOperator() string { return "jxc4-" + Time2Str(time.Now()) } // timestamp is in second func Timestamp2Str(timestamp int64) string { return Time2Str(time.Unix(timestamp, 0)) } func Timestamp2Time(timestamp int64) time.Time { return time.Unix(timestamp, 0) } func Time2Str(t time.Time) string { return t.Format("2006-01-02 15:04:05") } func Str2Time(timeStr string) time.Time { timeStr = strings.Replace(timeStr, "T", " ", 1) retVal, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local) if err != nil { baseapi.SugarLogger.Errorf("ParseInLocation failed, timeStr:%v, error:%v", timeStr, err) } return retVal } func HTTPResponse2Json(response *http.Response) (map[string]interface{}, error) { var jsonResult map[string]interface{} bodyData, err := ioutil.ReadAll(response.Body) if err != nil { baseapi.SugarLogger.Errorf("ioutil.ReadAll error:%v, response:%v", err, response) return nil, err } if err = UnmarshalUseNumber(bodyData, &jsonResult); err != nil { return nil, err } return jsonResult, nil } func HTTPBody2Values(data []byte, needDecode bool) (url.Values, error) { bodyStr := string(data) if needDecode { bodyStr1, err := url.QueryUnescape(bodyStr) if err != nil { baseapi.SugarLogger.Errorf("QueryUnescape error:%v, bodyStr:%v", err, bodyStr) return nil, err } bodyStr = bodyStr1 } result, err := url.ParseQuery(bodyStr) if err != nil { baseapi.SugarLogger.Errorf("ParseQuery error:%v, bodyStr:%v", err, bodyStr) return nil, err } return result, nil } func MustInterface2Int64(data interface{}) int64 { dataNumber, ok := data.(json.Number) if !ok { panic(fmt.Sprintf("error when cast:%v to int64", data)) } retVal, err := dataNumber.Int64() if err != nil { panic(err.Error()) } return retVal } func MustInterface2Float64(data interface{}) float64 { dataNumber, ok := data.(json.Number) if !ok { panic(fmt.Sprintf("error when convert:%v", data)) } retVal, err := dataNumber.Float64() if err != nil { panic(err.Error()) } return retVal } func Interface2String(data interface{}) string { if data == nil { return "" } return data.(string) } func MergeMaps(firstMap map[string]interface{}, otherMaps ...map[string]interface{}) (retVal map[string]interface{}) { retVal = make(map[string]interface{}) allMaps := append(otherMaps, firstMap) for _, oneMap := range allMaps { for k, v := range oneMap { retVal[k] = v } } return retVal } func CallFuncLogError(funcToCall func() error, msg string) error { err := funcToCall() if err != nil { baseapi.SugarLogger.Warnf("%s, error:%v", msg, err.Error()) } return err } func CallFuncAsync(funcToCall func()) { go func() { defer func() { if r := recover(); r != nil { baseapi.SugarLogger.Errorf("error when calling func:%v, r:%v", funcToCall, r) } }() funcToCall() }() } func Params2Map(key1, value1 interface{}, kv ...interface{}) (retVal map[string]interface{}) { retVal = make(map[string]interface{}) retVal[key1.(string)] = value1 key := "" for index, v := range kv { if index%2 == 0 { key = v.(string) } else { retVal[key] = v } } return retVal } func URLValues2Map(values url.Values) (retVal map[string]interface{}) { retVal = make(map[string]interface{}) for k := range values { retVal[k] = values.Get(k) } return retVal } func Map2URLValues(mapData map[string]interface{}) (retVal url.Values) { retVal = make(url.Values) for k, v := range mapData { retVal.Set(k, fmt.Sprint(v)) } return retVal } func GenerateGetURL(baseURL, apiStr string, params map[string]interface{}) string { queryString := "" if params != nil { for k, v := range params { if queryString == "" { queryString = "?" } else { queryString += "&" } queryString += k + "=" + url.QueryEscape(fmt.Sprint(v)) } } return baseURL + "/" + apiStr + queryString } func SendFakeRequest(method, url, body, contentType string) (*http.Response, error) { request, _ := http.NewRequest(method, url, strings.NewReader(body)) if contentType == "" { contentType = "application/x-www-form-urlencoded" } request.Header.Set("Content-Type", contentType) client := &http.Client{} return client.Do(request) }