package utils import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "reflect" "strconv" "strings" "time" "git.rosy.net.cn/baseapi" ) var ( DefaultTimeValue = Str2Time("1970-01-01 00:00:00") ) 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 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 with error:%v", obj, err)) } return byteArr } 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 Interface2Int64WithDefault(data interface{}, defValue int64) int64 { if data == nil { return defValue } return MustInterface2Int64(data) } func Interface2DirectIntWithDefault(data interface{}, defValue int) int { if data == nil { return defValue } return data.(int) } 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 Interface2FloatWithDefault(data interface{}, defValue float64) (retVal float64) { if data == nil { return defValue } return MustInterface2Float64(data) } func Interface2String(data interface{}) string { if data == nil { return "" } return data.(string) } func Interface2Int64List(data interface{}) []int64 { if data == nil { return nil } list := data.([]interface{}) retVal := make([]int64, len(list)) for k, v := range list { retVal[k] = MustInterface2Int64(v) } return retVal } func Interface2StringList(data interface{}) []string { if data == nil { return nil } list := data.([]interface{}) retVal := make([]string, len(list)) for k, v := range list { retVal[k] = Interface2String(v) } return retVal } func Interface2Slice(value interface{}) (retVal []interface{}) { typeInfo := reflect.TypeOf(value) if typeInfo.Kind() != reflect.Slice { panic("list must be slice type!") } if value != nil { valueInfo := reflect.ValueOf(value) retVal = make([]interface{}, valueInfo.Len()) for i := 0; i < valueInfo.Len(); i++ { retVal[i] = valueInfo.Index(i).Interface() } } return retVal } func Slice2MapSlice(data []interface{}) []map[string]interface{} { retVal := make([]map[string]interface{}, len(data)) for k, v := range data { retVal[k] = v.(map[string]interface{}) } return retVal } // 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 Str2Float64WithDefault(str string, defValue float64) float64 { retVal, err := strconv.ParseFloat(str, 64) if err != nil { retVal = defValue } return retVal } func Str2Float64(str string) float64 { retVal, err := strconv.ParseFloat(str, 64) if err != nil { baseapi.SugarLogger.Errorf("error when convert %s to float64", str) } return retVal } func Int64ToStr(value int64) string { return strconv.FormatInt(value, 10) } func Int2Str(value int) string { return strconv.Itoa(value) } // timestamp is in second func Timestamp2Str(timestamp int64) string { return Time2Str(Timestamp2Time(timestamp)) } func Timestamp2Time(timestamp int64) time.Time { const normalTimestamp = 1533709322 if timestamp > normalTimestamp*100 { // 传成毫秒了 baseapi.SugarLogger.Errorf("Timestamp2Time wrong timestamp:%d", timestamp) timestamp = timestamp / 1000 } 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) if strings.Index(timeStr, " ") == -1 { timeStr += " 00:00:00" } retVal, err := time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local) if err != nil { baseapi.SugarLogger.Errorf("time.ParseInLocation failed, timeStr:%v, error:%v", timeStr, err) } return retVal } func Str2TimeWithDefault(timeStr string, defValue time.Time) time.Time { timeStr = strings.Replace(timeStr, "T", " ", 1) retVal, err := time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local) if err != nil { return defValue } 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 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 MapKV2List(mapData map[string]interface{}) []map[string]interface{} { retVal := make([]map[string]interface{}, len(mapData)) index := 0 for _, v := range mapData { retVal[index] = v.(map[string]interface{}) index++ } return retVal } func Format4Output(obj interface{}, isSingleLine bool) (retVal string) { retVal, ok := obj.(string) if !ok { var ( result []byte err error ) if isSingleLine { if result, err = json.Marshal(obj); err == nil { retVal = string(result) } } else { if result, err = json.MarshalIndent(obj, "", "\t"); err == nil { retVal = string(result) } } if err != nil { baseapi.SugarLogger.Infof("Format4Output Marshal:%v failed with error:%v", obj, err) retVal = fmt.Sprintf("%v", obj) } } return retVal }